Laravel Sentry and UUID

Posted: 2014-07-02 17:12:58

Update October 10 10:07

Have hit a few issues with this model but still working okay.

To start this trait does some of the work to manage incoming POST data.

<?php namespace BehatEditor\Helpers;

use Rhumsaa\Uuid\Uuid;

trait UuidHelper {

    protected $uuid;
    protected $saved;

    public function getUuid()
    {
        return $this->uuid;
    }

    public function setUuid($uuid = null)
    {
        if($uuid === null)
        {
            $uuid = $this->generateNewId()->toString();
        }
        $this->uuid = $uuid;
        return $this;
    }

    /**
     * Get a new version 4 (random) UUID.
     *
     * @return \Rhumsaa\Uuid\Uuid
     */
    public function generateNewId()
    {
        return Uuid::uuid4();
    }

    protected function setModelParamsIdWithUuid($params)
    {
        if(!isset($params['id'])) {
            $this->setUuid($this->generateNewId()->toString());
            $params['id'] = $this->getUuid();
        }
        $this->uuid = $params['id'];
        return $params;
    }

    public function dealWithUsingUuidNotReturningIdFromCreate($model)
    {
        $this->saved = $model->find($this->uuid);
    }
} 

Here is an example of me using it.


/** * Incoming Post request from the Controller to a Service and finally to this Repository Class. */ public function createNewBatch($batch) { try { $this->post = $batch; //Incoming post data $this->setRelatedObjectsFromPost(); //I deal with some of the related data or incoming data before hand $setUuid = $this->setModelParamsIdWithUuid($batch); //this is the traits setting the UUID on the incoming POST data. $this->batch->create($setUuid); //Finally I create using the auto-generated UUID OR the id/uuid that came in via the post /** * Again the trait takes care of this ONE issue I can not get around is returning the results of Create with the an ID * It works and saves the data but the ID is missing. Though looking at Eloquent this most likely is because I need to be using save. * Any ways I load it back up again for further processing. * Also some of this work started when I was using Eloquent outside of Laravel so it may need to be refactored since we are back in Laravel. */ $this->dealWithUsingUuidNotReturningIdFromCreate($this->batch); $this->extractAndSyncRelatedObjects(); //This is the further processing I do not really related to this post return $this->uuid; //This was set in the Trait see the trait class for this uuid field. } catch (\Exception $e) { throw new \Exception('The batch could not be created ' . $e->getMessage()); } }

Also note the model class needs this property set

public $incrementing = false;

END UPDATES


I needed to have UUID setup for users since we will be syncing users from site to site. I also wanted to use sentry as a starting point for user auth, roles and groups.

Using this starter package for a demo https://github.com/alnutile/L4withSentry/tree/uuid which is a fork of https://github.com/rydurham/L4withSentry

A lot of this comes from http://garrettstjohn.com/entry/using-uuids-laravel-eloquent-orm/

The repo will show the changes

Add the method and class to the base controller

This way we can call to it from other controllers as needed

Update the UserController

There are lots of changes in here to replace is_numeric wtih $this->isValue($id) to check the uuid

Update the seeder

This will setup our seed data to work as well

Update the user model

We call the boot method to generate a uuid if there is none being passed in.

Update October 10 10:18

This below setup for the model has not worked which is why I have the update at the start of this article

End update

/**
     * The "booting" method of the model.
     *
     * @return void
     */
    public static function boot()
    {
        parent::boot();

        /**
         * Attach to the 'creating' Model Event to provide a UUID
         * for the `id` field (provided by $model->getKeyName())
         */
        static::creating(function ($model) {
            $model->id = (string)$model->generateNewId();
        });
    }

and then generateNewId method down below

   /**
     * Get a new version 4 (random) UUID.
     *
     * @return \Rhumsaa\Uuid\Uuid
     */
    public function generateNewId()
    {
        return Uuid::uuid4();
    }

Update Route file

Replace the regular expressions to allow uuid

+Route::get('users/{id}/reset/{code}', 'UserController@reset')->where('id', '[a-z0-9\-]+');
  Route::get('users/{id}/suspend', array('as' => 'suspendUserForm', function($id)
  {
    return View::make('users.suspend')->with('id', $id);
  }));

There are a number of them in there

Composer

Of course you need it in your composer file

    "require": {
        "laravel/framework": "4.2.*",
        "cartalyst/sentry": "~2.1",
        "r15ch13/peculiar": "1.0.*@dev"
    },

User Migration file

This repo the sentry migration files are copied into app/database/migrations

This being key

$table->string('id', '36')->primary();
#app/database/migrations/2012_12_06_225921_migration_cartalyst_sentry_install_users.php

<?php

use Illuminate\Database\Migrations\Migration;

class MigrationCartalystSentryInstallUsers extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function($table)
        {
                        $table->string('id', '36')->primary();
            $table->string('email');
            $table->string('password');
            $table->text('permissions')->nullable();
            $table->boolean('activated')->default(0);
            $table->string('activation_code')->nullable();
            $table->timestamp('activated_at')->nullable();
            $table->timestamp('last_login')->nullable();
            $table->string('persist_code')->nullable();
            $table->string('reset_password_code')->nullable();
            $table->string('first_name')->nullable();
            $table->string('last_name')->nullable();
            $table->timestamps();

            // We'll need to ensure that MySQL uses the InnoDB engine to
            // support the indexes, other engines aren't affected.
            $table->engine = 'InnoDB';
            $table->unique('email');
            $table->index('activation_code');
            $table->index('reset_password_code');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }

}

Tags:

laravel php