4

Update #1

So I think I found out where the problem is but since I lack the knowledge, there's no way for me to solve it.

When using Sentry, I've tried extending both 'Model' which is default with the Sentry package and Laravel's 'Eloquent' under Illuminate\Database\Eloquent\Model. Neither worked. But while using Laravel's Eloquent on its own (no Sentry package addons), Stapler works nicely.

So I guess there is some compatibilty problem between Stapler and Sentry's User model even though it uses Eloquent (its extra functionalities might be conflicting with stapler's traits or the construct function, I don't know). Too bad since Sentry is a great package for managing authentication and throttling and is widely used as far as I know.

Is there any easy way to use stapler's agnostic version with sentry or will I have to rewrite all my code to use laravel's auth?


Main question

I'm building an app which uses Cartalyst's Sentry for managing users. However, I want users and other models to be able to have associated avatars, so I'm using Codesleeve's Stapler too.

I've read both laravel-stapler's readme and most of stapler's standalone version documentation but couldn't figure out how to make them work with Sentry. Whenever I try to create an user through this function:

$user = Sentry::createUser(array(
    'username'      => Input::get('username'),
    'email'         => Input::get('email'),
    'password'      => Input::get('password'),
    'activated'     => false,
    'avatar'        => Input::file('avatar')
));

return 'success';

I get:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'avatar' in 'field list' 

So it seems Sentry is querying as if the avatar is a string and Stapler is not working.

Here is my Sentry user model (which I'm extending in Laravel's):

use Illuminate\Database\Eloquent\SoftDeletingTrait;
use Illuminate\Database\Eloquent\Model;
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;
use Cartalyst\Sentry\Groups\GroupInterface;
use Cartalyst\Sentry\Hashing\HasherInterface;
use Cartalyst\Sentry\Users\LoginRequiredException;
use Cartalyst\Sentry\Users\PasswordRequiredException;
use Cartalyst\Sentry\Users\UserAlreadyActivatedException;
use Cartalyst\Sentry\Users\UserExistsException;
use Cartalyst\Sentry\Users\UserInterface;

class User extends Model implements UserInterface, StaplerableInterface {

        use SoftDeletingTrait, EloquentTrait;

        protected $fillabe = array('username','email','password','password_temp','code','active','avatar');

        public function __construct(array $attributes = array()) {
                $this->hasAttachedFile('avatar', [
                    'styles' => [
                        'medium' => '300x300',
                        'thumb' => '100x100'
                    ]
                ]);

                parent::__construct($attributes);
        }
        protected $dates = ['deleted_at'];

And inside Sentry's config:

'model' => 'Cartalyst\Sentry\Users\Eloquent\User',

This might be simple to solve since I'm pretty new into Laravel, Sentry and Stapler but I couldn't find any info which would make me solve the problem.

Thanks in advance!

Gustavo Straube
  • 3,744
  • 6
  • 39
  • 62
Gabriel Rebello
  • 1,077
  • 1
  • 11
  • 17

1 Answers1

1

Yes, it can be done. Based on what's in your OP, the root cause appears to be that your user model doesn't know that avatar is a Stapler-provided column.

Theory: the Sentry User Provider manufactures a user model, right here. That user model must be Stapler-aware, per the Stapler docs. Fortunately, Sentry is configurable and you can tell it to use your custom model with setModel().

Rough outline of solution: First, you need a model that is Stapler-aware. You might already have this. Note that it extends the Sentry-provided model class and also imports the Stapler trait. Both are important.

<?php // app/models/UserModel.php
namespace App\Model;
use Codesleeve\Stapler\ORM\StaplerableInterface;
use Codesleeve\Stapler\ORM\EloquentTrait;
use Cartalyst\Sentry\Users\Eloquent\User as SentryUserModel;

class UserModel extends SentryUserModel implements StaplerableInterface {
    use EloquentTrait;
}

Second, you need to instruct Sentry to use this. Below I use run-time configuration changes, as is my preference. But you can also change the Sentry configuration file:

<?php // app/bootstrap.php

\Sentry::getUserProvider()->setModel('App\Model\UserModel');

I'm doing this from memory on Laravel 4, so there may need to be some tweaking involved.

bishop
  • 37,830
  • 11
  • 104
  • 139