~tsep-dev/tsep/0.9-beta

« back to all changes in this revision

Viewing changes to branches/symfony/cake/libs/controller/components/acl.php

  • Committer: geoffreyfishing
  • Date: 2011-01-11 23:46:12 UTC
  • Revision ID: svn-v4:ae0de26e-ed09-4cbe-9a20-e40b4c60ac6c::125
Created a symfony branch for future migration to symfony

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Access Control List factory class.
 
4
 *
 
5
 * Permissions system.
 
6
 *
 
7
 * PHP versions 4 and 5
 
8
 *
 
9
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 
10
 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
 
11
 *
 
12
 * Licensed under The MIT License
 
13
 * Redistributions of files must retain the above copyright notice.
 
14
 *
 
15
 * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
 
16
 * @link          http://cakephp.org CakePHP(tm) Project
 
17
 * @package       cake
 
18
 * @subpackage    cake.cake.libs.controller.components
 
19
 * @since         CakePHP(tm) v 0.10.0.1076
 
20
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 
21
 */
 
22
 
 
23
/**
 
24
 * Access Control List factory class.
 
25
 *
 
26
 * Uses a strategy pattern to allow custom ACL implementations to be used with the same component interface.
 
27
 * You can define by changing `Configure::write('Acl.classname', 'DbAcl');` in your core.php. Concrete ACL
 
28
 * implementations should extend `AclBase` and implement the methods it defines.
 
29
 *
 
30
 * @package       cake
 
31
 * @subpackage    cake.cake.libs.controller.components
 
32
 * @link http://book.cakephp.org/view/1242/Access-Control-Lists
 
33
 */
 
34
class AclComponent extends Object {
 
35
 
 
36
/**
 
37
 * Instance of an ACL class
 
38
 *
 
39
 * @var object
 
40
 * @access protected
 
41
 */
 
42
        var $_Instance = null;
 
43
 
 
44
/**
 
45
 * Constructor. Will return an instance of the correct ACL class as defined in `Configure::read('Acl.classname')`
 
46
 *
 
47
 */
 
48
        function __construct() {
 
49
                $name = Inflector::camelize(strtolower(Configure::read('Acl.classname')));
 
50
                if (!class_exists($name)) {
 
51
                        if (App::import('Component', $name)) {
 
52
                                list($plugin, $name) = pluginSplit($name);
 
53
                                $name .= 'Component';
 
54
                        } else {
 
55
                                trigger_error(sprintf(__('Could not find %s.', true), $name), E_USER_WARNING);
 
56
                        }
 
57
                }
 
58
                $this->_Instance =& new $name();
 
59
                $this->_Instance->initialize($this);
 
60
        }
 
61
 
 
62
/**
 
63
 * Startup is not used
 
64
 *
 
65
 * @param object $controller Controller using this component
 
66
 * @return boolean Proceed with component usage (true), or fail (false)
 
67
 * @access public
 
68
 */
 
69
        function startup(&$controller) {
 
70
                return true;
 
71
        }
 
72
 
 
73
/**
 
74
 * Empty class defintion, to be overridden in subclasses.
 
75
 *
 
76
 * @access protected
 
77
 */
 
78
        function _initACL() {
 
79
        }
 
80
 
 
81
/**
 
82
 * Pass-thru function for ACL check instance.  Check methods
 
83
 * are used to check whether or not an ARO can access an ACO
 
84
 *
 
85
 * @param string $aro ARO The requesting object identifier.
 
86
 * @param string $aco ACO The controlled object identifier.
 
87
 * @param string $action Action (defaults to *)
 
88
 * @return boolean Success
 
89
 * @access public
 
90
 */
 
91
        function check($aro, $aco, $action = "*") {
 
92
                return $this->_Instance->check($aro, $aco, $action);
 
93
        }
 
94
 
 
95
/**
 
96
 * Pass-thru function for ACL allow instance. Allow methods
 
97
 * are used to grant an ARO access to an ACO.
 
98
 *
 
99
 * @param string $aro ARO The requesting object identifier.
 
100
 * @param string $aco ACO The controlled object identifier.
 
101
 * @param string $action Action (defaults to *)
 
102
 * @return boolean Success
 
103
 * @access public
 
104
 */
 
105
        function allow($aro, $aco, $action = "*") {
 
106
                return $this->_Instance->allow($aro, $aco, $action);
 
107
        }
 
108
 
 
109
/**
 
110
 * Pass-thru function for ACL deny instance. Deny methods
 
111
 * are used to remove permission from an ARO to access an ACO.
 
112
 *
 
113
 * @param string $aro ARO The requesting object identifier.
 
114
 * @param string $aco ACO The controlled object identifier.
 
115
 * @param string $action Action (defaults to *)
 
116
 * @return boolean Success
 
117
 * @access public
 
118
 */
 
119
        function deny($aro, $aco, $action = "*") {
 
120
                return $this->_Instance->deny($aro, $aco, $action);
 
121
        }
 
122
 
 
123
/**
 
124
 * Pass-thru function for ACL inherit instance. Inherit methods
 
125
 * modify the permission for an ARO to be that of its parent object.
 
126
 *
 
127
 * @param string $aro ARO The requesting object identifier.
 
128
 * @param string $aco ACO The controlled object identifier.
 
129
 * @param string $action Action (defaults to *)
 
130
 * @return boolean Success
 
131
 * @access public
 
132
 */
 
133
        function inherit($aro, $aco, $action = "*") {
 
134
                return $this->_Instance->inherit($aro, $aco, $action);
 
135
        }
 
136
 
 
137
/**
 
138
 * Pass-thru function for ACL grant instance. An alias for AclComponent::allow()
 
139
 *
 
140
 * @param string $aro ARO The requesting object identifier.
 
141
 * @param string $aco ACO The controlled object identifier.
 
142
 * @param string $action Action (defaults to *)
 
143
 * @return boolean Success
 
144
 * @access public
 
145
 */
 
146
        function grant($aro, $aco, $action = "*") {
 
147
                return $this->_Instance->grant($aro, $aco, $action);
 
148
        }
 
149
 
 
150
/**
 
151
 * Pass-thru function for ACL grant instance. An alias for AclComponent::deny()
 
152
 *
 
153
 * @param string $aro ARO The requesting object identifier.
 
154
 * @param string $aco ACO The controlled object identifier.
 
155
 * @param string $action Action (defaults to *)
 
156
 * @return boolean Success
 
157
 * @access public
 
158
 */
 
159
        function revoke($aro, $aco, $action = "*") {
 
160
                return $this->_Instance->revoke($aro, $aco, $action);
 
161
        }
 
162
}
 
