1<?php
2/*
3 * By Raphael Reitzig, 2012
4 * version 2.0
5 * code@verrech.net
6 * http://lmazy.verrech.net
7 */
8?>
9<?php
10/*
11    This program is free software: you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation, either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23*/
24?>
25
26<?php
27
28/**
29 * Provides helping functions in order to keep clutter from the main file.
30 *
31 * @author Raphael Reitzig
32 * @version 2.0
33 */
34class Helper
35{
36
37  /**
38   * Copy of main class's options
39   * @var array
40   */
41  private $options;
42
43  /**
44   * Constructor.
45   *
46   * @access public
47   * @param array $options Options array with same semantics as main class.
48   */
49  function __construct(&$options=array())
50  {
51    $this->options = $options;
52  }
53
54  /**
55   * Obtains a month number from the passed entry.
56   *
57   * @access private
58   * @param array $entry An entry
59   * @return string The passed entry's month number. <code>00</code> if
60   *                the month could not be recognized.
61   */
62  private function e2mn(&$entry) {
63    $month = empty($entry['month']) ? '' : $entry['month'];
64
65    $result = '00';
66    $month = strtolower($month);
67
68    if ( preg_match('/^\d[\d]$/', $month) )
69    {
70      return strlen($month) == 1 ? '0'.$month : $month;
71    }
72    else
73    {
74      foreach ( $this->options['lang']['months'] as $number => $pattern )
75      {
76	$pattern = '/'.$pattern.'/';
77        if ( preg_match($pattern , $month) )
78        {
79          $result = $number;
80          break;
81        }
82      }
83    }
84
85    return $result;
86  }
87
88  /**
89   * Compares two group keys for the purpose of sorting.
90   *
91   * @access public
92   * @param string $k1 group key one
93   * @param string $k2 group key two
94   * @return int integer (<,=,>) zero if k1 is (less than,equal,larger than) k2
95   */
96  function group_cmp($k1, $k2)
97  {
98    return  $this->options['order_groups'] !== 'desc'
99          ? strcmp($k1, $k2)
100          : -strcmp($k1, $k2);
101  }
102
103  /**
104   * Compares two entries for the purpose of sorting.
105   *
106   * @access public
107   * @param string $k1 entry key one
108   * @param string $k2 entry key two
109   * @return int integer (<,=,>) zero if entry[$k1] is
110   *                     (less than,equal,larger than) entry[k2]
111   */
112  function entry_cmp($e1, $e2)
113  {
114    if ( $this->options['sort_by'] === 'DATE' )
115    {
116      $order = strcmp((!empty($e1['year']) ? $e1['year'] : '0000').$this->e2mn($e1),
117                      (!empty($e2['year']) ? $e2['year'] : '0000').$this->e2mn($e2));
118    }
119    elseif ( $this->options['sort_by'] === 'author' ) {
120      $order = strcmp($e1['sortauthor'], $e2['sortauthor']);
121    }
122    elseif ( $this->options['sort_by'] === 'firstauthor' ) {
123      $order = strcmp($e1['author'][0]['sort'], $e2['author'][0]['sort']);
124    }
125    else
126    {
127      $order = strcmp((!empty($e1[$this->options['sort_by']]) ? $e1[$this->options['sort_by']] : ''),
128                      (!empty($e2[$this->options['sort_by']]) ? $e2[$this->options['sort_by']] : ''));
129    }
130
131    if ( $this->options['order'] === 'desc' )
132    {
133      $order = -$order;
134    }
135
136    return $order;
137  }
138
139  /**
140   * Counts array elements in the specified array at the specified level.
141   * For depth<=1, lcount equals count.
142   *
143   * @access public
144   * @param array $array Array to count
145   * @param int $depth Counting depth. Default 1.
146   * @return int Number of array elements in $array at nesting level $depth
147   */
148  static function lcount(&$array, $depth=1)
149  {
150    $sum = 0;
151    $depth--;
152
153    if ( $depth > 0 )
154    {
155      foreach ( $array as $elem )
156      {
157        $sum += is_array($elem) ? self::lcount($elem, $depth) : 0;
158      }
159    }
160    else
161    {
162      foreach ( $array as $elem )
163      {
164        $sum += is_array($elem) ? 1 : 0;
165      }
166    }
167
168    return $sum;
169  }
170}
171?>
172