Laravel: Access EventServiceProvider listeners from PHP

So i came across a situation where i wanted to access the listeners array of \App\Providers\EventServiceProvider, and here’s what i did.

I didn’t just need to print the php artisan event:list, i needed to compare that list with some value i had. Apparently there was a way to access a provider using the app()->getProvider() command, and the code was:

app()->getProviders(EventServiceProvider::class);

That syntax will return an array of providers, you can either foreach that or make it into a collection and return the first value

# Example 1 
foreach(app()->getProviders(EventServiceProvider::class) as $_provider);

# Example 2
collect(app()->getProviders(EventServiceProvider::class))->first();

Both work however i didn’t need to loop through that, i only needed the first one, so i went for Example 2.

Now to access the listeners simply use the listens() method inside the provider;

 $Listeners = collect(app()->getProviders(EventServiceProvider::class))
->first() # The first item in collection
->listens() # Listens(), belongs to getProviders() method.

That’s it, i hope you find that useful.

Laravel: Store Settings in Database with Defaults in the config file

I personally prefer to have my site settings in the database to make them more customizable than to have them in the /config/settings.php file, Here’s how i do it:

assuming you want to have the file’s name settings.php inside the /config path, then whatever you put in there will be config(‘settings.some_option’);

<?php 
return [
    'title'       =>'App Title',
    'description' =>'App Description',
    'performance' => [
        'cache'   => 1,
        'lifetime'=> 120,
    ]
];

That’s how my config file will look like, intentionally i had performance key as array for demostration.

Now i want to store these inside the database, and for that i have to create a migration (with or without model), preferably with a controller to keep things clean.

Do the php artisan make:migration SiteSettings -mc, that will generate the migration + the model + the controller

The Migration then should have two columns (option, value) [name them whatever you want].

public function up()
    {
        Schema::create('site_settings', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('option');
            $table->string('value');
            $table->timestamps();
        });
    }

Now here come’s the actual work, we’re going to convert the config of /config/settings.php to flat array then store it as it is in the database, for that i used a snippet from stackoverflow.

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

That method will flatten the config and makes it compatible with how you usually retrieve keys from Laravel’s config() helper. Let’s say you want to retrieve the title from the config, we usually write it like that: config(‘settings.title’); and for something that is under performance we write it like that: config(‘settings.performance.cache’); but in order to make all this tree as one flat tree you need to use that function prefixKey (). that will make the config array looks like this

array[
'title'=>xxx,
'description=>xxx,
'performance.cache'=>xxx,
'performance.lifetime=>xxx,
];

And that’s how you actually write the config syntax to retrieve something: config(‘performance.lifetime’) and we want to keep it like that.

Now that we made the settings configs flat we can insert them in the database, but before we do and make things too complex let’s do it from the controller through a method we call it init(), and in there we check and set the configs.

    /**
     * Initialize the config
     *
     * @throws \Exception
     */
    public static function init(): void
    {

        # Just in case config('settings') doesn't exist
        if (is_array(config('settings'))) {

            # Create the default setting option if the key doesn't exist in database
            foreach (Helpers::prefixKey('', config('settings')) as $_key => $_value) {
                SiteSettings::firstOrCreate(['option' => $_key], ['value' => $_value]);
            }

            # Retrieve the settings from database
            $Settings = SiteSettings::all()->pluck('value', 'option')->toArray();

            # Update the config helper to retrieve the database values
            # not the default values
            foreach ($Settings as $_option => $_value) {
                config(['settings.' . $_option => $_value]);
            }

        } else {
            throw new \Exception('The config `settings` does not exist.');
        }
        
    }
  • First of all i loaded all the config(‘settings’) from the actual file located in /config/settings.php and made it flat array.
  • Insert SiteSettings DB row using the firstOrCreate because we don’t want to have two identical rows of the same settings. and we don’t want to use the updateOrCreate method because this row will be inserted from the default /config/settings.php key and not updated all the time, that’s how the file there becomes only for defaults and nothing more then it will be inserted in the database for future user updates.
  • Then we retrieve the Settings, make them as array[value=>option], that will make it well formatted to match the config default syntax.
  • Then we set the config(‘settings.*’) to use the database instead of the actual file.