163
 
 
164
/**
 
165
 * Access Control List abstract class. Not to be instantiated.
 
166
 * Subclasses of this class are used by AclComponent to perform ACL checks in Cake.
 
167
 *
 
168
 * @package       cake
 
169
 * @subpackage    cake.cake.libs.controller.components
 
170
 * @abstract
 
171
 */
 
172
class AclBase extends Object {
 
173
 
 
174
/**
 
175
 * This class should never be instantiated, just subclassed.
 
176
 *
 
177
 */
 
178
        function __construct() {
 
179
                if (strcasecmp(get_class($this), "AclBase") == 0 || !is_subclass_of($this, "AclBase")) {
 
180
                        trigger_error(__("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", true), E_USER_ERROR);
 
181
                        return NULL;
 
182
                }
 
183
        }
 
184
 
 
185
/**
 
186
 * Empty method to be overridden in subclasses
 
187
 *
 
188
 * @param string $aro ARO The requesting object identifier.
 
189
 * @param string $aco ACO The controlled object identifier.
 
190
 * @param string $action Action (defaults to *)
 
191
 * @access public
 
192
 */
 
193
        function check($aro, $aco, $action = "*") {
 
194
        }
 
195
 
 
196
/**
 
197
 * Empty method to be overridden in subclasses
 
198
 *
 
199
 * @param object $component Component
 
200
 * @access public
 
201
 */
 
202
        function initialize(&$component) {
 
203
        }
 
204
}
 
