Skip to content

Instantly share code, notes, and snippets.

@Ellrion
Created September 22, 2014 10:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ellrion/d8ed4f95845bd0aac60b to your computer and use it in GitHub Desktop.
Save Ellrion/d8ed4f95845bd0aac60b to your computer and use it in GitHub Desktop.
Laravel 4 Model GlobalScope
<?php
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ScopeInterface;
class ActivityStatusScope
implements ScopeInterface
{
const STATUS_FIELD = 'status';
const ACTIVE = 1;
const INACTIVE = 0;
/**
* All of the extensions to be added to the builder.
*
* @var array
*/
protected $extensions = ['Deactivate', 'Activate', 'WithInactive', 'OnlyInactive'];
/**
* Apply the scope to a given Eloquent query builder.
*
* @param Builder $builder
* @return void
*/
public function apply(Builder $builder)
{
$model = $builder->getModel();
$builder->where($this->getQualifiedStatusColumn($model), self::ACTIVE);
$this->extend($builder);
}
/**
* Remove the scope from the given Eloquent query builder.
*
* @param Builder $builder
* @return void
*/
public function remove(Builder $builder)
{
$model = $builder->getModel();
$column = $this->getQualifiedStatusColumn($model);
$query = $builder->getQuery();
$bindings = $query->getBindings();
foreach ((array) $query->wheres as $key => $where) {
if ('basic' === strtolower($where['type']) && $column === $where['column'] && '=' === $where['operator']) {
if ( $bindings[$key] == $where['value'] ) {
unset($bindings[$key]);
}
unset($query->wheres[$key]);
$query->wheres = array_values($query->wheres);
}
}
$query->wheres = array_values($query->wheres);
$query->setBindings(array_values($bindings));
}
/**
* Extend the query builder with the needed functions.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return void
*/
public function extend(Builder $builder)
{
foreach ($this->extensions as $extension) {
$this->{"add{$extension}"}($builder);
}
}
protected function addDeactivate(Builder $builder)
{
$builder->macro('deactivate', function(Builder $builder) {
return $builder->update([$this->getStatusColumn($builder->getModel()) => self::INACTIVE]);
});
}
protected function addActivate(Builder $builder)
{
$builder->macro('activate', function(Builder $builder) {
$builder->withInactive();
return $builder->update([$this->getStatusColumn($builder->getModel()) => self::ACTIVE]);
});
}
protected function addWithInactive(Builder $builder)
{
$builder->macro('withInactive', function(Builder $builder) {
$this->remove($builder);
return $builder;
});
}
protected function addOnlyInactive(Builder $builder)
{
$builder->macro('onlyInactive', function(Builder $builder) {
$this->remove($builder);
$builder->getQuery()->where(
$this->getStatusColumn($builder->getModel())
, '!='
, self::ACTIVE
);
return $builder;
});
}
protected function getQualifiedStatusColumn(\Illuminate\Database\Eloquent\Model $model)
{
return method_exists($model, 'getQualifiedStatusColumn')
? $model->getQualifiedStatusColumn()
: $model->getTable().'.'.$this->getStatusColumn($model);
}
protected function getStatusColumn(\Illuminate\Database\Eloquent\Model $model)
{
return method_exists($model, 'getStatusColumn')
? $model->getStatusColumn()
: self::STATUS_FIELD;
}
}
<?php
trait ActivityStatusTrait
{
public static function bootActivityStatusTrait()
{
static::addGlobalScope(new ActivityStatusScope);
}
/**
* Set active status fore inactive model instance.
*
* @return bool|null
*/
public function activate()
{
if ($this->fireModelEvent('activating') === false) {
return false;
}
$this->{$this->getStatusColumn()} = ActivityStatusScope::ACTIVE;
$result = $this->save();
$this->fireModelEvent('activated', false);
return $result;
}
/**
* Set inactive status fore active model instance.
*
* @return bool|null
*/
public function deactivate()
{
if ($this->fireModelEvent('deactivating') === false) {
return false;
}
$this->{$this->getStatusColumn()} = ActivityStatusScope::INACTIVE;
$result = $this->save();
$this->fireModelEvent('deactivated', false);
return $result;
}
/**
* Determine if the model instance has been inactive.
*
* @return bool
*/
public function isInactive()
{
return (int)$this->{$this->getStatusColumn()} !== (int)ActivityStatusScope::ACTIVE;
}
/**
* Get a new query builder that includes inactive items.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withInactive()
{
return (new static)->newQueryWithoutScope(new ActivityStatusScope);
}
/**
* Get a new query builder that only includes inactive items.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function onlyInactive()
{
$instance = new static;
$column = $instance->getQualifiedStatusColumn();
return $instance->newQueryWithoutScope(new ActivityStatusScope())
->where($column, '!=', ActivityStatusScope::ACTIVE);
}
/**
* Register a activating model event with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function activating($callback)
{
static::registerModelEvent('activating', $callback);
}
/**
* Register a activated model event with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function activated($callback)
{
static::registerModelEvent('activated', $callback);
}
/**
* Register a deactivating model event with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function deactivating($callback)
{
static::registerModelEvent('deactivating', $callback);
}
/**
* Register a deactivated model event with the dispatcher.
*
* @param \Closure|string $callback
* @return void
*/
public static function deactivated($callback)
{
static::registerModelEvent('deactivated', $callback);
}
/**
* Get the name of the "status" column.
*
* @return string
*/
public function getStatusColumn()
{
return defined('static::STATUS_FIELD') ? static::STATUS_FIELD : ActivityStatusScope::STATUS_FIELD;
}
/**
* Get the fully qualified "status" column.
*
* @return string
*/
public function getQualifiedStatusColumn()
{
return $this->getTable().'.'.$this->getStatusColumn();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment