Laravel Configuration update - laravel

I am working on Laravel. I have questions about update / add configuration dynamically. Let me tell you my question.
I am updating / add the global configuration of my project using the file_put_content in config file. I have another way, save configuration into the database and pull that configuration at the time of login to the system.
Which way is better to use and why?

one way is maintain seprate table for config data if your data is static means nothing have to change in that data. and then create provider to get your data and bind that data at run time
public function boot()
{
if (Schema::hasTable('roles')) {
$roles = Role::pluck('name', 'id')->all();
$data = collect($roles)->mapWithKeys(function ($item, $index) {
return [str_slug($item, '_') => $index];
})->all();
config(['configfilename.configkey' => $data]);
}
}
Like this you can get your config data at run time

Related

Impementing global app settings for Laravel API?

I wish to implement a few global app settings, e.g. App name, first day of the week, and other feature flags. The end goal is to have these be fetched and edited by administrators through the API.
What might be the most convenient way of doing this? I've experimented with using a Settings model to store key-value pairs, but this doesn't make sense to me since the desired settings should be hard coded and won't change, and seeding the Settings table doesn't sound ideal. Thanks in advance!
You can access App name from Laravel provided config function.
$appName = config('app.name');
// This value is retrieved from .env file of APP_NAME=
If you have to store multiple values related with the week, you can create a new config file week.php
//config/week.php
return [
...
'first_day_of_the_week' => 0
];
In order to retrieve the first_day_of_the_week, you can use the same function config
$firstDayOfTheWeek = config('week.first_day_of_the_week')
Similar to other essential flags, you can create a new config file.
You can later cache your config variables using the following command.
php artisan config:cache
You can also create a Helper class inside any preferred location inside the laravel project. I keep my helper class inside App\Helpers.
<?php
namespace App\Helpers;
use Carbon\Carbon;
class DateHelpers
{
public const DATE_RANGE_SEPARATOR = ' to ';
public static function getTodayFormat($format = 'Y-m-d')
{
$today = Carbon::now();
$todayDate = Carbon::parse($today->format($format));
return $todayDate;
}
....
}
If you need to retrieve the method value in the Laravel project, you can access by
$getTodayDateFormat = App\Helpers\DateHelpers::getTodayFormat();
EDIT 1:
Based on the question description. You need to create one row in the settings table.
//create_settings_table.php Migration File
public function up()
{
// Create table for storing roles
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('app_name')->default("My App Name");
$table->unsignedInteger('first_day_of_the_week')->default(1);
....
$table->timestamps();
});
}
You only need one row of the settings table to retrieve/update the default value.
//Retrieving the first day
$first_day_of_the_week = App\Setting::first()->first_day_of_the_week;
//Updating the first day
...
$first_day_of_the_week = request('first_day_of_the_week');
App\Setting::first()->update([
'first_day_of_the_week' => $first_day_of_the_week
]);

Laravel DatabaseTransactions for PHPunit have no effect

Writing tests for an existing API, there are many cases where the database has been modified. What I have been doing is something as follows:
public function testPut()
{
//setup
/*Copy an existing record and take its data as an array.
* the function being tested will take an array of data
* and create a new record. Using existing data guarantees
* the data is valid.
*/
$customerObj = Customer::getInstance(); //regular instantiation disabled in this api
$cust = ArCust::first()->toArray();
$oldNum = $cust['CUST_NO'];
unset($cust['CUST_NO']);
$custNo = rand(1, 9999999999999);
//test
/*put() creates a new customer record in the database
and returns the object.
*/
$this->assertInternalType('object', $customerObj->put($custNo, $cust));
//cleanup
/*manually remove the newly created record.
*/
ArCust::whereNam($cust['NAM'])->whereNotIn('CUST_NO', [$oldNum])->delete();
}
I am now running into instances where the API creates or updates many tables based on foreign keys. It would take far too much time to go through and manually reset each table.
The DatabaseTransaction trait provided by Laravel is supposed to take care of resetting everything for you. However, when I use it, I still find the test-created records in the database.
Here is how I have used it:
class CustomerTest extends TestCase
{
use DatabaseTransactions;
public function testPut()
{
//setup
$customerObj = Customer::getInstance();
$cust = ArCust::first()->toArray();
$oldNum = $cust['CUST_NO'];
unset($cust['CUST_NO']);
$custNo = rand(1, 9999999999999);
//test
$this->assertInternalType('object', $customerObj->put($custNo, $cust));
}
}
Am I using this incorrectly? Getting DatabaseTransactions to work correctly will save an incredible amount of time, as well as make the testes more readable to other people.
The issue was that we had multiple database connections defined in config > database.
In the database.php conf file, I changed the default connection to the correct database using its name as defined in the setup:
$connection = 'counterpoint';
and DatabaseTransactions now works.
This next step to this solution is to direct the connection of each test to the appropriate database rather than change the global connection.

Laravel: two models in one controller method