Now for tests, try to to add a line in the actual config/settings.php, for example : ‘test’=>1 and run the init() method, That should add a row of that option in the database, now try to change the value of the test in the /config/settings.php file and try to output it using config(‘settings.test’) it will not show the updated value, but the database value. Try to change the value in the database and that should return the updated value. try to remove the row from the database and refresh, that should re-insert a db row of that missing value with the value set in /config/settings.php.

Now to make this check happens everytime without manually running the init() method, you can include that in the AppServiceProvider using : \App\Http\Controller\SiteSettingsController::init(); or whatever way you prefer.

That’s is, Hope you found this useful.

Unix/Linux dd Usage Examples

List disks in Linux

fdisk -l

After entering fdisk -l you would need to identify your disk(s)

dd how to clone disk to another disk

dd if=/dev/sdc of=Desktop/usb.iso bs=1M conv=noerror,sync

when using dd you have to make sure that you do not mix up the if (input file) and of (output file). “If” will always be the disk that you are copying and “of” is the location or the disk you are copying to

dd how to clone disk to an image

dd if=/dev/sdc of=/dev/sde bs=1M conv=noerror,sync

dd how to show progress

watch -n60 'sudo kill -USR1 $(pgrep ^dd)'

To get the progress of dd we will be using the

  • kill – a built-in command used to terminate processes manually
  • watch – execute a program periodically
    • -n60 (the number 60 in the command above is the seconds that it will refresh, change that to the desired refresh rate )

How to disable /cpanel /whm /webmail links from WHM/cPanel

Some of us look to disable all whm specific urls from our domains, things like cpanel, whm, webmail, webdisk, cpcalendars, cpcontacts.

Disable Automatically adding those urls to your domains

  • Login to your WHM (port 2087)
  • Find Tweak Settings
  • Find Service Subdomains (It’s in the Domains tab, but you can use the find field there, just type in ‘service subdomains’
  • Disable that.
  • You will most probably need to clear the old dns entries which contain these urls from WHM > Edit DNS Zone -> Select your domains, click edit. and clear the fields where it has anything you want to remove. However if you don’t have any custom dns entries you can simply WHM -> Reset a DNS Zone (be cautious there since this will reset the dns zone to defaults, so if you have¬† anything custom there it will be cleared.)

Remove cPanel Specific URL for a specific site from cPanel

  • Login to your cPanel page (usually port 2083)
  • Find Zone Editor.
  • Click Manage next to the domain you want to edit.
  • You will find those /cpanel /webmail etc… urls there, Remove them.

 

How to change PHP version in WHM/cPanel

Change your PHP Version in WHM

  • Login to your WHM using the default port 2087.
  • On the left sidebar locate MultiPHP Manager.
  • You will find a tab that says System PHP Version, under that you will find the selected php version for the whole system.
  • Press the Edit button next to it and choose the PHP version you want.
  • In case you cannot find the PHP version you’re looking for, then you will probably need to install it in the EasyApache page first.
  • In case you want to change the PHP version for a specific site, then you will need to scroll down a little and you will find a table which contains all the domains you have on that server. One of the columns contain a PHP Version list, choose one.

How to Change PHP Version from cPanel

  • Login to you cPanel page (usually at port 2083 or example.com/cpanel).
  • If you are allowed to change the PHP Version from your cPanel then you will find MultiPHP Manager, click that. But if you cannot find that Feature then you will need to contact your server’s administrators to change it for you and to enable that feature.
  • You will find a table with the domains you have on that account in case you have more than one domain/subdomain there, select the ones you want to change.
  • On the top you will find a dropdown list which says PHP Version. Choose one then click Apply.

How to install PHP Imagick Extension on Centos7 with WHM/cPanel and EasyApache4

Imagick is a native php extension to create and modify images using the ImageMagick API.

ImageMagick is a software suite to create, edit, and compose bitmap images. It can read, convert and write images in a variety of formats (over 100) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF.

ImageMagick Studio LLC is a non-profit organization dedicated to making software imaging solutions freely available.

Continue reading

How to Send Emails with PHP

In order to send emails with PHP you need to have the `mail`  function ready.

<?php
$to      = 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
    'Reply-To: webmaster@example.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);
?>