Eloquent Model Traits With Casts

As a follow up to the previous entry, you can also include a function to return a casts array for a trait/concern that your eloquent model is using.

trait HasUuid  
{
    public function getHasUuidCasts()
    {
        if(config('uuid.binary_format')) {
            return ['uuid' => 'uuid'];
        }

        return [];
    }

    //
}

Here is the trait that will enable this functionality on your eloquent models.

trait HasTraitsWithCasts  
{
    /**
     * Get the casts array.
     *
     * @return array
     */
    public function getCasts()
    {
        $class = static::class;

        foreach (class_uses_recursive($class) as $trait) {
            if (method_exists($class, $method = 'get'.class_basename($trait).'Casts')) {
                $this->casts = array_unique(array_merge($this->casts, $this->{$method}()));
            }
        }

        return parent::getCasts();
    }
}

Eloquent Model Traits With Dates

In the same way that we can use a boot{Trait}() method in a trait/concern for an eloquent model, it would be nice to be able to register specific date fields in a trait/concern (i.e. Publishable with a published_at timestamp column).

trait Publishable  
{
    public function getPublishableDates()
    {
        return ['published_at'];
    }

    // 
}

Here is the trait that will enable this functionality on your eloquent models.

trait HasTraitsWithDates  
{
    /**
     * Get the attributes that should be converted to dates.
     *
     * @return array
     */
    public function getDates()
    {
        $class = static::class;

        foreach (class_uses_recursive($class) as $trait) {
            if (method_exists($class, $method = 'get'.class_basename($trait).'Dates')) {
                $this->dates = array_unique(array_merge($this->dates, $this->{$method}()));
            }
        }

        return parent::getDates();
    }
}

The beautiful part is that this feature is additive in nature. Both default fields, created_at and updated_at, as well as those defined in the $dates property on a model are still included with any trait based date fields when getDates() is called.

Find Hard Drive Details On Server

Here are two commands that can help when dealing with physical Linux servers.

To get detailed information directly from the hard drive:

$ hdparm -I /dev/sda

To get a list of all the serial numbers for your hard drives:

$ for i in a b c d e f g h; do echo -n "/dev/sd$i: "; hdparm -I /dev/sd$i | awk '/Serial Number/ {print $3}'; done

Nginx Configuration For Symlinked PHP Releases

If you want to use a deployment tool like Capistrano or Laravel Envoy with symbolic linked release directories, instead of mapping your script to the path of the symlink with $document_root:

location ~ \.php$ {  
    # ...
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    # ...
}

You should instead reference the $realpath_root variable as this allows for all new requests to immediately be mapped to the new release on deployment.

location ~ \.php$ {  
    # ...
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    fastcgi_param DOCUMENT_ROOT $realpath_root;
    # ...
}

Find Total Size Of Files On Server

As a continuation of my last post, here is a command if you want to find the total combined size (in kilobytes) of a set of folders or files listed in a text file named file-list.txt.

$ find -print -maxdepth 1 | grep -Fxf file-list.txt | xargs du -k | awk '{total=total+$1} END {print total}'

Find Folders On Server To Eliminate

If you need to narrow down a list of folders in a directory to the set that you need to either archive or cleanup from a linux server, here's a quick command.

First, add the list of folders that you know you want to keep to a file named file-list.txt. All other folders will be printed from this command.

$ ls -hal | grep ^d | grep -Fxvf file-list.txt

What the flags mean:

  • -mtime +7 More than seven days old

  • -maxdepth 1 Only search the current directory, not recursively

  • -F, --fixed-strings Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.

  • -x, --line-regexp Select only those matches that exactly match the whole line.

  • -v, --invert-match Invert the sense of matching, to select non-matching lines.

  • -f FILE, --file=FILE Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore matches nothing.

If you want get a count to make sure the all folders listed in file-list.txt exist in the current directory, here's another command.

$ ls -hal | grep ^d | grep -Fxf file-list.txt | wc -l