Project

General

Profile

Download (6.39 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 = array();
25
  //private static $footnote_key_index = 1;
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 array $footnoteListKey
84
   * @param string $separator
85
   *
86
   * @return string
87
   *   The rendered footnotelist.
88
   */
89
  public static function renderFootnoteList($footnoteListKey, $separator = ', ') {
90
    $out = '';
91
    if (array_key_exists($footnoteListKey, self::$fnstore)) {
92
      foreach (self::$fnstore[$footnoteListKey] as $fn) {
93
        $out .= $fn->doRender() . $separator;
94
      }
95
      $out = substr($out, 0, strlen($out) - strlen($separator));
96
    }
97
    return $out;
98
  }
99

    
100
  /**
101
   * Add a new footnote.
102
   *
103
   * @param $footnoteListKey
104
   * @param $object
105
   * @param $theme
106
   * @param $themeArguments
107
   *
108
   * @return FootnoteKey
109
   */
110
  public static function addNewFootnote($footnoteListKey, $object = NULL, $enclosing_tag = null) {
111
    if (!$object) {
112
      return FALSE;
113
    }
114
    if (!array_key_exists($footnoteListKey, self::$fnstore)) {
115
      self::$fnstore[$footnoteListKey] = array();
116
    }
117

    
118
    $key_label = NULL;
119
    if (!($key_label = self::footnoteExists($footnoteListKey, $object))) {
120

    
121
      $set_def = &self::matchFootnoteSetDefinition($footnoteListKey);
122

    
123
      $fn_index = $set_def['key_index']++;
124

    
125
      // see http://php.net/manual/de/function.base-convert.php
126
      switch($set_def['key_format']) {
127
        case 'ROMAN':
128
          $key_label = roman_numerals($fn_index);
129
          break;
130
        case 'roman':
131
          $key_label = strtolower(roman_numerals($fn_index));
132
          break;
133
        case 'ALPHA':
134
          $key_label = num2alpha($fn_index - 1);
135
          break;
136
        case 'alpha':
137
          $key_label = strtolower(num2alpha($fn_index - 1));
138
          break;
139
        case 'latin':
140
        default:
141
          $key_label = $fn_index;
142
      }
143

    
144
      $fn = new Footnote($key_label, $object, $set_def['enclosing_tag']);
145
      self::$fnstore[$footnoteListKey][$key_label] = $fn;
146
    }
147

    
148
    return new FootnoteKey($key_label, $footnoteListKey);
149
  }
150

    
151
  /**
152
   * Check if a footnote exists.
153
   *
154
   * @param $footnoteListKey
155
   * @param $object
156
   *
157
   * @return
158
   */
159
  private static function footnoteExists($footnoteListKey, $object) {
160
    foreach (self::$fnstore[$footnoteListKey] as $key => $fn) {
161
      /*
162
      When using the comparison operator (==), object variables are compared
163
      in a simple manner, namely:
164
      Two object instances are equal if they have the same attributes and
165
      values, and are instances of the same class.
166
      */
167
      if ($object == $fn->object) {
168
        return $key;
169
      }
170
    }
171
    return FALSE;
172
  }
173

    
174
  /**
175
   * Register special footnote set for the given $footnoteListKey which is to be handle separately
176
   * @param $footnoteListKey
177
   * @param $enclosing_tag: the enclosing tag to be used for rendering of the footnote, @see theme_cdm_footnote()
178
   * @param $key_format: 'latin', 'ROMAN', 'roman', 'ALPHA', 'alpha'
179
   */
180
  public static function registerFootnoteSet($footnoteListKey, $enclosing_tag = null, $key_format = null){
181

    
182
    $set_def = array('key_index' => 1);
183
    if($enclosing_tag){
184
      $set_def['enclosing_tag'] = $enclosing_tag;
185
    } else {
186
      $set_def['enclosing_tag'] = self::$default_set_definition['enclosing_tag'];
187
    }
188
    if($key_format){
189
      $set_def['key_format'] = $key_format;
190
    } else {
191
      $set_def['key_format'] = self::$default_set_definition['key_format'];
192
    }
193
    self::$fn_sets[$footnoteListKey] = $set_def;
194
  }
195

    
196
  /**
197
   * Returns the footnote set definition which has been
198
   * registered with a key which matches the given $footnoteListKey.
199
   * A match is the first key which is equal to or which starts with $footnoteListKey
200
   * If no match is found the default is returned.
201
   *
202
   * @see registerFootnoteSet()
203
   *
204
   * @param $footnoteListKey
205
   * @return array
206
   */
207
  public static function &matchFootnoteSetDefinition($footnoteListKey){
208

    
209
    foreach(self::$fn_sets as $fn_set_key => &$fn_set_def){
210
      if($footnoteListKey == $fn_set_key || str_beginsWith($footnoteListKey, $fn_set_key)){
211
        return $fn_set_def;
212
      }
213
    }
214
    return self::$default_set_definition;
215
  }
216

    
217
  /**
218
   * Stop users from cloning.
219
   */
220
  public function __clone() {
221
    trigger_error('Cloning instances of the singleton class FootNoteManager is prohibited', E_USER_ERROR);
222
  }
223
}
(3-3/4)