1<?php
2/**
3 * Copyright 2014-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file COPYING for license information (LGPL). If you
6 * did not receive this file, see http://www.horde.org/licenses/lgpl21.
7 *
8 * @category  Horde
9 * @copyright 2014-2017 Horde LLC
10 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
11 * @package   Core
12 */
13
14/**
15 * Represents the merged configuration of an application with the base
16 * Horde configuration.
17 *
18 * @author    Michael Slusarz <slusarz@horde.org>
19 * @category  Horde
20 * @copyright 2014-2017 Horde LLC
21 * @license   http://www.horde.org/licenses/lgpl21 LGPL 2.1
22 * @package   Core
23 * @since     2.12.0
24 */
25class Horde_Registry_Hordeconfig_Merged extends Horde_Registry_Hordeconfig
26{
27    /**
28     * Application configuration.
29     *
30     * @var Horde_Registry_Hordeconfig
31     */
32    protected $_aconfig;
33
34    /**
35     * Horde configuration.
36     *
37     * @var Horde_Registry_Hordeconfig
38     */
39    protected $_hconfig;
40
41    /**
42     * Indicates whether config is fully merged.
43     *
44     * @var boolean
45     */
46    protected $_merged = false;
47
48    /**
49     * Constructor.
50     *
51     * @param array $opts  Configuration options:
52     * <pre>
53     *   - aconfig: (Horde_Registry_Hordeconfig) Application config.
54     *   - hconfig: (Horde_Registry_Hordeconfig) Horde config.
55     * </pre>
56     */
57    public function __construct(array $opts)
58    {
59        $this->_aconfig = $opts['aconfig'];
60        $this->_hconfig = $opts['hconfig'];
61
62        $this->app = $this->_aconfig->app;
63    }
64
65    /**
66     */
67    public function toArray()
68    {
69        if (!$this->_merged) {
70            $this->_config = $this->_merge(
71                $this->_hconfig->toArray(),
72                $this->_aconfig->toArray()
73            );
74            $this->_merged = true;
75        }
76
77        return $this->_config;
78    }
79
80    /**
81     */
82    protected function _load($offset)
83    {
84        if (!$this->_merged && !isset($this->_config[$offset])) {
85            $h = $this->_hconfig[$offset];
86            $a = $this->_aconfig[$offset];
87
88            if (is_array($a)) {
89                $this->_config[$offset] = is_array($h)
90                    ? $this->_merge($h, $a)
91                    : $a;
92            } else {
93                $this->_config[$offset] = is_null($a)
94                    ? $h
95                    : $a;
96            }
97        }
98    }
99
100    /**
101     * Merge configurations between two applications.
102     * See Bug #10381.
103     *
104     * @param array $a1  Horde configuration.
105     * @param array $a2  App configuration.
106     *
107     * @return array  Merged configuration.
108     */
109    protected function _merge(array $a1, array $a2)
110    {
111        foreach ($a2 as $key => $val) {
112            if (isset($a1[$key]) && is_array($a1[$key])) {
113                reset($a1[$key]);
114                if (!is_int(key($a1[$key]))) {
115                    $val = $this->_merge($a1[$key], $val);
116                }
117            }
118            $a1[$key] = $val;
119        }
120
121        return $a1;
122    }
123
124}
125