1
0
mirror of https://github.com/freescout-helpdesk/freescout.git synced 2024-11-25 11:52:29 +01:00
freescout/app/Option.php

302 lines
8.1 KiB
PHP
Raw Normal View History

2018-08-08 09:52:53 +02:00
<?php
/**
2018-11-12 10:12:57 +01:00
* todo: implement caching by saving all options in one cache variable on register_shutdown_function.
2018-08-08 09:52:53 +02:00
*/
2018-11-12 10:12:57 +01:00
2018-08-08 09:52:53 +02:00
namespace App;
use Illuminate\Database\Eloquent\Model;
class Option extends Model
{
2018-11-28 07:05:13 +01:00
// Value returned when cache contains default value.
const CACHE_DEFAULT_VALUE = 'CACHE_DEFAULT_VALUE';
2018-09-24 15:16:27 +02:00
// todo: cache like in WordPress (fetch all options from DB each time)
2018-09-14 20:43:19 +02:00
public static $cache = [];
2018-08-08 09:52:53 +02:00
public $timestamps = false;
/**
* The attributes that are not mass assignable.
*
* @var array
*/
protected $guarded = ['id'];
2018-08-08 09:56:03 +02:00
2018-08-08 09:52:53 +02:00
/**
* Set an option.
*
2018-11-12 10:12:57 +01:00
* @param string $name
* @param string $value
*
* @return bool
2018-08-08 09:52:53 +02:00
*/
public static function set($name, $value)
{
2018-08-29 16:20:25 +02:00
$name = trim($name);
if (empty($name)) {
return false;
}
// Sanitize option
if (is_null($value)) {
$value = '';
}
if (is_object($value)) {
$value = clone $value;
}
$serialized_value = self::maybeSerialize($value);
2018-11-12 10:12:57 +01:00
$option = self::firstOrCreate(
2018-08-29 16:20:25 +02:00
['name' => $name], ['value' => $serialized_value]
2018-08-08 09:52:53 +02:00
);
2018-08-29 16:20:25 +02:00
$old_value = $option['value'];
if ($value === $old_value || self::maybeSerialize($value) === self::maybeSerialize($old_value)) {
return false;
2018-08-08 09:52:53 +02:00
}
2018-08-29 16:20:25 +02:00
$option->value = $serialized_value;
$option->save();
2018-08-08 09:52:53 +02:00
}
/**
* Get option.
*
2018-11-12 10:12:57 +01:00
* @param string $name
*
2018-08-08 09:52:53 +02:00
* @return string
*/
2018-09-23 07:02:02 +02:00
public static function get($name, $default = false, $decode = true)
2018-08-08 09:52:53 +02:00
{
2018-11-12 10:12:57 +01:00
// If not passed, get default value from config
2018-09-24 15:07:07 +02:00
if (func_num_args() == 1) {
$default = self::getDefault($name, $default);
}
2018-09-24 15:16:27 +02:00
if (isset(self::$cache[$name])) {
2018-11-28 07:05:13 +01:00
if (self::$cache[$name] == self::CACHE_DEFAULT_VALUE) {
return $default;
} else {
return self::$cache[$name];
}
2018-09-14 20:43:19 +02:00
}
2018-11-12 10:12:57 +01:00
$option = self::where('name', (string) $name)->first();
2018-08-08 09:52:53 +02:00
if ($option) {
2018-08-29 16:20:25 +02:00
if ($decode) {
2018-09-14 20:43:19 +02:00
$value = self::maybeUnserialize($option->value);
2018-08-29 16:20:25 +02:00
} else {
2018-09-14 20:43:19 +02:00
$value = $option->value;
2018-08-29 16:20:25 +02:00
}
2018-11-28 07:05:13 +01:00
self::$cache[$name] = $value;
2018-08-08 09:52:53 +02:00
} else {
2018-09-14 20:43:19 +02:00
$value = $default;
2018-11-28 07:05:13 +01:00
self::$cache[$name] = self::CACHE_DEFAULT_VALUE;
2018-08-08 09:52:53 +02:00
}
2018-09-14 20:43:19 +02:00
return $value;
2018-08-08 09:52:53 +02:00
}
2018-08-29 16:20:25 +02:00
2018-11-22 15:45:50 +01:00
public static function getDefault($option_name, $default = false)
2018-09-24 15:07:07 +02:00
{
$options = \Config::get('app.options');
if (isset($options[$option_name]) && isset($options[$option_name]['default'])) {
return $options[$option_name]['default'];
} else {
2018-11-27 09:04:56 +01:00
// Try to get default option value from module's config.
preg_match("/^([a-z_]+)\.(.*)/", $option_name, $m);
if (!empty($m[1]) && !empty($m[2])) {
$module_alias = $m[1];
$modle_option_name = $m[2];
$module_options = \Config::get($module_alias.'.options');
if (isset($module_options[$modle_option_name]) && isset($module_options[$modle_option_name]['default'])) {
return $module_options[$modle_option_name]['default'];
}
}
2018-09-24 15:07:07 +02:00
return $default;
}
}
2018-11-18 10:20:14 +01:00
public static function isDefaultSet($option_name)
{
$options = \Config::get('app.options');
2018-11-24 11:11:51 +01:00
return isset($options[$option_name]) && isset($options[$option_name]['default']);
2018-11-18 10:20:14 +01:00
}
2018-11-24 11:11:51 +01:00
2018-11-22 15:45:50 +01:00
/**
* Get multiple options.
2018-11-24 11:11:51 +01:00
*
* @param [type] $name [description]
* @param bool $default [description]
* @param bool $decode [description]
*
* @return [type] [description]
2018-11-22 15:45:50 +01:00
*/
public static function getOptions($options, $defaults = [], $decode = [])
{
$values = [];
// Check in cache first
// Return if we can get all options from cache
foreach ($options as $name) {
if (isset(self::$cache[$name])) {
2018-11-28 07:05:13 +01:00
if (self::$cache[$name] == self::CACHE_DEFAULT_VALUE) {
if (empty($defaults[$name])) {
$default = self::getDefault($name);
}
$values[$name] = $default;
} else {
$values[$name] = self::$cache[$name];
}
2018-11-22 15:45:50 +01:00
}
}
if (count($values) == count($options)) {
return $values;
} else {
2018-11-24 11:11:51 +01:00
$values = [];
2018-11-22 15:45:50 +01:00
}
$db_options = self::whereIn('name', $options)->get();
foreach ($options as $name) {
// If not passed, get default value from config
if (empty($defaults[$name])) {
$default = self::getDefault($name);
}
$db_option = $db_options->where('name', $name)->first();
if ($db_option) {
// todo: decode
if (1 || $decode) {
$value = self::maybeUnserialize($db_option->value);
} else {
$value = $db_option->value;
}
2018-11-28 07:05:13 +01:00
self::$cache[$name] = $value;
2018-11-22 15:45:50 +01:00
} else {
$value = $default;
2018-11-28 07:05:13 +01:00
self::$cache[$name] = self::CACHE_DEFAULT_VALUE;
2018-11-22 15:45:50 +01:00
}
$values[$name] = $value;
}
2018-11-24 11:11:51 +01:00
2018-11-22 15:45:50 +01:00
return $values;
}
2018-11-24 11:11:51 +01:00
2018-08-29 16:20:25 +02:00
public static function remove($name)
{
2018-11-12 10:12:57 +01:00
self::where('name', (string) $name)->delete();
2018-08-29 16:20:25 +02:00
}
/**
* Serialize data, if needed.
*/
2018-11-12 10:12:57 +01:00
public static function maybeSerialize($data)
{
2018-08-29 16:20:25 +02:00
if (is_array($data) || is_object($data)) {
2018-11-12 10:12:57 +01:00
return serialize($data);
2018-08-29 16:20:25 +02:00
}
2018-11-12 10:12:57 +01:00
2018-08-29 16:20:25 +02:00
return $data;
}
/**
* Unserialize data.
*/
public static function maybeUnserialize($original)
{
if (self::isSerialized($original)) {
try {
$original = unserialize($original);
} catch (\Exception $e) {
// Do nothing
}
2018-11-12 10:12:57 +01:00
2018-08-29 16:20:25 +02:00
return $original;
}
2018-11-12 10:12:57 +01:00
2018-08-29 16:20:25 +02:00
return $original;
}
/**
* Check value to find if it was serialized.
* Serialized data is always a string.
*/
2018-11-12 10:12:57 +01:00
public static function isSerialized($data, $strict = true)
{
2018-08-29 16:20:25 +02:00
// if it isn't a string, it isn't serialized.
2018-11-12 10:12:57 +01:00
if (!is_string($data)) {
2018-08-29 16:20:25 +02:00
return false;
}
$data = trim($data);
if ('N;' == $data) {
return true;
}
2018-11-12 10:12:57 +01:00
if (strlen($data) < 4) {
2018-08-29 16:20:25 +02:00
return false;
}
if (':' !== $data[1]) {
return false;
}
if ($strict) {
$lastc = substr($data, -1);
if (';' !== $lastc && '}' !== $lastc) {
return false;
}
} else {
$semicolon = strpos($data, ';');
2018-11-12 10:12:57 +01:00
$brace = strpos($data, '}');
2018-08-29 16:20:25 +02:00
// Either ; or } must exist.
2018-11-12 10:12:57 +01:00
if (false === $semicolon && false === $brace) {
2018-08-29 16:20:25 +02:00
return false;
2018-11-12 10:12:57 +01:00
}
2018-08-29 16:20:25 +02:00
// But neither must be in the first X characters.
2018-11-12 10:12:57 +01:00
if (false !== $semicolon && $semicolon < 3) {
2018-08-29 16:20:25 +02:00
return false;
2018-11-12 10:12:57 +01:00
}
if (false !== $brace && $brace < 4) {
2018-08-29 16:20:25 +02:00
return false;
2018-11-12 10:12:57 +01:00
}
2018-08-29 16:20:25 +02:00
}
$token = $data[0];
switch ($token) {
2018-11-12 10:12:57 +01:00
case 's':
2018-08-29 16:20:25 +02:00
if ($strict) {
2018-11-12 10:12:57 +01:00
if ('"' !== substr($data, -2, 1)) {
2018-08-29 16:20:25 +02:00
return false;
}
2018-11-12 10:12:57 +01:00
} elseif (false === strpos($data, '"')) {
2018-08-29 16:20:25 +02:00
return false;
}
// or else fall through
2018-11-12 10:12:57 +01:00
case 'a':
case 'O':
return (bool) preg_match("/^{$token}:[0-9]+:/s", $data);
case 'b':
case 'i':
case 'd':
2018-08-29 16:20:25 +02:00
$end = $strict ? '$' : '';
2018-11-12 10:12:57 +01:00
return (bool) preg_match("/^{$token}:[0-9.E-]+;$end/", $data);
2018-08-29 16:20:25 +02:00
}
2018-11-12 10:12:57 +01:00
2018-08-29 16:20:25 +02:00
return false;
}
/**
* Get company name.
*/
public static function getCompanyName()
{
return self::get('company_name', \Config::get('app.name'));
}
2018-08-08 09:52:53 +02:00
}