1d35a869edc332f9ae388bb127c880258edc5ac5
[tine20] / tine20 / Tinebase / Helper.php
1 <?php
2 /**
3  * Tine 2.0
4  * 
5  * @package     Tinebase
6  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
7  * @copyright   Copyright (c) 2007-2014 Metaways Infosystems GmbH (http://www.metaways.de)
8  * @author      Cornelius Weiss <c.weiss@metaways.de>
9  */
10
11 /**
12  * Helper class
13  *
14  * @package     Tinebase
15  */
16 class Tinebase_Helper
17 {
18     /**
19      * returns one value of an array, indentified by its key
20      *
21      * @param mixed $_key
22      * @param array $_array
23      * @return mixed
24      */
25     public static function array_value($_key, array $_array)
26     {
27         return (isset($_array[$_key]) || array_key_exists($_key, $_array)) ? $_array[$_key] : NULL;
28     }
29     
30     /**
31      * Generates a hash from keys(optional) and values of an array
32      *
33      * @param  array | string  $values
34      * @param  boolean         $includeKeys
35      * @return string
36      */
37     public static function arrayHash($values, $includeKeys = false)
38     {
39         $ctx = hash_init('md5');
40         
41         foreach ((array)$values as $id => $value) {
42             if (is_array($value)) {
43                 $value = self::arrayHash($value, $includeKeys);
44             }
45             
46             hash_update($ctx, ($includeKeys ? $id : null) . (string)$value);
47         }
48         
49         return hash_final($ctx);
50     }
51
52     /**
53      * converts string with M or K to bytes integer
54      * - for example: 50M -> 52428800
55      *
56      * @param mixed $_value
57      * @return int
58      * @throws Exception
59      */
60     public static function convertToBytes($value)
61     {
62         $powers = 'KMGTPEZY';
63         $power = 0;
64
65         if (preg_match('/(\d+)\s*([' . $powers . '])/', $value, $matches)) {
66             $value = $matches[1];
67             $power = strpos($powers, $matches[2]) + 1;
68         }
69
70         return (int)$value * pow(1024, $power);
71     }
72     
73     /**
74      * converts value to megabytes
75      * 
76      * @param integer $_value
77      * @return integer
78      */
79     public static function convertToMegabytes($_value)
80     {
81         $result = ($_value) ? round($_value / 1024 / 1024) : $_value;
82         
83         return $result;
84     }
85     
86     /**
87      * get svn revision info
88      *
89      * @return string
90      */
91     public static function getDevelopmentRevision()
92     {
93         $branch = '';
94         $rev = 0;
95         $date = '';
96         
97         try {
98             // try to find the .git dir
99             $dir = realpath(dirname(dirname(dirname(__FILE__)))) . '/.git';
100             if (file_exists($dir)) {
101                 $HEAD = trim(str_replace('ref: ', '', @file_get_contents("$dir/HEAD")));
102                 $explodedHead = explode('/', $HEAD);
103                 
104                 $branch = array_pop($explodedHead);
105                 $rev = trim(@file_get_contents("$dir/$HEAD"));
106                 
107                 $hashes = str_split($rev, 2);
108     
109                 $objPath = "$dir/objects";
110                 while (count($hashes) != 0) {
111                     $objPath .= '/' . array_shift($hashes);
112                     $objFile = "$objPath/" . implode('', $hashes);
113                     if (@file_exists($objFile)) {
114                         $date = date_create('@' . filemtime($objFile))->format('Y-m-d H:i:s');
115                         break;
116                     }
117                 }
118             }
119             $revision = "$branch: $rev ($date)";
120         } catch (Exception $e) {
121             $revision = 'not resolvable';
122         }
123         
124         return $revision;
125     }
126     
127     /**
128      * get release Codename
129      *
130      * @return string
131      */
132     public static function getCodename()
133     {
134         return 'Elena';
135     }
136     
137     /**
138      * converts cache id
139      * cache id strings can only contain the chars [a-zA-Z0-9_]
140      * 
141      * @param string $_cacheId
142      * @return string
143      */
144     public static function convertCacheId($_cacheId) 
145     {
146         $result = preg_replace('/[^a-z^A-Z^0-9^_]/', '', $_cacheId);
147         
148         return $result;
149     }
150     
151     /**
152      * replaces and/or strips special chars from given string
153      *
154      * @param string $_input
155      * @return string
156      */
157     public static function replaceSpecialChars($_input)
158     {
159         $search  = array('ä',  'ü',  'ö',  'ß',  'é', 'è', 'ê', 'ó' ,'ô', 'á', 'ź', 'Ä',  'Ü',  'Ö',  'É', 'È', 'Ê', 'Ó' ,'Ô', 'Á', 'Ź');
160         $replace = array('ae', 'ue', 'oe', 'ss', 'e', 'e', 'e', 'o', 'o', 'a', 'z', 'Ae', 'Ue', 'Oe', 'E', 'E', 'E', 'O', 'O', 'a', 'z');
161         
162         $output = str_replace($search, $replace, $_input);
163         
164         return preg_replace('/[^a-zA-Z0-9._\-]/', '', $output);
165     }
166     
167     /**
168      * Checks if needle $_str is in haystack $_arr but ignores case.
169      * 
170      * @param array $_arr
171      * @param string $_str
172      * @return boolean
173      */
174     public static function in_array_case($_arr, $_str)
175     {
176         if (! is_array($_arr)) {
177             return false;
178         }
179         
180         foreach ($_arr as $s) {
181             if (strcasecmp($_str, $s) == 0) {
182                 return true;
183             }
184         }
185         return false;
186     }
187     
188     /**
189      * try to convert string to utf8 using mb_convert_encoding
190      * 
191      * @param string $string
192      * @param string $encodingTo (default: utf-8)
193      * @return string
194      */
195     public static function mbConvertTo($string, $encodingTo = 'utf-8')
196     {
197         if (! extension_loaded('mbstring')) {
198             return $string;
199         }
200         // try to fix bad encodings
201         $encoding = mb_detect_encoding($string, array('utf-8', 'iso-8859-1', 'windows-1252', 'iso-8859-15'));
202         if ($encoding !== FALSE) {
203             $string = @mb_convert_encoding($string, $encodingTo, $encoding);
204         }
205         
206         return $string;
207     }
208     
209     /**
210      * converts all linebreaks to unix linebreaks
211      *
212      * @param string $string
213      * @return string
214      */
215     public static function normalizeLineBreaks($string)
216     {
217         if (is_string($string)) {
218             $result = str_replace(array("\r\n", "\r"), "\n", $string);
219         } else {
220             $result = $string;
221         }
222         
223         return $result;
224     }
225     
226     /**
227      * returns all elements of an array whose key matches the $pattern
228      * 
229      * @param string $pattern
230      * @param array $array
231      * @return array
232      */
233     public static function searchArrayByRegexpKey($pattern, $array)
234     {
235         $keys = array_keys($array);
236         $result = preg_grep($pattern, $keys);
237         
238         return array_intersect_key($array, array_flip($result));
239     }
240     
241     /**
242      * checks if a string is valid json
243      * 
244      * @param string $string
245      * @return boolean 
246      */
247     public static function is_json($string)
248     {
249         if (! is_string($string) || (substr($string, 0, 1) !== '[' && substr($string, 0, 1) !== '{')) {
250             return false;
251         }
252         
253         try {
254             Zend_Json::decode($string);
255         } catch (Exception $e) {
256             return false;
257         }
258         
259         // check if error occured (only if json_last_error() exists)
260         return (! function_exists('json_last_error') || json_last_error() == JSON_ERROR_NONE);
261     }
262     
263     /**
264      * formats a microtime diff to an appropriate string containing time unit based on the value range
265      * 
266      * value ranges
267      * below 1s return ms
268      * below 1m return s
269      * below 1h return m
270      * as of 1h return h
271      * 
272      * @param float $timediff
273      * @return string
274      */
275     public static function formatMicrotimeDiff($timediff)
276     {
277         $ms = (int)($timediff * 1000);
278         if ($ms>=3600000) {
279             return (((int)($ms / 3600000 * 100.0)) / 100.0).'h';
280         } elseif ($ms>=60000) {
281             return (((int)($ms / 60000 * 100.0)) / 100.0).'m';
282         } elseif ($ms>=1000) {
283             return (((int)($ms / 1000 * 100.0)) / 100.0).'s';
284         } else {
285             return $ms.'ms';
286         }
287     }
288     
289     /**
290      * checks if an url exists by checking headers 
291      * -> inspired by http://php.net/manual/en/function.file-exists.php#75064
292      * 
293      * @param string $url
294      * @return boolean
295      */
296     public static function urlExists($url)
297     {
298         $file_headers = @get_headers($url);
299         
300         if ($file_headers[0] == 'HTTP/1.1 404 Not Found') {
301             $exists = false;
302         } else {
303             $exists = true;
304         }
305         
306         return $exists;
307     }
308 }