205
 
 
206
/**
 
207
 * DbAcl implements an ACL control system in the database.  ARO's and ACO's are 
 
208
 * structured into trees and a linking table is used to define permissions.  You 
 
209
 * can install the schema for DbAcl with the Schema Shell.
 
210
 *
 
211
 * `$aco` and `$aro` parameters can be slash delimited paths to tree nodes.
 
212
 *
 
213
 * eg. `controllers/Users/edit`
 
214
 *
 
215
 * Would point to a tree structure like
 
216
 *
 
217
 * {{{
 
218
 *      controllers
 
219
 *              Users
 
220
 *                      edit
 
221
 * }}}
 
222
 *
 
223
 * @package       cake
 
224
 * @subpackage    cake.cake.libs.model
 
225
 */
 
226
class DbAcl extends AclBase {
 
227
 
 
228
/**
 
229
 * Constructor
 
230
 *
 
231
 */
 
232
        function __construct() {
 
233
                parent::__construct();
 
234
                if (!class_exists('AclNode')) {
 
235
                        require LIBS . 'model' . DS . 'db_acl.php';
 
236
                }
 
237
                $this->Aro =& ClassRegistry::init(array('class' => 'Aro', 'alias' => 'Aro'));
 
238
                $this->Aco =& ClassRegistry::init(array('class' => 'Aco', 'alias' => 'Aco'));
 
239
        }
 
240
 
 
241
/**
 
242
 * Initializes the containing component and sets the Aro/Aco objects to it.
 
243
 *
 
244
 * @param AclComponent $component
 
245
 * @return void
 
246
 * @access public
 
247
 */
 
248
        function initialize(&$component) {
 
249
                $component->Aro =& $this->Aro;
 
250
                $component->Aco =& $this->Aco;
 
251
        }
 
252
 
 
253
/**
 
254
 * Checks if the given $aro has access to action $action in $aco
 
255
 *
 
256
 * @param string $aro ARO The requesting object identifier.
 
257
 * @param string $aco ACO The controlled object identifier.
 
258
 * @param string $action Action (defaults to *)
 
259
 * @return boolean Success (true if ARO has access to action in ACO, false otherwise)
 
260
 * @access public
 
261
 * @link http://book.cakephp.org/view/1249/Checking-Permissions-The-ACL-Component
 
262
 */
 
263
        function check($aro, $aco, $action = "*") {
 
264
                if ($aro == null || $aco == null) {
 
265
                        return false;
 
266
                }
 
267
 
 
268
                $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
 
269
                $aroPath = $this->Aro->node($aro);
 
270
                $acoPath = $this->Aco->node($aco);
 
271
 
 
272
                if (empty($aroPath) || empty($acoPath)) {
 
273
                        trigger_error(__("DbAcl::check() - Failed ARO/ACO node lookup in permissions check.  Node references:\nAro: ", true) . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
 
274
                        return false;
 
275
                }
 
276
 
 
277
                if ($acoPath == null || $acoPath == array()) {
 
278
                        trigger_error(__("DbAcl::check() - Failed ACO node lookup in permissions check.  Node references:\nAro: ", true) . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
 
279
                        return false;
 
280
                }
 
281
 
 
282
                $aroNode = $aroPath[0];
 
283
                $acoNode = $acoPath[0];
 
284
 
 
285
                if ($action != '*' && !in_array('_' . $action, $permKeys)) {
 
286
                        trigger_error(sprintf(__("ACO permissions key %s does not exist in DbAcl::check()", true), $action), E_USER_NOTICE);
 
287
                        return false;
 
288
                }
 
289
 
 
290
                $inherited = array();
 
291
                $acoIDs = Set::extract($acoPath, '{n}.' . $this->Aco->alias . '.id');
 
292
 
 
293
                $count = count($aroPath);
 
294
                for ($i = 0 ; $i < $count; $i++) {
 
295
                        $permAlias = $this->Aro->Permission->alias;
 
296
 
 
297
                        $perms = $this->Aro->Permission->find('all', array(
 
298
                                'conditions' => array(
 
299
                                        "{$permAlias}.aro_id" => $aroPath[$i][$this->Aro->alias]['id'],
 
300
                                        "{$permAlias}.aco_id" => $acoIDs
 
301
                                ),
 
302
                                'order' => array($this->Aco->alias . '.lft' => 'desc'),
 
303
                                'recursive' => 0
 
304
                        ));
 
305
 
 
306
                        if (empty($perms)) {
 
307
                                continue;
 
308
                        } else {
 
309
                                $perms = Set::extract($perms, '{n}.' . $this->Aro->Permission->alias);
 
310
                                foreach ($perms as $perm) {
 
311
                                        if ($action == '*') {
 
312
 
 
313
                                                foreach ($permKeys as $key) {
 
314
                                                        if (!empty($perm)) {
 
315
                                                                if ($perm[$key] == -1) {
 
316
                                                                        return false;
 
317
                                                                } elseif ($perm[$key] == 1) {
 
318
                                                                        $inherited[$key] = 1;
 
319
                                                                }
 
320
                                                        }
 
321
                                                }
 
322
 
 
323
                                                if (count($inherited) === count($permKeys)) {
 
324
                                                        return true;
 
325
                                                }
 
326
                                        } else {
 
327
                                                switch ($perm['_' . $action]) {
 
328
                                                        case -1:
 
329
                                                                return false;
 
330
                                                        case 0:
 
331
                                                                continue;
 
332
                                                        break;
 
333
                                                        case 1:
 
334
                                                                return true;
 
335
                                                        break;
 
336
                                                }
 
337
                                        }
 
338
                                }
 
339
                        }
 
340
                }
 
341
                return false;
 
342
        }
 
343
 
 
344
/**
 
345
 * Allow $aro to have access to action $actions in $aco
 
346
 *
 
347
 * @param string $aro ARO The requesting object identifier.
 
348
 * @param string $aco ACO The controlled object identifier.
 
349
 * @param string $actions Action (defaults to *)
 
350
 * @param integer $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
 
351
 * @return boolean Success
 
352
 * @access public
 
353
 * @link http://book.cakephp.org/view/1248/Assigning-Permissions
 
354
 */
 
355
        function allow($aro, $aco, $actions = "*", $value = 1) {
 
356
                $perms = $this->getAclLink($aro, $aco);
 
357
                $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
 
358
                $save = array();
 
359
 
 
360
                if ($perms == false) {
 
361
                        trigger_error(__('DbAcl::allow() - Invalid node', true), E_USER_WARNING);
 
362
                        return false;
 
363
                }
 
364
                if (isset($perms[0])) {
 
365
                        $save = $perms[0][$this->Aro->Permission->alias];
 
366
                }
 
367
 
 
368
                if ($actions == "*") {
 
369
                        $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
 
370
                        $save = array_combine($permKeys, array_pad(array(), count($permKeys), $value));
 
371
                } else {
 
372
                        if (!is_array($actions)) {
 
373
                                $actions = array('_' . $actions);
 
374
                        }
 
375
                        if (is_array($actions)) {
 
376
                                foreach ($actions as $action) {
 
377
                                        if ($action{0} != '_') {
 
378
                                                $action = '_' . $action;
 
379
                                        }
 
380
                                        if (in_array($action, $permKeys)) {
 
381
                                                $save[$action] = $value;
 
382
                                        }
 
383
                                }
 
384
                        }
 
385
                }
 
386
                list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']);
 
387
 
 
388
                if ($perms['link'] != null && !empty($perms['link'])) {
 
389
                        $save['id'] = $perms['link'][0][$this->Aro->Permission->alias]['id'];
 
390
                } else {
 
391
                        unset($save['id']);
 
392
                        $this->Aro->Permission->id = null;
 
393
                }
 
394
                return ($this->Aro->Permission->save($save) !== false);
 
395
        }
 
396
 
 
397
/**
 
398
 * Deny access for $aro to action $action in $aco
 
399
 *
 
400
 * @param string $aro ARO The requesting object identifier.
 
401
 * @param string $aco ACO The controlled object identifier.
 
402
 * @param string $actions Action (defaults to *)
 
403
 * @return boolean Success
 
404
 * @access public
 
405
 * @link http://book.cakephp.org/view/1248/Assigning-Permissions
 
406
 */
 
407
        function deny($aro, $aco, $action = "*") {
 
408
                return $this->allow($aro, $aco, $action, -1);
 
409
        }
 
410
 
 
411
/**
 
412
 * Let access for $aro to action $action in $aco be inherited
 
413
 *
 
414
 * @param string $aro ARO The requesting object identifier.
 
415
 * @param string $aco ACO The controlled object identifier.
 
416
 * @param string $actions Action (defaults to *)
 
417
 * @return boolean Success
 
418
 * @access public
 
419
 */
 
420
        function inherit($aro, $aco, $action = "*") {
 
421
                return $this->allow($aro, $aco, $action, 0);
 
422
        }
 
423
 
 
424
/**
 
425
 * Allow $aro to have access to action $actions in $aco
 
426
 *
 
427
 * @param string $aro ARO The requesting object identifier.
 
428
 * @param string $aco ACO The controlled object identifier.
 
429
 * @param string $actions Action (defaults to *)
 
430
 * @return boolean Success
 
431
 * @see allow()
 
432
 * @access public
 
433
 */
 
434
        function grant($aro, $aco, $action = "*") {
 
435
                return $this->allow($aro, $aco, $action);
 
436
        }
 
437
 
 
438
/**
 
439
 * Deny access for $aro to action $action in $aco
 
440
 *
 
441
 * @param string $aro ARO The requesting object identifier.
 
442
 * @param string $aco ACO The controlled object identifier.
 
443
 * @param string $actions Action (defaults to *)
 
444
 * @return boolean Success
 
445
 * @see deny()
 
446
 * @access public
 
447
 */
 
448
        function revoke($aro, $aco, $action = "*") {
 
449
                return $this->deny($aro, $aco, $action);
 
450
        }
 
451
 
 
452
/**
 
453
 * Get an array of access-control links between the given Aro and Aco
 
454
 *
 
455
 * @param string $aro ARO The requesting object identifier.
 
456
 * @param string $aco ACO The controlled object identifier.
 
457
 * @return array Indexed array with: 'aro', 'aco' and 'link'
 
458
 * @access public
 
459
 */
 
460
        function getAclLink($aro, $aco) {
 
461
                $obj = array();
 
462
                $obj['Aro'] = $this->Aro->node($aro);
 
463
                $obj['Aco'] = $this->Aco->node($aco);
 
464
 
 
465
                if (empty($obj['Aro']) || empty($obj['Aco'])) {
 
466
                        return false;
 
467
                }
 
468
 
 
469
                return array(
 
470
                        'aro' => Set::extract($obj, 'Aro.0.'.$this->Aro->alias.'.id'),
 
471
                        'aco'  => Set::extract($obj, 'Aco.0.'.$this->Aco->alias.'.id'),
 
472
                        'link' => $this->Aro->Permission->find('all', array('conditions' => array(
 
473
                                $this->Aro->Permission->alias . '.aro_id' => Set::extract($obj, 'Aro.0.'.$this->Aro->alias.'.id'),
 
474
                                $this->Aro->Permission->alias . '.aco_id' => Set::extract($obj, 'Aco.0.'.$this->Aco->alias.'.id')
 
475
                        )))
 
476
                );
 
477
        }
 
478
 
 
479
/**
 
480
 * Get the keys used in an ACO
 
481
 *
 
482
 * @param array $keys Permission model info
 
483
 * @return array ACO keys
 
484
 * @access protected
 
485
 */
 
486
        function _getAcoKeys($keys) {
 
487
                $newKeys = array();
 
488
                $keys = array_keys($keys);
 
489
                foreach ($keys as $key) {
 
490
                        if (!in_array($key, array('id', 'aro_id', 'aco_id'))) {
 
491
                                $newKeys[] = $key;
 
492
                        }
 
493
                }
 
494
                return $newKeys;
 
495
        }
 
496
}
 
497
 
 
498
/**
 
499
 * IniAcl implements an access control system using an INI file.  An example 
 
500
 * of the ini file used can be found in /config/acl.ini.php.
 
501
 *
 
502
 * @package       cake
 
503
 * @subpackage    cake.cake.libs.model.iniacl
 
504
 */
 
505
class IniAcl extends AclBase {
 
506
 
 
507
/**
 
508
 * Array with configuration, parsed from ini file
 
509
 *
 
510
 * @var array
 
511
 * @access public
 
512
 */
 
513
        var $config = null;
 
514
 
 
515
/**
 
516
 * The constructor must be overridden, as AclBase is abstract.
 
517
 *
 
518
 */
 
519
        function __construct() {
 
520
        }
 
521
 
 
522
/**
 
523
 * Main ACL check function. Checks to see if the ARO (access request object) has access to the 
 
524
 * ACO (access control object).Looks at the acl.ini.php file for permissions 
 
525
 * (see instructions in /config/acl.ini.php).
 
526
 *
 
527
 * @param string $aro ARO
 
528
 * @param string $aco ACO
 
529
 * @param string $aco_action Action
 
530
 * @return boolean Success
 
531
 * @access public
 
532
 */
 
533
        function check($aro, $aco, $aco_action = null) {
 
534
                if ($this->config == null) {
 
535
                        $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php');
 
536
                }
 
537
                $aclConfig = $this->config;
 
538
 
 
539
                if (isset($aclConfig[$aro]['deny'])) {
 
540
                        $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
 
541
 
 
542
                        if (array_search($aco, $userDenies)) {
 
543
                                return false;
 
544
                        }
 
545
                }
 
546
 
 
547
                if (isset($aclConfig[$aro]['allow'])) {
 
548
                        $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
 
549
 
 
550
                        if (array_search($aco, $userAllows)) {
 
551
                                return true;
 
552
                        }
 
553
                }
 
554
 
 
555
                if (isset($aclConfig[$aro]['groups'])) {
 
556
                        $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
 
557
 
 
558
                        foreach ($userGroups as $group) {
 
559
                                if (array_key_exists($group, $aclConfig)) {
 
560
                                        if (isset($aclConfig[$group]['deny'])) {
 
561
                                                $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
 
562
 
 
563
                                                if (array_search($aco, $groupDenies)) {
 
564
                                                        return false;
 
565
                                                }
 
566
                                        }
 
567
 
 
568
                                        if (isset($aclConfig[$group]['allow'])) {
 
569
                                                $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
 
570
 
 
571
                                                if (array_search($aco, $groupAllows)) {
 
572
                                                        return true;
 
573
                                                }
 
574
                                        }
 
575
                                }
 
576
                        }
 
577
                }
 
578
                return false;
 
579
        }
 
580
 
 
581
/**
 
582
 * Parses an INI file and returns an array that reflects the INI file's section structure. Double-quote friendly.
 
583
 *
 
584
 * @param string $fileName File
 
585
 * @return array INI section structure
 
586
 * @access public
 
587
 */
 
588
        function readConfigFile($fileName) {
 
589
                $fileLineArray = file($fileName);
 
590
 
 
591
                foreach ($fileLineArray as $fileLine) {
 
592
                        $dataLine = trim($fileLine);
 
593
                        $firstChar = substr($dataLine, 0, 1);
 
594
 
 
595
                        if ($firstChar != ';' && $dataLine != '') {
 
596
                                if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
 
597
                                        $sectionName = preg_replace('/[\[\]]/', '', $dataLine);
 
598
                                } else {
 
599
                                        $delimiter = strpos($dataLine, '=');
 
600
 
 
601
                                        if ($delimiter > 0) {
 
602
                                                $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
 
603
                                                $value = trim(substr($dataLine, $delimiter + 1));
 
604
 
 
605
                                                if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
 
606
                                                        $value = substr($value, 1, -1);
 
607
                                                }
 
608
 
 
609
                                                $iniSetting[$sectionName][$key]=stripcslashes($value);
 
610
                                        } else {
 
611
                                                if (!isset($sectionName)) {
 
612
                                                        $sectionName = '';
 
613
                                                }
 
614
 
 
615
                                                $iniSetting[$sectionName][strtolower(trim($dataLine))]='';
 
616
                                        }
 
617
                                }
 
618
                        }
 
619
                }
 
620
 
 
621
                return $iniSetting;
 
622
        }
 
623
 
 
624
/**
 
625
 * Removes trailing spaces on all array elements (to prepare for searching)
 
626
 *
 
627
 * @param array $array Array to trim
 
628
 * @return array Trimmed array
 
629
 * @access public
 
630
 */
 
631
        function arrayTrim($array) {
 
632
                foreach ($array as $key => $value) {
 
633
                        $array[$key] = trim($value);
 
634
                }
 
635
                array_unshift($array, "");
 
636
                return $array;
 
637
        }
 
638
}