Let me explain about my problem.
I am currently using Laravel 5.0. Here is my structure
Table: bgts, Model: Bgt, Controller: BgtController
Table: bgthistories, Model: BgtHistory
Now I want to do these:
Everytimes creating new item into bgts table, I want to make a copy and insert into bgthistories table. Then, everytimes that record is updated, i'll copy one more version, still insert into bgthistories.
Here is store() method.
public function store(Request $request) {
$bgt = new Bgt();
$history = $this->coppy($bgt);
$uploader = new UploadController('/data/uploads/bgt');
$bgt->name = $request['name'];
$bgt->avatar = $uploader->avatar($request);
$bgt->attachments($uploader->attachments($request));
//dd($bgt);
$bgt->save();
$history->save();
return redirect('bgt');
}
And this is the coping:
public function coppy($bgt) {
$array = $this->$bgt->toArray();
$version = new BgtHistory();
foreach($array as $key => $value) {
$version->$key = $value;
}
return $version;
}
I create migration tables already. Everything is ready. But, when I call
$bgt->save();
$history->save();
It did not work. If I remove $history->save();, it create new record ok. I think the save() method that built-in in Model provided by Laravel is problem. Can anyone tell me how to solve this.
I tried to build the raw query then executed it by DB:statement but it did not work too. Every try to execute anything with DB is failing.
Please research before re-inventing the wheel.
(Same stuff different sites in case one is down)
http://packalyst.com/packages/package/mpociot/versionable
https://packagist.org/packages/mpociot/versionable
https://github.com/mpociot/versionable
Cheers and good luck ;)

Laravel Event Listening

I have an issue similar to this post :
Laravel - last login date and time timestamp
In short, my purpose and question is :
I have a "logrecords" table in my database.
My event listeners in global.php are just working on default "users" table.
I want my event listeners are able to insert data on my "logrecords" table.
How can i do that :
Should i configure my database tables using which are using eloquent ?
Or should i change something in global.php ?
Thanks for your support.
--------------------Update--------------------
I realized that in my auth.php file, default authentication model has been set as :
'model' => 'User'
But i want to listen and work with both User and Logrecord model.So that when i try to listen events in my global.php file, laravel is automatically trying to work with User model. So that i had to configure my event listeners like that :
Part of my global.php file :
//First Example
Event::listen('auth.login', function($user)
{
$userLogRecord = Logrecord::firstOrCreate(array('user_id' => $user->id));
$userLogRecord->user_id = $user->id;
$userLogRecord->login_last_at = date('Y-m-d H:i:s');
$userLogRecord->save();
});
//Second Example
Event::listen('auth.logout', function($user)
{
$userLogRecord = Logrecord::firstOrCreate(array('user_id' => $user->id));
$userLogRecord->user_id = $user->id;
$userLogRecord->logout_last_at = date('Y-m-d H:i:s');
$userLogRecord->save();
});
It is working for now, but I am thinking that it's not a good idea to edit my listeners like that. My purpose is to listen and do some process with both User and Logrecord models. It serves my purpose right now but i feel like i have to improve.
Any ideas ?
#DemonDrake,
If I understand correctly you simply want to add data to a "log" table?
In the most simple form, the answer is "Yes you would use the eloquent ORM for that
class Log extends Eloquent {
protected $table = 'log';
}
or perhaps query builder even.
There are a number of ways this is possible. I personally suggest you check out https://laracasts.com/lessons

Codeigniter dynamic configuration

How do I let users set the database configuration for a new CI install?
My intention is to have a form that allows them to enter the data then either generate a new config file or to set the options in the database.php file.
Is this possible?
Let's say you want to create a database config file. Here's how I do it:
Create a "dummy" config file by copying a real one, and use values that look something like this:
$db['default']['hostname'] = '__HOSTNAME__';
$db['default']['username'] = '__USERNAME__';
$db['default']['password'] = '__PASSWORD__';
$db['default']['database'] = '__DATABASE__';
Have the user complete the installation form, and verify all the data by testing a database connection. Next, use file_get_contents() to grab the content of the "dummy" config file, use a simple str_replace() to rewrite the values with the ones the user provided, then write the new content to your real config file overwriting the entire thing.
Here's part of the actual code I'm using for creating the file, just to get an idea. Bear in mind that I'm running this on a totally separate CI installation (the "installer"), and this is not a copy/paste example:
// Write the database configuration file
$config = array(
'hostname',
'username',
'password',
'database',
);
$data = file_get_contents(APPPATH.'config/dummy_database.php');
$file = '../private/config/database.php';
// Oops! Just caught this after posting: str_replace() accepts arrays.
// TODO: Use the array method instead of a loop!
foreach ($config as $item)
{
$data = str_replace('____'.strtoupper($item).'____', mysql_escape_string($this->data[$item]), $data);
}
if (write_file($file, $data))
{
$this->message('Database configuration file was written!', 'success');
#chmod($file, 0644);
{
if (is_really_writable($file))
{
$this->message('The database configuration is still writable, make sure to set permissions to <code>0644</code>!', 'notice');
}
}
}
else
{
$this->message('Could not write the database configuration file!');
redirect('step_4');
}
This retains the original copy of the "dummy" config file. You could use the same logic for editing, just read the current config values for anything the user has not changed and do the same string replacement technique.

Resources