root/trunk/lib/SGL/Util.php

Revision 3125, 16.3 kB (checked in by demian, 3 weeks ago)

bugfix to trunk merge -3

Line 
1 <?php
2 /* Reminder: always indent with 4 spaces (no tabs). */
3 // +---------------------------------------------------------------------------+
4 // | Copyright (c) 2006, Demian Turner                                         |
5 // | All rights reserved.                                                      |
6 // |                                                                           |
7 // | Redistribution and use in source and binary forms, with or without        |
8 // | modification, are permitted provided that the following conditions        |
9 // | are met:                                                                  |
10 // |                                                                           |
11 // | o Redistributions of source code must retain the above copyright          |
12 // |   notice, this list of conditions and the following disclaimer.           |
13 // | o Redistributions in binary form must reproduce the above copyright       |
14 // |   notice, this list of conditions and the following disclaimer in the     |
15 // |   documentation and/or other materials provided with the distribution.    |
16 // | o The names of the authors may not be used to endorse or promote          |
17 // |   products derived from this software without specific prior written      |
18 // |   permission.                                                             |
19 // |                                                                           |
20 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
21 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         |
22 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     |
23 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
24 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     |
25 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          |
26 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     |
27 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
28 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
29 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE     |
30 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.      |
31 // |                                                                           |
32 // +---------------------------------------------------------------------------+
33 // | Seagull 0.6                                                               |
34 // +---------------------------------------------------------------------------+
35 // | Util.php                                                                  |
36 // +---------------------------------------------------------------------------+
37 // | Author:   Demian Turner <demian@phpkitchen.com>                           |
38 // +---------------------------------------------------------------------------+
39 // $Id: Util.php,v 1.22 2005/05/11 00:19:40 demian Exp $
40
41 /**
42  * Various utility methods.
43  *
44  * @package SGL
45  * @author  Demian Turner <demian@phpkitchen.com>
46  * @version $Revision: 1.22 $
47  */
48 class SGL_Util
49 {
50     // +---------------------------------------+
51     // | Column-sorting methods                |
52     // +---------------------------------------+
53
54     /**
55      * Used by list pages to determine last sort order.
56      *
57      * If no value passed from Request, returns last value
58      * from session
59      *
60      * @access  public
61      * @param   string  $sortOrder  Output object containing validated input
62      * @return  string  $order
63      */
64     function getSortOrder($sortOrder)
65     {
66         SGL::logMessage(null, PEAR_LOG_DEBUG);
67         if ($sortOrder == '') {
68             $order = SGL_Session::get('sortOrder');
69         } elseif ($sortOrder == 'ASC') {
70             $order = 'DESC';
71         } else {
72             $order = 'ASC';
73         }
74         //  update session
75         SGL_Session::set('sortOrder', $order);
76         return $order;
77     }
78
79     /**
80      * Determines which column results should be sorted by.
81      *
82      * If no value passed from Request, returns last value
83      * from session
84      *
85      * @access  public
86      * @param   string  $frmSortBy      column name passed from Request
87      * @param   int     $callingPage    table relevant to sortby
88      * @return  string  $sortBy         value to sort by
89      */
90     function getSortBy($frmSortBy, $callingPage)
91     {
92         SGL::logMessage(null, PEAR_LOG_DEBUG);
93
94         switch ($callingPage) {
95
96         case SGL_SORTBY_GRP:
97             $sortByType = 'Grp';
98             $sessSortBy = SGL_Session::get('sortByGrp');
99             break;
100
101         case SGL_SORTBY_USER:
102             $sortByType = 'User';
103             $sessSortBy = SGL_Session::get('sortByUser');
104             break;
105         }
106         if ($frmSortBy == '' && $sessSortBy == '') {
107             //  take default set in child class
108             $sortBy = $this->sortBy;
109         } elseif ($frmSortBy == '') {
110             $sortBy = $sessSortBy;
111         } else {
112             $sortBy = $frmSortBy;
113         }
114         //  update session
115         $sessVar = 'sortBy' . $sortByType;
116         SGL_Session::set($sessVar, $sortBy);
117         return $sortBy;
118     }
119
120     /**
121      * Fetches the .css files in theme/css/ into array of form:
122      * filename => filename [without ".css" extension] for use by
123      * Output->generateSelect()
124      *
125      * @return  array of .css files from www/css
126      * @access  private
127      */
128     function getStyleFiles($curStyle = false)
129     {
130         $aFiles = array();
131
132         $c = &SGL_Config::singleton();
133         $theme = $c->get(array('site' => 'defaultTheme'));
134
135         //  get array of files in /www/css/
136         if ($fh = @opendir(SGL_THEME_DIR . "/$theme/css/")) {
137             while (false !== ($file = readdir($fh))) {
138
139                 //  remove unwanted dir elements
140                 if ($file == '.' || $file == '..' || $file == 'CVS') {
141                     continue;
142                 }
143                 //  and anything without .nav.php extension
144                 $ext = substr($file, -8);
145                 if ($ext != '.nav.php') {
146                     continue;
147                 }
148
149                 $filename = substr($file, 0, strpos($file, '.'));
150
151                 //  if $curStyle is not false, we need an array of hashes for NavStyleMgr
152                 if ($curStyle) {
153                     $aFiles[$filename]['currentStyle'] = ($filename == $curStyle) ? true : false;
154                     $aFiles[$filename]['fileMtime'] =  strftime('%Y-%b-%d %H:%M:%S',
155                         filemtime(SGL_THEME_DIR . '/' . $theme . '/css/' . $file));
156
157                 //  otherwise a simple hash will do for ConfigMgr
158                 } else {
159                     $aFiles[$filename] = $filename;
160                 }
161             }
162             closedir($fh);
163         } else {
164             SGL::raiseError('There was a problem reading the navigation style dir',
165                 SGL_ERROR_INVALIDFILEPERMS);
166         }
167         return $aFiles;
168     }
169
170     function getAllThemes()
171     {
172         SGL::logMessage(null, PEAR_LOG_DEBUG);
173
174         require_once 'File/Util.php';
175         //  match all folders except admin themes
176         $ret = SGL_Util::listDir(SGL_THEME_DIR, FILE_LIST_DIRS, $sort = FILE_SORT_NONE,
177                 array('SGL_Util', 'themeFilterCallback'));
178         return $ret;
179     }
180
181     function themeFilterCallback($str)
182     {
183          return (stristr($str, '_admin')) ? false : true;
184     }
185
186     /**
187      * Returns an hash of strings containing the installed (and registered) Modules
188      *
189         Array
190         (
191             [block] => block
192             [cms] => cms
193             [default] => default
194             [event] => event
195             [export] => export
196             [navigation] => navigation
197             [user] => user
198         )
199      * @static
200      * @access  public
201      * @return  array
202      * @param   bool $onlyRegistered
203      */
204
205     function getAllModuleDirs($onlyRegistered = true)
206     {
207         SGL::logMessage(null, PEAR_LOG_DEBUG);
208
209         require_once 'File/Util.php';
210
211         //  match all folders except CVS
212         $ret = SGL_Util::listDir(SGL_MOD_DIR, FILE_LIST_DIRS, FILE_SORT_NAME,
213             create_function('$a', 'return preg_match("/[^CVS]/", $a);'));
214
215         foreach ($ret as $module) {
216             if ($onlyRegistered && !SGL::moduleIsEnabled($module)) {
217                 unset($ret[$module]);
218             }
219         }
220         return $ret;
221     }
222
223     function getAllManagersPerModule($moduleDir)
224     {
225         SGL::logMessage(null, PEAR_LOG_DEBUG);
226
227         require_once 'File/Util.php';
228
229         //  match files with php extension
230         $classDir = $moduleDir . '/classes';
231         $ret = SGL_Util::listDir($classDir, FILE_LIST_FILES, $sort = FILE_SORT_NAME,
232                 create_function('$a', 'return preg_match("/.*Mgr\.php$/", $a);'));
233
234         //  parse out filename w/o extension and .
235         array_walk($ret, create_function('&$a', 'preg_match("/^.*Mgr/", $a, $matches); $a =  $matches[0]; return true;'));
236
237         return $ret;
238     }
239
240     function getAllActionMethodsPerMgr($mgr)
241     {
242         $managerFileName = basename($mgr);
243         $moduleDir = dirname(dirname($mgr));
244         $files = SGL_Util::getAllManagersPerModule($moduleDir);
245
246         //  remap 'ContactUsMgr.php => ContactUsMgr' hash to array
247         $fileNames = array();
248         foreach ($files as $k => $file) {
249             $fileNames[] = $k;
250         }
251
252         $fileNamesLowerCase = array_map('strtolower', $fileNames);
253         $isFound = array_search(strtolower($managerFileName), $fileNamesLowerCase);
254         $managerFileName = ($isFound !== false) ? $fileNames[$isFound] : false;
255
256         if (!($managerFileName)) {
257             return false;
258         }
259
260         $filePath = $moduleDir . '/classes/' . $managerFileName;
261
262         if (is_file($filePath)) {
263             require_once $filePath;
264             $aElems = explode('/', $filePath);
265             $last = array_pop($aElems);
266             $className = substr($last, 0, -4);
267
268             $obj = new $className(); // extract classname
269             $vars = get_object_vars($obj);
270             $actions = array_keys($vars['_aActionsMapping']);
271             $ret = array();
272             foreach ($actions as $k => $action) {
273                 $ret[$action] = $action;
274             }
275             return $ret;
276         } else {
277             return false;
278         }
279     }
280
281     function getAllClassesFromFolder($folder = '', $filter = '.*')
282     {
283         SGL::logMessage(null, PEAR_LOG_DEBUG);
284
285         require_once 'File/Util.php';
286
287         //  match files with php extension
288         $ret = SGL_Util::listDir($folder, FILE_LIST_FILES, $sort = FILE_SORT_NAME,
289                 create_function('$a', 'return preg_match("/^.*\.php$/", $a);'));
290
291         //  parse out filename w/o extension and .
292         $aClasses = array();
293         foreach ($ret as $k => $v) {
294             if (preg_match("/^($filter)\.php$/", $v, $matches)) {
295                 $aClasses[$matches[1]] = $matches[1];
296             }
297         }
298         return $aClasses;
299     }
300
301     /**
302      * Wrapper for the File_Util::listDir method.
303      *
304      * Instead of returning an array of objects, it returns an array of
305      * strings (filenames).
306      *
307      * The final argument, $cb, is a callback that either evaluates to true or
308      * false and performs a filter operation, or it can also modify the
309      * directory/file names returned.  To achieve the latter effect use as
310      * follows:
311      *
312      * <code>
313      * function uc(&$filename) {
314      *     $filename = strtoupper($filename);
315      *     return true;
316      * }
317      * $entries = File_Util::listDir('.', FILE_LIST_ALL, FILE_SORT_NONE, 'uc');
318      * foreach ($entries as $e) {
319      *     echo $e->name, "\n";
320      * }
321      * </code>
322      *
323      * @static
324      * @access  public
325      * @return  array
326      * @param   string  $path
327      * @param   int     $list
328      * @param   int     $sort
329      * @param   mixed   $cb
330      */
331     function listDir($path, $list = FILE_LIST_ALL, $sort = FILE_SORT_NONE, $cb = null)
332     {
333         $aRet = array();
334         if (is_array($aFiles = File_Util::listDir($path, $list, $sort, $cb))) {
335             foreach ($aFiles as $oFile) {
336                 $aRet[$oFile->name] = $oFile->name;
337             }
338         }
339         return $aRet;
340     }
341
342     /**
343      * Ini file protection.
344      *
345      * By giving ini files a php extension, and inserting some PHP die() code,
346      * we can improve security in situations where browsers might be able to
347      * read them.  Thanks to Georg Gell for the idea.
348      *
349      * @param string $file  Path to ini file
350      */
351     function makeIniUnreadable($file)
352     {
353         $iniFle = file($file);
354         $string = ';<?php die("Eat dust"); ?>' . "\n";
355         array_unshift($iniFle, $string);
356         file_put_contents($file . '.php', implode('', $iniFle));
357         //  remove original ini file
358         unlink($file);
359     }
360     /**
361      * Returns a hash of the form array('en-iso-8859-15' => 'English (en-iso-8859-15),) etc.
362      *
363      * @return array
364      */
365     function getLangsDescriptionMap($aSelected = array(), $langKeyType = null)
366     {
367         $availableLanguages = $GLOBALS['_SGL']['LANGUAGE'];
368         uasort($availableLanguages, 'SGL_cmp');
369         $aLangs = array();
370         foreach ($availableLanguages as $id => $tmplang) {
371             $langName = ucfirst(substr(strstr($tmplang[0], '|'), 1));
372             $keyId = ($langKeyType)
373                 ? SGL_Translation::transformLangID($id, $langKeyType)
374                 : $id;
375             if (count($aSelected) && in_array($id, $aSelected)) {
376                 $aSelectedLangs[$keyId] =  $langName . ' (' . $id . ')';
377             } else {
378                 $aLangs[$keyId] =  $langName . ' (' . $id . ')';
379             }
380         }
381
382         //  if $aSelectedLangs has elements return it.
383         $aLangs = (isset ($aSelectedLangs) && !empty($aSelectedLangs))
384             ? $aSelectedLangs
385             : $aLangs;
386
387         return $aLangs;
388     }
389
390     /**
391      * Returns params from ini file.
392      *
393      * @return array
394      */
395     function loadParams($ini_file = '', $aSavedParams = array(), $aCurrentParams = array())
396     {
397         //  set default params
398         $aReturn = array();
399         $details = '';
400         $aPreparedParams = array();
401
402         if (is_file($ini_file)) {
403
404             //  get details section
405             $aParams = @parse_ini_file($ini_file, true);
406             if (array_key_exists('details', $aParams)) {
407                 $details = (object)$aParams['details'];
408                 unset($aParams['details']);
409             }
410
411             foreach ($aParams as $key => $value) {
412                 if (is_array($value) && array_key_exists('value',$value)
413                     && array_key_exists('type',$value) && array_key_exists('label',$value)) {
414                     $value array_key_exists($key, $aCurrentParams) ? $aCurrentParams[$key] : '';
415                     if ($value) {
416                         $aParams[$key]['value'] = $value;
417                     } elseif (array_key_exists($key ,$aSavedParams)) {
418                         $aParams[$key]['value'] = $aSavedParams[$key];
419                     }
420                     $aParams[$key]['name'] = 'aParams['.$key.']';
421                     if ($aParams[$key]['type'] == 'wysiwyg') {
422                         $aReturn['wysiwyg'] = true;
423                     }
424                     $aPreparedParams[$key] = (object)$aParams[$key];
425                 }
426             }
427         }
428
429         $aReturn['details'] = $details;
430         $aReturn['aParams'] = $aPreparedParams;
431         return $aReturn;
432     }
433
434     /**
435      * Returns the system's tmp directory.
436      *
437      * Mactel doesn't supply tmp path in most of the normal places.
438      *
439      * @return string  Path to tmp dir
440      */
441     function getTmpDir()
442     {
443        // Try to get from environment variable
444        if (!empty($_ENV['TMP'])) {
445            return realpath($_ENV['TMP']);
446        } elseif (!empty($_ENV['TMPDIR'])) {
447            return realpath($_ENV['TMPDIR']);
448        } elseif (!empty($_ENV['TEMP'])) {
449            return realpath($_ENV['TEMP']);
450        }
451        // Detect by creating a temporary file
452        else {
453            // Try to use system's temporary directory
454            // as random name shouldn't exist
455            $temp_file = tempnam(md5(uniqid(rand(), true)), '');
456            if ($temp_file) {
457                $temp_dir = realpath(dirname($temp_file));
458                unlink($temp_file);
459                return $temp_dir;
460            } else {
461                return false;
462            }
463        }
464     }
465 }
466 ?>
Note: See TracBrowser for help on using the browser.