1: <?php
2: /*
3: You may not change or alter any portion of this comment or credits
4: of supporting developers from this source code or any supporting source code
5: which is considered copyrighted (c) material of the original comment or credit authors.
6:
7: This program is distributed in the hope that it will be useful,
8: but WITHOUT ANY WARRANTY; without even the implied warranty of
9: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10: */
11:
12: use Xoops\Core\Yaml;
13:
14: /**
15: * XoopsBaseConfig holds the base XOOPS configs needed to locate key paths and
16: * enable database access
17: *
18: * @category XoopsBaseConfig
19: * @package XoopsBaseConfig
20: * @author Richard Griffith <richard@geekwright.com>
21: * @copyright 2015 XOOPS Project (http://xoops.org)
22: * @license GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
23: * @link http://xoops.org
24: */
25: class XoopsBaseConfig
26: {
27: /**
28: * @var string[] $configs
29: */
30: private static $configs = array();
31:
32: /**
33: * __construct
34: * @param string|string[] $config fully qualified name of configuration file
35: * or configuration array
36: * @throws Exception
37: */
38: final private function __construct($config)
39: {
40: if (!class_exists('XoopsLoad', false)) {
41: include __DIR__ . '/xoopsload.php';
42: }
43: if (is_string($config)) {
44: $yamlString = file_get_contents($config);
45: if ($yamlString === false) {
46: throw new \Exception('XoopsBaseConfig failed to load configuration.');
47: }
48: $loaderPath = $this->extractLibPath($yamlString) . '/vendor/autoload.php';
49: if (file_exists($loaderPath)) {
50: include_once $loaderPath;
51: }
52: self::$configs = Yaml::loadWrapped($yamlString);
53: \XoopsLoad::startAutoloader(self::$configs['lib-path']);
54: } elseif (is_array($config)) {
55: self::$configs = $config;
56: \XoopsLoad::startAutoloader(self::$configs['lib-path']);
57: }
58: if (!isset(self::$configs['lib-path'])) {
59: throw new \Exception('XoopsBaseConfig lib-path not defined.');
60: return;
61: }
62: \XoopsLoad::startAutoloader(self::$configs['lib-path']);
63: }
64:
65: /**
66: * Allow one instance only!
67: *
68: * @param string|string[] $config fully qualified name of configuration file
69: * or configuration array
70: *
71: * @return XoopsBaseConfig instance
72: * @throws Exception
73: */
74: final public static function getInstance($config = '')
75: {
76: static $instance = false;
77:
78: if (!$instance && !empty($config)) {
79: $instance = new \XoopsBaseConfig($config);
80: }
81:
82: if ($instance === false || empty(self::$configs)) {
83: throw new \Exception('XoopsBaseConfig failed.');
84: }
85: return $instance;
86: }
87:
88: /**
89: * extractLibPath - solve a which comes first, chicken or egg type problem
90: *
91: * The yaml file we can load has the path we need to set up the autoloader we need
92: * to reach our yaml library. We solve this by looking through the raw yaml file
93: * contents to locate our data. This works only because there is a unique key that
94: * should not be duplicated in a limited and known data set.
95: *
96: * Not pretty, but this way we get full access to xoops from a single known path.
97: *
98: * @param string $filecontents contents of the yaml configuration file
99: *
100: * @return string the extracted lib-path value
101: */
102: final private function extractLibPath($filecontents)
103: {
104: $match = array();
105: $matched = preg_match('/[.\v]*^lib-path\h*\:\h*[\']?([^\'\v]*)[\']?\h*$[.\v]*/m', $filecontents, $match);
106:
107: return $matched ? trim($match[1]) : '';
108: }
109:
110: /**
111: * Retrieve an attribute value.
112: *
113: * @param string $name name of an attribute
114: *
115: * @return mixed value of the attribute, or null if not set.
116: */
117: final public static function get($name)
118: {
119: if (isset(self::$configs[$name])) {
120: return self::$configs[$name];
121: }
122: //trigger_error('variable : '.$name.' not found!', E_USER_ERROR);
123: return null;
124: }
125:
126: /**
127: * Verify an attribute is defined.
128: *
129: * @param string $name name of an attribute
130: *
131: * @return boolean true if attribute is defined, otherwise false.
132: */
133: final public static function has($name)
134: {
135: return isset(self::$configs[$name]);
136: }
137:
138: /**
139: * Get a copy of all base configurations
140: *
141: * @return array of of all attributes
142: */
143: final public function getAll()
144: {
145: return self::$configs;
146: }
147:
148: /**
149: * Establish backward compatibility defines
150: *
151: * @return void
152: */
153: final public static function establishBCDefines()
154: {
155: if (defined('XOOPS_ROOT_PATH')) {
156: return;
157: }
158:
159: // Physical path to the XOOPS documents (served) directory WITHOUT trailing slash
160: define('XOOPS_ROOT_PATH', self::get('root-path'));
161:
162: // For forward compatibility
163: // Physical path to the XOOPS library directory WITHOUT trailing slash
164: define('XOOPS_PATH', self::get('lib-path'));
165: // Physical path to the XOOPS datafiles (writable) directory WITHOUT trailing slash
166: define('XOOPS_VAR_PATH', self::get('var-path'));
167: // Alias of XOOPS_PATH, for compatibility, temporary solution
168: define("XOOPS_TRUST_PATH", self::get('trust-path'));
169:
170: // URL Association for SSL and Protocol Compatibility
171: define('XOOPS_PROT', self::get('prot'));
172:
173: // XOOPS Virtual Path (URL)
174: // Virtual path to your main XOOPS directory WITHOUT trailing slash
175: // Example: define('XOOPS_URL', 'http://localhost/xoopscore');
176: define('XOOPS_URL', self::get('url'));
177:
178: // Secure file
179: // require XOOPS_VAR_PATH . '/data/secure.php';
180:
181: // Database
182: // Choose the database to be used
183: define('XOOPS_DB_TYPE', self::get('db-type'));
184:
185: // Set the database charset if applicable
186: define("XOOPS_DB_CHARSET", self::get('db-charset'));
187:
188: // Table Prefix
189: // This prefix will be added to all new tables created to avoid name conflict in the database.
190: define('XOOPS_DB_PREFIX', self::get('db-prefix'));
191:
192: // Database Hostname
193: // Hostname of the database server. If you are unsure, "localhost" works in most cases.
194: define('XOOPS_DB_HOST', self::get('db-host'));
195:
196: // Database Username
197: // Your database user account on the host
198: define('XOOPS_DB_USER', self::get('db-user'));
199:
200: // Database Password
201: // Password for your database user account
202: define('XOOPS_DB_PASS', self::get('db-pass'));
203:
204: // Database Name
205: // The name of database on the host.
206: define('XOOPS_DB_NAME', self::get('db-name'));
207:
208: // persistent connection is no longer supported
209: define("XOOPS_DB_PCONNECT", self::get('db-pconnect'));
210:
211: // Serialized connection parameter
212: // This is built by the installer and includes all connection parameters
213: define('XOOPS_DB_PARAMETERS', serialize(self::get('db-parameters')));
214: }
215:
216: /**
217: * Create a working environment from traditional mainfile environment
218: *
219: * For the early phases in the installer, these may not be defined. Until it
220: * is converted we try and do the best we can without errors
221: *
222: * @return void
223: */
224: final public static function bootstrapTransition()
225: {
226: $path = self::defineDefault('XOOPS_ROOT_PATH', basename(__DIR__));
227: $url = (defined('XOOPS_URL')) ?
228: XOOPS_URL :
229: ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === "on") ? 'https://' : 'http://')
230: . $_SERVER['SERVER_NAME']
231: . (($_SERVER['SERVER_PORT'] != '80') ? ':' . $_SERVER['SERVER_PORT'] : '');
232:
233: $parts = parse_url($url . '/');
234: $host = isset($parts['host']) ? $parts['host'] : $_SERVER['SERVER_NAME'];
235: $host = ($host==='localhost') ? '' : $host;
236: $urlpath = isset($parts['path']) ? $parts['path'] : '/';
237:
238: $libpath = self::defineDefault('XOOPS_PATH');
239: $varpath = self::defineDefault('XOOPS_VAR_PATH');
240:
241: $configs = array(
242: 'root-path' => $path,
243: 'lib-path' => $libpath,
244: 'var-path' => $varpath,
245: 'trust-path' => $libpath,
246: 'url' => $url,
247: 'prot' => self::defineDefault('XOOPS_PROT'),
248: 'asset-path' => $path . '/assets',
249: 'asset-url' => $url . '/assets',
250: 'themes-path' => $path .'/themes',
251: 'themes-url' => $url . '/themes',
252: 'adminthemes-path' => $path . '/modules/system/themes',
253: 'adminthemes-url' => $url . '/modules/system/themes',
254: 'media-path' => $path . '/media',
255: 'media-url' => $url . '/media',
256: 'uploads-path' => $path . '/uploads',
257: 'uploads-url' => $url . '/uploads',
258: 'cookie-domain' => $host,
259: 'cookie-path' => $urlpath,
260: 'smarty-cache' => $varpath . '/caches/smarty_cache',
261: 'smarty-compile' => $varpath . '/caches/smarty_compile',
262: 'smarty-xoops-plugins' => $libpath . '/smarty/xoops_plugins',
263: 'db-type' => self::defineDefault('XOOPS_DB_TYPE'),
264: 'db-charset' => 'utf8',
265: 'db-prefix' => self::defineDefault('XOOPS_DB_PREFIX'),
266: 'db-host' => self::defineDefault('XOOPS_DB_HOST'),
267: 'db-user' => self::defineDefault('XOOPS_DB_USER'),
268: 'db-pass' => self::defineDefault('XOOPS_DB_PASS'),
269: 'db-name' => self::defineDefault('XOOPS_DB_NAME'),
270: 'db-pconnect' => 0,
271: 'db-parameters' => defined('XOOPS_DB_PARAMETERS') ? unserialize(XOOPS_DB_PARAMETERS) : array(),
272: );
273: self::getInstance($configs);
274: }
275:
276: /**
277: * defineDefault - return a constant if it is defined, or a default value if not.
278: * If no default is specified, the define name will be used if needed.
279: *
280: * @param string $define a define constant name
281: * @param string|null $default default value to return if $define is not defined
282: *
283: * @return string value of define or default
284: */
285: private static function defineDefault($define, $default = null)
286: {
287: $default = ($default === null) ? $define : $default;
288: $return = defined($define) ? constant($define) : $default;
289: return $return;
290: }
291: }
292: