2

I want to be able to soft delete users through the $user->delete(); method but it doesn't seem to work properly. It always hard deletes, no matter what I do. I've followed all the Laravel 4.2 documentation about it and I think I've configured Sentry correctly. Here is my code:

User.php

<?php

use Cartalyst\Sentry\Sentry;
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
use Illuminate\Database\Eloquent\SoftDeletingTrait;

class User extends Cartalyst\Sentry\Users\Eloquent\User implements UserInterface, RemindableInterface 
{ 

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

    use UserTrait, RemindableTrait, SoftDeletingTrait;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = array('password', 'remember_token');

    //Soft deleting

    protected $dates = ['deleted_at'];
    public $timestamps = true;

}

Controller.php

public function postDeactivate() 
{

    $validator = Validator::make(Input::all(), array('password' => 'required|min:6'));

    if ($validator->fails()) {
        return Redirect::route('account-deactivate')->withErrors($validator);
    } else {

        try {
            $user = Sentry::getUser();
            if ($user->checkPassword(Input::get('password'))) {
                Mail::send(
                    'emails.deactivate',
                    array('username' => $user->username), 
                    function($message) use ($user) {
                        $message->to($user->email, $user->username)->subject('Hope to see you soon!');
                    }
               );

               if ($user->delete()) {
                   return Redirect::route('home')                                                       ->with('global','Account deactivated!');
               } else {
                   return Redirect::route('account-deactivate')->with('global','Error!');
               }

           } else {
               return Redirect::route('account-deactivate')->with('global','Wrong password.');
           }

       } catch (Cartalyst\Sentry\Users\UserNotFoundException $e) {
           return Redirect::route('account-sign-in-get')->with('message','User not found!');
       }

}

By the way, I've published the Sentry config file under

/vendor/cartalyst/sentry/src/config/config.php

and changed line 123 to

'model' => 'User',

I've also created the migration to add the 'deleted_at' column on my table, so I'm at a loss. Any help would be greatly appreciated.

Thanks in advance!

t j
  • 7,026
  • 12
  • 46
  • 66
Gabriel Rebello
  • 1,077
  • 1
  • 11
  • 17

2 Answers2

1

So, actually the solution was pretty simple. When working with Sentry, you're not using the Eloquent model that comes pre-configured with Laravel, but rather Cartalyst's own model. So what I needed to do was get the soft deleting declaration inside the Sentry user model under /vendor/cartalyst/sentry/src/Cartalyst/Sentry/Users/Eloquent/User.php instead of the one I attempted when this question was opened.

Here's my Sentry User model:

<?php namespace Cartalyst\Sentry\Users\Eloquent;

use Illuminate\Database\Eloquent\SoftDeletingTrait;
use Illuminate\Database\Eloquent\Model;
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 {

        use SoftDeletingTrait;

        protected $dates = ['deleted_at'];
        /**
         * The table associated with the model.
         *
         * @var string
         */
        protected $table = 'users';

Now $user->delete(); works properly, adding a 'deleted_at' timestamp instead of destroying the user.

That comes with some issues though. I haven't had the time to test everything yet, but I came upon some difficulties like the Sentry model not being able to query with trashed results and therefore not retrieving a soft deleted user. For now I just do it with User::withTrashed(); Laravel method, which works nice.

And don't forget to extend Cartalyst's model under /app/models/User.php!

Hope this works for others too!

Gabriel Rebello
  • 1,077
  • 1
  • 11
  • 17
1

This setting worked for me:

On user model: app/models/User.php

<?php
use Cartalyst\Sentry\Users\Eloquent\User as SentryUserModel;
use Illuminate\Database\Eloquent\SoftDeletingTrait;

class User extends SentryUserModel {

    use SoftDeletingTrait;
    protected $softDelete = true;
    protected $dates = ['deleted_at'];

Added the deleted_at field on my user migration:

class UpdateUsersTable extends Migration {

public function up()
{
    Schema::table('users', function(Blueprint $table)
        $table->datetime('deleted_at');
    });
}

public function down()
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->dropColumn('deleted_at');
    });
}

Published the sentry config file

php artisan config:publish --path="vendor/cartalyst/sentry/src/config/config.php" cartalyst/sentry

And I changed line 123 on that published file to use the laravel user model: (app/config/packages/cartalyst/sentry/config.php)

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

It worked and even this works: User::withTrashed()->get();

If that doesn't work, try clearing your database run migrations afresh.

The good thing about this method is that even after you update sentry you wont lose your changes in the vendor folder and your app wont have bugs. Good luck!

Timothy
  • 4,198
  • 6
  • 49
  • 59