Skip to content

Commit

Permalink
- New features added
Browse files Browse the repository at this point in the history
  • Loading branch information
Mehmet Faruk Demirkoparan committed Feb 3, 2025
1 parent 269ab1b commit 0b99063
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 135 deletions.
30 changes: 11 additions & 19 deletions config/aconfig.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
<?php

return [
/* The Config database table name */
'table' => 'aconfig',
/* * The database table where dynamic configurations will be stored */
'table' => 'aconfig',

/*
* The key that defines which config file should be loaded dynamically
* and store into the database
* Add that key to any config file to make it dynamic.
*/
'dynamic_key' => 'dynamics',

/*
* they key which will have the defaults of a config key
* example: config('defaults.app.name'); This is added on runtime.
*/
'defaults_key' => 'defaults',
'keys' => [
/*
* 'app.name' => 'Laravel',
* 'app.env' => 'production',
*/
],

/*
* Delete orphan keys
* if set to true and delete a key from the actual config file,
* that key will be deleted from database.
*/
/* * Automatic deletion of records that exist in the database but are not defined * in the aconfig.php file (orphan records). */
'auto_delete_orphan_keys' => true,
];
];
2 changes: 1 addition & 1 deletion database/migrations/create_aconfig_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CreateAConfigTable extends Migration
Schema::create(config('aconfig.table'), function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('key', 500)->unique();
$table->json('value')->nullable();
$table->text('value')->nullable();
$table->timestamps();
});
}
Expand Down
55 changes: 14 additions & 41 deletions src/AConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,44 @@

use Illuminate\Database\Eloquent\Model;

/**
* Class DynamicConfig
*
* @property mixed value
* @package EmadHa\DynamicConfig
*/
class AConfig extends Model
{
/**
* @var array
*/
protected $guarded = ['id'];


protected $casts = [
'value' => 'array',
];

];

/**
* DynamicConfig constructor.
*
* @param array $attributes
*/
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->setTable(config('aconfig.table'));
}

/**
* Update the current key value
*
* @param $value
*
* @return bool
*/
public function setTo($value)
{
return $this->update(['value' => $value]);
}

/**
* Get the default value of the specified key
*
* @return \Illuminate\Config\Repository|mixed
*/
public function default()
{
return config(
config('aconfig.defaults_key') . '.' . $this->key
);
$defaults = config('aconfig.defaults', []);
return $defaults[$this->key] ?? null;
}

/**
* Revert the current key to it's original value
* from the actual config file
*
* @return mixed
*/
public function revert()
{
return config($this->key)->setTo(
config(config('aconfig.defaults_key') . '.' . $this->key)
);
$defaultValue = $this->default();
return $this->setTo($defaultValue);
}

}
public function __toString()
{
if (is_scalar($this->value)) {
return (string) $this->value;
}

return json_encode($this->value);
}
}
102 changes: 28 additions & 74 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,29 @@

namespace AuroraWebSoftware\AConfig;

use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use mysql_xdevapi\Exception;

class ServiceProvider extends \Illuminate\Support\ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{

}

/**
* Bootstrap services.
*
* @return void
* @throws \Exception
*/
public function boot()
{
if ($this->app->runningInConsole()) {
if (!class_exists('CreateAConfigTable')) {
$timestamp = date('Y_m_d_His', time());
$this->publishes([
__DIR__ . '/../database/migrations/create_aconfig_table.php.stub' => database_path('migrations/' . $timestamp . '_create_aconfig_table.php'),
__DIR__.'/../database/migrations/create_aconfig_table.php.stub'
=> database_path('migrations/'.$timestamp.'_create_aconfig_table.php'),
], 'migrations');
}

$this->publishes([
__DIR__ . '/../config/aconfig.php' => config_path('aconfig.php'),
__DIR__.'/../config/aconfig.php' => config_path('aconfig.php'),
], 'config');
}

Expand All @@ -46,86 +33,53 @@ public function boot()

private function initConfig()
{

# Check if the table exists
if (!Schema::hasTable(config('aconfig.table'))) {

# Don't crash, Log the error instead
Log::error(sprintf(
get_class($this) . " is missing the the dynamic config table [`%s`]. you might need to do `php artisan vendor:publish` && `php artisan migrate`",
config('aconfig.table'))
);

return false;
"%s: Dinamik konfigürasyon tablosu `%s` bulunamadı. Lütfen migrasyonları çalıştırın.",
__CLASS__,
config('aconfig.table')
));
return;
}

# Create a new collection of what's dynamic
$DefaultConfig = collect([]);

# Return the config entries containing ['dynamic'=>true] key
collect(config()->all())->each(function ($value, $key) use (&$DefaultConfig) {

# Check if the current config key has dynamic key set to it, and it's true
if (array_key_exists(config('aconfig.dynamic_key'), $value)
&& $value[config('aconfig.dynamic_key')] == true) {

# unset that dynamic value
unset($value[config('aconfig.dynamic_key')]);

# Add that to the DynamicConfig collection
$DefaultConfig->put($key, $value);
}

});

# Keep the defaults for reference
config([config('aconfig.defaults_key') => $DefaultConfig]);
$configKeys = config('aconfig.keys', []);

# Flatten the config table data
$prefixedKeys = $this->prefixKey(null, $DefaultConfig->all());
$flattened = $this->prefixKey(null, $configKeys);

# Insert the flattened data into database
foreach ($prefixedKeys as $_key => $_value) {

# Get the row from database if it exists,
# If not, add it using the value from the actual config file.
AConfig::firstOrCreate(['key' => $_key], ['value' => $_value]);
config(['aconfig.defaults' => $flattened]);

foreach ($flattened as $_key => $_value) {
AConfig::firstOrCreate(
['key' => $_key],
['value' => $_value]
);
}

# Build the Config array
$AConfig = AConfig::all();
$dbConfigs = AConfig::all();

# Check if auto deleting orphan keys is enabled
# and delete those if they don't exists in the actual config file
if (config('aconfig.auto_delete_orphan_keys') == true) {

# Check for orphan keys
$orphanKeys = array_diff_assoc($AConfig->pluck('value', 'key')->toArray(), $prefixedKeys);

# Delete orphan keys
AConfig::whereIn('key', array_keys($orphanKeys))->delete();
if (config('aconfig.auto_delete_orphan_keys') === true) {
$dbKeys = $dbConfigs->pluck('value', 'key')->toArray();
$orphanKeys = array_diff_key($dbKeys, $flattened);

if (!empty($orphanKeys)) {
AConfig::whereIn('key', array_keys($orphanKeys))->delete();
}
}

# Store these config into the config() helper, but as model objects
# Thus making Model's method accessible from here
# example: config('app.name')->revert().
# Available methods are `revert`, `default` and `setTo($value)`
$AConfig->map(function ($config) use ($DefaultConfig) {
config([$config->key => $config]);
$dbConfigs->each(function ($configModel) {
config([$configModel->key => $configModel]);
});

}

public function prefixKey($prefix, $array)
{
$result = [];
foreach ($array as $key => $value) {
$newPrefix = $prefix ? $prefix.$key : $key;
if (is_array($value)) {
$result = array_merge($result, self::prefixKey($prefix . $key . '.', $value));
$result = array_merge($result, $this->prefixKey($newPrefix.'.', $value));
} else {
$result[$prefix . $key] = $value;
$result[$newPrefix] = $value;
}
}
return $result;
Expand Down

0 comments on commit 0b99063

Please sign in to comment.