1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-11 05:32:39 +01:00
invoiceninja/app/Utils/Traits/SettingsSaver.php

196 lines
4.6 KiB
PHP
Raw Normal View History

<?php
/**
* Invoice Ninja (https://invoiceninja.com)
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2019. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\Utils\Traits;
use App\DataMapper\CompanySettings;
/**
2019-10-10 04:24:19 +02:00
* Class SettingsSaver
* @package App\Utils\Traits
*/
2019-10-10 04:24:19 +02:00
trait SettingsSaver
{
2019-10-10 04:24:19 +02:00
/**
* Saves a setting object
*
* Works for groups|clients|companies
* @param array $settings The request input settings array
* @param object $entity The entity which the settings belongs to
* @return void
*/
public function saveSettings($settings, $entity)
2019-10-09 07:57:32 +02:00
{
2019-10-09 14:21:21 +02:00
2019-10-09 07:57:32 +02:00
if(!$settings)
return;
2019-10-09 14:21:21 +02:00
2019-10-10 04:24:19 +02:00
$entity_settings = $this->settings;
//unset protected properties.
foreach(CompanySettings::$protected_fields as $field)
unset($settings[$field]);
2019-10-10 03:55:21 +02:00
$settings = $this->checkSettingType($settings);
2019-10-09 14:21:21 +02:00
//iterate through set properties with new values;
foreach($settings as $key => $value)
2019-10-10 04:24:19 +02:00
$entity_settings->{$key} = $value;
2019-10-10 04:24:19 +02:00
$entity->settings = $entity_settings;
$entity->save();
}
2019-10-10 04:24:19 +02:00
/**
* Used for custom validation of inbound
* settings request.
*
* Returns an array of errors, or boolean TRUE
* on successful validation
* @param array $settings The request() settings array
* @return array|bool Array on failure, boolean TRUE on success
*/
2019-10-10 03:01:38 +02:00
public function validateSettings($settings)
{
$settings = (object)$settings;
$casts = CompanySettings::$casts;
ksort($casts);
2019-10-10 03:01:38 +02:00
foreach ($casts as $key => $value){
2019-10-10 03:01:38 +02:00
/*Separate loop if it is a _id field which is an integer cast as a string*/
if(substr($key, -3) == '_id' || substr($key, -14) == 'number_counter'){
$value = "integer";
if(!property_exists($settings, $key)){
continue;
}
else if(!$this->checkAttribute($value, $settings->{$key})){
2019-10-10 03:01:38 +02:00
return [$key, $value];
}
continue;
}
/* Handles unset settings or blank strings */
if(!property_exists($settings, $key) || is_null($settings->{$key}) || !isset($settings->{$key}) || $settings->{$key} == '')
2019-10-10 03:01:38 +02:00
continue;
2019-10-10 03:01:38 +02:00
/*Catch all filter */
if(!$this->checkAttribute($value, $settings->{$key}))
return [$key, $value];
2019-10-10 03:01:38 +02:00
}
return true;
}
2019-10-09 14:21:21 +02:00
2019-10-10 04:24:19 +02:00
/**
* Checks the settings object for
* correct property types.
*
* The method will drop invalid types from
* the object and will also settype() the property
* so that it can be saved cleanly
*
* @param array $settings The settings request() array
* @return object stdClass object
*/
private function checkSettingType($settings) : \stdClass
2019-10-09 14:21:21 +02:00
{
$settings = (object)$settings;
2019-10-10 03:55:21 +02:00
$casts = CompanySettings::$casts;
2019-10-09 14:21:21 +02:00
foreach ($casts as $key => $value){
/*Separate loop if it is a _id field which is an integer cast as a string*/
2019-10-10 03:01:38 +02:00
if(substr($key, -3) == '_id' || substr($key, -14) == 'number_counter'){
2019-10-09 14:21:21 +02:00
$value = "integer";
if(!property_exists($settings, $key)){
continue;
}
elseif($this->checkAttribute($value, $settings->{$key})){
if(substr($key, -3) == '_id')
settype($settings->{$key}, 'string');
else
settype($settings->{$key}, $value);
2019-10-09 14:21:21 +02:00
}
else {
unset($settings->{$key});
2019-10-09 14:21:21 +02:00
}
2019-10-09 14:21:21 +02:00
continue;
}
/* Handles unset settings or blank strings */
if(!property_exists($settings, $key) || is_null($settings->{$key}) || !isset($settings->{$key}) || $settings->{$key} == ''){
2019-10-09 14:21:21 +02:00
continue;
}
/*Catch all filter */
2019-10-09 14:21:21 +02:00
if($this->checkAttribute($value, $settings->{$key})){
if($value == 'string' && is_null($settings->{$key}))
$settings->{$key} = '';
2019-10-10 01:15:35 +02:00
settype($settings->{$key}, $value);
2019-10-09 14:21:21 +02:00
}
else {
unset($settings->{$key});
2019-10-09 14:21:21 +02:00
}
}
return $settings;
2019-10-09 14:21:21 +02:00
}
2019-10-10 04:24:19 +02:00
/**
* Type checks a object property.
* @param string $key The type
* @param string $value The object property
* @return bool TRUE if the property is the expected type
*/
private function checkAttribute($key, $value) :bool
2019-10-09 14:21:21 +02:00
{
switch ($key)
{
case 'int':
case 'integer':
return ctype_digit(strval($value));
2019-10-09 14:21:21 +02:00
case 'real':
case 'float':
case 'double':
2019-10-10 00:20:38 +02:00
return is_float($value) || is_numeric(strval($value));
2019-10-09 14:21:21 +02:00
case 'string':
return method_exists($value, '__toString' ) || is_null($value) || is_string($value);
case 'bool':
case 'boolean':
2019-10-10 01:15:35 +02:00
return is_bool($value) || (int) filter_var($value, FILTER_VALIDATE_BOOLEAN);
2019-10-09 14:21:21 +02:00
case 'object':
return is_object($value);
case 'array':
return is_array($value);
case 'json':
json_decode($string);
return (json_last_error() == JSON_ERROR_NONE);
default:
2019-10-10 04:24:19 +02:00
return false;
2019-10-09 14:21:21 +02:00
}
}
}