Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 161 |
|
0.00% |
0 / 19 |
CRAP | |
0.00% |
0 / 1 |
| MySqlSiteSettings | |
0.00% |
0 / 161 |
|
0.00% |
0 / 19 |
3660 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 | |||
| isConsistent | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
42 | |||
| fetchSettings | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
12 | |||
| initEnvironment | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
| __isset | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| __set | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| __get | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
| get | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| getDescription | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
| getEnvironment | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
| set | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
42 | |||
| register | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
42 | |||
| getRegisteredSettings | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| getLocales | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
| getThemes | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
| getPlugins | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
| getSystemInfo | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
| getLog | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
20 | |||
| store | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
56 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace UserFrosting; |
| 4 | |
| 5 | /** |
| 6 | * MySqlSiteSettings Class |
| 7 | * |
| 8 | * A site settings database object for MySQL databases. |
| 9 | * |
| 10 | */ |
| 11 | class MySqlSiteSettings extends MySqlDatabase implements SiteSettingsInterface { |
| 12 | |
| 13 | /** |
| 14 | * @var array An array of UF environment variables. Should be read-only. |
| 15 | */ |
| 16 | protected $_environment; |
| 17 | |
| 18 | /** |
| 19 | * @var array A list of plugin names => arrays of settings for that plugin. The core plugin is "userfrosting". |
| 20 | */ |
| 21 | protected $_settings; |
| 22 | |
| 23 | /** |
| 24 | * @var array A list of plugin names => arrays of descriptions for that plugin. The core plugin is "userfrosting". |
| 25 | */ |
| 26 | protected $_descriptions; |
| 27 | |
| 28 | /** |
| 29 | * @var array A list of settings that have been registered to appear in the site settings interface. |
| 30 | */ |
| 31 | protected $_settings_registered; |
| 32 | |
| 33 | /** |
| 34 | * @var string The name of the table, including prefix, that contains the persistent site settings. |
| 35 | */ |
| 36 | protected $_table; |
| 37 | |
| 38 | /** Construct the site settings object, loading values from the database */ |
| 39 | public function __construct($settings = [], $descriptions = []) { |
| 40 | $this->_table = static::getTable('configuration'); |
| 41 | |
| 42 | // Initialize UF environment |
| 43 | $this->initEnvironment(); |
| 44 | |
| 45 | // Set default settings first |
| 46 | $this->_settings = $settings; |
| 47 | $this->_descriptions = $descriptions; |
| 48 | |
| 49 | // Now, try to load settings from database if possible |
| 50 | try { |
| 51 | $results = $this->fetchSettings(); |
| 52 | // Merge, replacing default settings with DB settings as necessary. |
| 53 | $this->_settings = array_replace_recursive($this->_settings , $results['settings']); |
| 54 | $this->_descriptions = array_replace_recursive($this->_descriptions, $results['descriptions']); |
| 55 | } catch (\PDOException $e){ |
| 56 | $connection = static::connection(); |
| 57 | $table = static::getTable('configuration')->name; |
| 58 | |
| 59 | // If the database connection is fine, but the table doesn't exist, create it! |
| 60 | $connection->query("CREATE TABLE IF NOT EXISTS `$table` ( |
| 61 | `id` int(10) unsigned NOT NULL AUTO_INCREMENT, |
| 62 | `plugin` varchar(50) NOT NULL COMMENT 'The name of the plugin that manages this setting (set to ''userfrosting'' for core settings)', |
| 63 | `name` varchar(150) NOT NULL COMMENT 'The name of the setting.', |
| 64 | `value` longtext NOT NULL COMMENT 'The current value of the setting.', |
| 65 | `description` text NOT NULL COMMENT 'A brief description of this setting.', |
| 66 | PRIMARY KEY (`id`) |
| 67 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='A configuration table, mapping global configuration options to their values.' AUTO_INCREMENT=1 ;"); |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | public function isConsistent(){ |
| 72 | $connection = static::connection(); |
| 73 | $prefix = static::$app->config('db')['db_prefix']; |
| 74 | |
| 75 | $table_exists = $connection->query("SHOW TABLES LIKE '$prefix" . "configuration'")->rowCount() > 0; |
| 76 | |
| 77 | if (!$table_exists){ |
| 78 | return false; |
| 79 | } |
| 80 | |
| 81 | $db_data = $this->fetchSettings()['settings']; |
| 82 | foreach ($this->_settings as $plugin => $setting){ |
| 83 | if (!isset($db_data[$plugin])){ |
| 84 | return false; |
| 85 | } |
| 86 | foreach ($setting as $name => $value){ |
| 87 | if (!isset($db_data[$plugin][$name])){ |
| 88 | return false; |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | return true; |
| 93 | } |
| 94 | |
| 95 | public function fetchSettings(){ |
| 96 | $db = static::connection(); |
| 97 | |
| 98 | $table = $this->_table->name; |
| 99 | |
| 100 | $stmt = $db->query("SELECT * FROM `$table`"); |
| 101 | |
| 102 | $results = []; |
| 103 | $results['settings'] = []; |
| 104 | $results['descriptions'] = []; |
| 105 | while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
| 106 | $name = $row['name']; |
| 107 | $value = $row['value']; |
| 108 | $plugin = $row['plugin']; |
| 109 | $description = $row['description']; |
| 110 | if (!isset($results['settings'][$plugin])) { |
| 111 | $results['settings'][$plugin] = []; |
| 112 | $results['descriptions'][$plugin] = []; |
| 113 | } |
| 114 | |
| 115 | $results['settings'][$plugin][$name] = $value; |
| 116 | $results['descriptions'][$plugin][$name] = $description; |
| 117 | } |
| 118 | return $results; |
| 119 | } |
| 120 | |
| 121 | /** |
| 122 | * Initialize the environment (non-persistent) variables for the app. This includes things like the public root URL, css URLs, etc. |
| 123 | * |
| 124 | */ |
| 125 | private function initEnvironment(){ |
| 126 | $this->_environment = [ |
| 127 | 'uri' => static::$app->config('uri') |
| 128 | ]; |
| 129 | } |
| 130 | |
| 131 | public function __isset($name) { |
| 132 | if (isset($this->_environment[$name]) || isset($this->_settings['userfrosting'][$name])) |
| 133 | return true; |
| 134 | else |
| 135 | return false; |
| 136 | } |
| 137 | |
| 138 | public function __set($name, $value){ |
| 139 | return $this->set('userfrosting', $name, $value); |
| 140 | } |
| 141 | |
| 142 | public function __get($name){ |
| 143 | if (isset($this->_environment[$name])){ |
| 144 | return $this->_environment[$name]; |
| 145 | } else if (isset($this->_settings['userfrosting'][$name])){ |
| 146 | return $this->_settings['userfrosting'][$name]; |
| 147 | } else { |
| 148 | throw new \Exception("The value '$name' does not exist in the core userfrosting settings."); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | public function get($name, $plugin = "userfrosting"){ |
| 153 | if (isset($this->_settings[$plugin]) && isset($this->_settings[$plugin][$name])){ |
| 154 | return $this->_settings[$plugin][$name]; |
| 155 | } else { |
| 156 | throw new \Exception("The value '$name' does not exist in the settings for plugin '$plugin'."); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | public function getDescription($name, $plugin = "userfrosting"){ |
| 161 | if (isset($this->_settings[$plugin]) && isset($this->_descriptions[$plugin][$name])){ |
| 162 | return $this->_descriptions[$plugin][$name]; |
| 163 | } else { |
| 164 | throw new \Exception("The value '$name' does not exist in the setting descriptions for plugin '$plugin'."); |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | public function getEnvironment($name){ |
| 169 | if (isset($this->_environment[$name])){ |
| 170 | return $this->_environment[$name]; |
| 171 | } else { |
| 172 | throw new \Exception("The value '$name' does not exist in the settings environment."); |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | public function set($plugin, $name, $value = null, $description = null){ |
| 177 | if (!isset($this->_settings[$plugin])){ |
| 178 | $this->_settings[$plugin] = []; |
| 179 | $this->_descriptions[$plugin] = []; |
| 180 | } |
| 181 | if ($value !== null) { |
| 182 | $this->_settings[$plugin][$name] = $value; |
| 183 | } else { |
| 184 | if (!isset($this->_settings[$plugin][$name])) |
| 185 | $this->_settings[$plugin][$name] = ""; |
| 186 | } |
| 187 | if ($description !== null) { |
| 188 | $this->_descriptions[$plugin][$name] = $description; |
| 189 | } else { |
| 190 | if (!isset($this->_descriptions[$plugin][$name])) |
| 191 | $this->_descriptions[$plugin][$name] = ""; |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | public function register($plugin, $name, $label, $type = "text", $options = []){ |
| 196 | // Get the array of settings & descriptions |
| 197 | if (isset($this->_settings[$plugin])){ |
| 198 | $settings = $this->_settings[$plugin]; |
| 199 | $descriptions = $this->_descriptions[$plugin]; |
| 200 | } else { |
| 201 | throw new \Exception("The plugin '$plugin' does not have any site settings. Be sure to add them first by calling set()."); |
| 202 | } |
| 203 | |
| 204 | if (!isset($settings[$name])){ |
| 205 | throw new \Exception("The plugin '$plugin' does not have a value for '$name'. Please add it first by calling set()."); |
| 206 | } |
| 207 | |
| 208 | // Check type |
| 209 | if (!in_array($type, ["readonly", "text", "toggle", "select"])) |
| 210 | throw new \Exception("Type must be one of 'readonly', 'text', 'toggle', or 'select'."); |
| 211 | |
| 212 | if (!isset($this->_settings_registered[$plugin])) |
| 213 | $this->_settings_registered[$plugin] = []; |
| 214 | if (!isset($this->_settings_registered[$plugin][$name])) |
| 215 | $this->_settings_registered[$plugin][$name] = []; |
| 216 | |
| 217 | $this->_settings_registered[$plugin][$name]['label'] = $label; |
| 218 | $this->_settings_registered[$plugin][$name]['type'] = $type; |
| 219 | $this->_settings_registered[$plugin][$name]['options'] = $options; |
| 220 | $this->_settings_registered[$plugin][$name]['description'] = $descriptions[$name]; |
| 221 | } |
| 222 | |
| 223 | public function getRegisteredSettings(){ |
| 224 | foreach ($this->_settings_registered as $plugin => $setting){ |
| 225 | foreach ($setting as $name => $params){ |
| 226 | $this->_settings_registered[$plugin][$name]['value'] = $this->_settings[$plugin][$name]; |
| 227 | } |
| 228 | } |
| 229 | return $this->_settings_registered; |
| 230 | } |
| 231 | |
| 232 | // Get a list of all supported locales |
| 233 | public function getLocales(){ |
| 234 | $directory = static::$app->config('locales.path'); |
| 235 | $languages = glob($directory . "/*.php"); |
| 236 | $results = []; |
| 237 | foreach ($languages as $language){ |
| 238 | $basename = basename($language, ".php"); |
| 239 | $results[$basename] = $basename; |
| 240 | } |
| 241 | return $results; |
| 242 | } |
| 243 | |
| 244 | // Get a list of all supported themes |
| 245 | public function getThemes(){ |
| 246 | $directory = static::$app->config('themes.path'); |
| 247 | $themes = glob($directory . "/*", GLOB_ONLYDIR); |
| 248 | $results = []; |
| 249 | foreach ($themes as $theme){ |
| 250 | $basename = basename($theme); |
| 251 | $results[$basename] = $basename; |
| 252 | } |
| 253 | return $results; |
| 254 | } |
| 255 | |
| 256 | // Get a list of all plugins |
| 257 | public function getPlugins(){ |
| 258 | $directory = static::$app->config('plugins.path'); |
| 259 | $themes = glob($directory . "/*", GLOB_ONLYDIR); |
| 260 | $results = []; |
| 261 | foreach ($themes as $theme){ |
| 262 | $basename = basename($theme); |
| 263 | $results[$basename] = $basename; |
| 264 | } |
| 265 | return $results; |
| 266 | } |
| 267 | // Return an array of system and server configuration info |
| 268 | public function getSystemInfo(){ |
| 269 | $results = []; |
| 270 | $results['UserFrosting Version'] = $this->version; |
| 271 | $results['Web Server'] = $_SERVER['SERVER_SOFTWARE']; |
| 272 | $results['PHP Version'] = phpversion(); |
| 273 | $dbinfo = static::getInfo(); |
| 274 | $results['Database Version'] = $dbinfo['db_type'] . " " . $dbinfo['db_version']; |
| 275 | $results['Database Name'] = $dbinfo['db_name']; |
| 276 | $results['Table Prefix'] = $dbinfo['table_prefix']; |
| 277 | $environment = static::$app->environment(); |
| 278 | $results['Application Root'] = static::$app->config('base.path'); |
| 279 | $results['Document Root'] = $this->uri['public']; |
| 280 | return $results; |
| 281 | } |
| 282 | |
| 283 | // Return the error log |
| 284 | public function getLog($lines = null){ |
| 285 | // Check if error logging is enabled |
| 286 | if (!ini_get("error_log")){ |
| 287 | $path = "Unavailable"; |
| 288 | $messages = ["You do not seem to have an error log set up. Please check your php.ini file."]; |
| 289 | } else if (!ini_get("log_errors")){ |
| 290 | $path = ini_get('error_log'); |
| 291 | $messages = ["Error logging appears to be disabled. Please check your php.ini file."]; |
| 292 | } else { |
| 293 | $path = ini_get('error_log'); |
| 294 | if ($lines){ |
| 295 | $messages = array_reverse(array_slice(file($path), -$lines)); |
| 296 | } else { |
| 297 | $messages = array_reverse(file($path)); |
| 298 | } |
| 299 | } |
| 300 | return [ |
| 301 | "path" => $path, |
| 302 | "messages" => $messages |
| 303 | ]; |
| 304 | } |
| 305 | |
| 306 | public function store(){ |
| 307 | // Get current values as stored in DB |
| 308 | $db_settings = $this->fetchSettings(); |
| 309 | |
| 310 | $db = static::connection(); |
| 311 | $table = $this->_table->name; |
| 312 | |
| 313 | $stmt_insert = $db->prepare("INSERT INTO `$table` |
| 314 | (plugin, name, value, description) |
| 315 | VALUES (:plugin, :name, :value, :description);"); |
| 316 | |
| 317 | $stmt_update = $db->prepare("UPDATE `$table` SET |
| 318 | value = :value, |
| 319 | description = :description |
| 320 | WHERE plugin = :plugin and name = :name;"); |
| 321 | |
| 322 | // For each setting in this object, check if it exists in DB. If it does not exist, add. If it exists and is different from the current value, update. |
| 323 | foreach ($this->_settings as $plugin => $setting){ |
| 324 | foreach ($setting as $name => $value){ |
| 325 | $sqlVars = [ |
| 326 | ":plugin" => $plugin, |
| 327 | ":name" => $name, |
| 328 | ":value" => $value, |
| 329 | ":description" => $this->_descriptions[$plugin][$name] |
| 330 | ]; |
| 331 | if (!isset($db_settings['settings'][$plugin]) || !isset($db_settings['settings'][$plugin][$name])){ |
| 332 | $stmt_insert->execute($sqlVars); |
| 333 | } else if (($db_settings['settings'][$plugin][$name] !== $this->_settings[$plugin][$name]) || ($db_settings['descriptions'][$plugin][$name] !== $this->_descriptions[$plugin][$name])){ |
| 334 | $stmt_update->execute($sqlVars); |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | return true; |
| 340 | } |
| 341 | } |