Skip to content

Commit

Permalink
Merge pull request #7 from hootlex/instance-methods
Browse files Browse the repository at this point in the history
Instance methods
  • Loading branch information
hootlex authored Jun 22, 2016
2 parents 4cd8178 + fbc96e6 commit 9854894
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 62 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ php artisan vendor:publish --provider="Hootlex\Moderation\ModerationServiceProvi
```


## Setup the Model(s)
## Prepare Model

To enable moderation for a model, use the `Hootlex\Moderation\Moderatable` trait on the model and add the `status`, `moderated_by` and `moderated_at` columns to your model's table.
```php
Expand Down Expand Up @@ -95,15 +95,27 @@ class AddModerationColumnsToPostsTable extends Migration
> **Note:** In next examples I will use Post model to demonstrate how the query builder works. You can Moderate any Eloquent Model, even User.
###Moderate Models
You can moderate a model by referencing it's id.
You can moderate a model Instance:
```php
$post->markApproved();

$post->markRejected();

$post->markPostponed();

$post->markPending();
```

or by referencing it's id"
```php
Post::approve($post->id);

Post::reject($post->id);

Post::postpone($post->id);
```
Or by making a query.

or by making a query.
```php
Post::where('title', 'Horse')->approve();

Expand Down
91 changes: 33 additions & 58 deletions src/Moderatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

trait Moderatable
{
use ModerationQueryBuilder;

/**
* Boot the soft deleting trait for a model.
Expand All @@ -18,109 +19,83 @@ public static function bootModeratable()
}

/**
* Get a new query builder that only includes pending resources.
* Change resource status to Approved
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function pending()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->pending();
}

/**
* Get a new query builder that only includes rejected resources.
* @param $id
*
* @return \Illuminate\Database\Eloquent\Builder|static
* @return mixed
*/
public static function rejected()
public static function approve($id)
{
return (new static)->newQueryWithoutScope(new ModerationScope())->rejected();
return (new static)->newQueryWithoutScope(new ModerationScope())->approve($id);
}

/**
* Get a new query builder that only includes postponed resources.
* Change resource status to Rejected
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function postponed()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->postponed();
}

/**
* Get a new query builder that includes pending resources.
* @param null $id
*
* @return \Illuminate\Database\Eloquent\Builder|static
* @return mixed
*/
public static function withPending()
public static function reject($id)
{
return (new static)->newQueryWithoutScope(new ModerationScope())->withPending();
return (new static)->newQueryWithoutScope(new ModerationScope())->reject($id);
}

/**
* Get a new query builder that includes rejected resources.
* Change resource status to Postpone
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withRejected()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->withRejected();
}

/**
* Get a new query builder that includes postponed resources.
* @param null $id
*
* @return \Illuminate\Database\Eloquent\Builder|static
* @return mixed
*/
public static function withPostponed()
public static function postpone($id)
{
return (new static)->newQueryWithoutScope(new ModerationScope())->withPostponed();
return (new static)->newQueryWithoutScope(new ModerationScope())->postpone($id);
}

/**
* Get a new query builder that includes all resources.
* Change Instance's status to Approved
*
* @return \Illuminate\Database\Eloquent\Builder|static
* @return mixed
*/
public static function withAnyStatus()
public function markApproved()
{
return (new static)->newQueryWithoutScope(new ModerationScope());
$new = (new static)->newQueryWithoutScope(new ModerationScope())->approve($this->id);
return $this->setRawAttributes($new->attributesToArray());
}

/**
* Change resource status to Approved
*
* @param $id
* Change Instance's status to Rejected
*
* @return mixed
*/
public static function approve($id)
public function markRejected()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->approve($id);
$new = (new static)->newQueryWithoutScope(new ModerationScope())->reject($this->id);
return $this->setRawAttributes($new->attributesToArray());
}

/**
* Change resource status to Rejected
*
* @param null $id
* Change Instance's status to Postponed
*
* @return mixed
*/
public static function reject($id)
public function markPostponed()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->reject($id);
$new = (new static)->newQueryWithoutScope(new ModerationScope())->postpone($this->id);
return $this->setRawAttributes($new->attributesToArray());
}

/**
* Change resource status to Postpone
*
* @param null $id
* Change Instance's status to Pending
*
* @return mixed
*/
public static function postpone($id)
public function markPending()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->postpone($id);
$new = (new static)->newQueryWithoutScope(new ModerationScope())->pend($this->id);
return $this->setRawAttributes($new->attributesToArray());
}

/**
Expand Down
78 changes: 78 additions & 0 deletions src/ModerationQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Hootlex\Moderation;



trait ModerationQueryBuilder
{
/**
* Get a new query builder that only includes pending resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function pending()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->pending();
}

/**
* Get a new query builder that only includes rejected resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function rejected()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->rejected();
}

/**
* Get a new query builder that only includes postponed resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function postponed()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->postponed();
}

/**
* Get a new query builder that includes pending resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withPending()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->withPending();
}

/**
* Get a new query builder that includes rejected resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withRejected()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->withRejected();
}

/**
* Get a new query builder that includes postponed resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withPostponed()
{
return (new static)->newQueryWithoutScope(new ModerationScope())->withPostponed();
}

/**
* Get a new query builder that includes all resources.
*
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public static function withAnyStatus()
{
return (new static)->newQueryWithoutScope(new ModerationScope());
}
}
19 changes: 18 additions & 1 deletion src/ModerationScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ModerationScope implements ScopeInterface
'Approve',
'Reject',
'Postpone',
'Pend'
];

/**
Expand Down Expand Up @@ -278,6 +279,21 @@ protected function addPostpone(Builder $builder)
});
}

/**
* Add the Postpone extension to the builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
*
* @return void
*/
protected function addPend(Builder $builder)
{
$builder->macro('pend', function (Builder $builder, $id = null) {
$builder->withAnyStatus();
return $this->updateModerationStatus($builder, $id, Status::PENDING);
});
}

/**
* Get the "deleted at" column for the builder.
*
Expand Down Expand Up @@ -346,7 +362,8 @@ private function updateModerationStatus(Builder $builder, $id, $status)
$model->{$moderated_by} = \Auth::user()->getKey();
}

return $model->save();
$model->save();
return $model;
}

$update = [
Expand Down
63 changes: 63 additions & 0 deletions tests/ModerationTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,17 @@ public function it_postpones_a_story_by_id()
['id' => $post->id, $this->status_column => Status::POSTPONED, $this->moderated_at_column => \Carbon\Carbon::now()]);
}

/** @test */
public function it_pendings_a_story_by_id()
{
$post = $this->createPost([$this->status_column => Status::APPROVED]);

Post::pend($post->id);

$this->seeInDatabase('posts',
['id' => $post->id, $this->status_column => Status::PENDING, $this->moderated_at_column => \Carbon\Carbon::now()]);
}

/** @test */
public function it_determines_if_story_is_approved()
{
Expand Down Expand Up @@ -186,4 +197,56 @@ public function it_deletes_resources_of_any_status(){
$this->dontSeeInDatabase('posts',['id' => $posts[2]->id]);
}

/** @test */
public function it_marks_as_approved_an_instance()
{
$post = $this->createPost([$this->status_column => Status::PENDING]);

$post->markApproved();

$this->assertEquals(Status::APPROVED, $post->status);

$this->seeInDatabase('posts',
['id' => $post->id, $this->status_column => Status::APPROVED, $this->moderated_at_column => \Carbon\Carbon::now()]);
}

/** @test */
public function it_marks_as_rejected_an_instance()
{
$post = $this->createPost([$this->status_column => Status::PENDING]);

$post->markRejected();

$this->assertEquals(Status::REJECTED, $post->status);

$this->seeInDatabase('posts',
['id' => $post->id, $this->status_column => Status::REJECTED, $this->moderated_at_column => \Carbon\Carbon::now()]);
}

/** @test */
public function it_marks_as_postponed_an_instance()
{
$post = $this->createPost([$this->status_column => Status::PENDING]);

$post->markPostponed();

$this->assertEquals(Status::POSTPONED, $post->status);

$this->seeInDatabase('posts',
['id' => $post->id, $this->status_column => Status::POSTPONED, $this->moderated_at_column => \Carbon\Carbon::now()]);
}

/** @test */
public function it_marks_as_pending_an_instance()
{
$post = $this->createPost([$this->status_column => Status::PENDING]);

$post->markPending();

$this->assertEquals(Status::PENDING, $post->status);

$this->seeInDatabase('posts',
['id' => $post->id, $this->status_column => Status::PENDING, $this->moderated_at_column => \Carbon\Carbon::now()]);
}

}

0 comments on commit 9854894

Please sign in to comment.