Skip to content

Commit

Permalink
new concept of likes and dislikes
Browse files Browse the repository at this point in the history
  • Loading branch information
turahe committed Oct 27, 2020
1 parent 343183f commit f81cdf2
Show file tree
Hide file tree
Showing 28 changed files with 2,244 additions and 303 deletions.
406 changes: 384 additions & 22 deletions README.md

Large diffs are not rendered by default.

38 changes: 36 additions & 2 deletions migrations/2016_02_07_000000_create_likeable_tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,61 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
* Class CreateLikeableTables
*/
class CreateLikeableTables extends Migration
{
public function up()
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('likes', function(Blueprint $table) {
$table->id();
$table->morphs('likeable');
$table->unsignedBigInteger('user_id')->index();
$table->enum('type_id', [
'like',
'dislike',
])->default('like');
$table->timestamps();

$table->unique([
'likeable_id',
'likeable_type',
'user_id',
], 'like_user_unique');

});

Schema::create('like_counters', function(Blueprint $table) {
$table->id();
$table->morphs('likeable');
$table->enum('type_id', [
'like',
'dislike',
])->default('like');
$table->unsignedBigInteger('count')->default(0);
$table->timestamps();

$table->unique([
'likeable_id',
'likeable_type',
'type_id',
], 'like_counter_unique');
});

}

public function down()
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('likes');
Schema::drop('like_counters');
Expand Down
134 changes: 134 additions & 0 deletions src/Console/LikeableRecountCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php


namespace Turahe\Likeable\Console;

use Turahe\Likeable\Contracts\Likeable as LikeableContract;
use Turahe\Likeable\Contracts\Like as LikeContract;
use Turahe\Likeable\Contracts\LikeCounter as LikeCounterContract;
use Turahe\Likeable\Exceptions\ModelInvalidException;
use Turahe\Likeable\Services\LikeableService as LikeableServiceContract;
use Illuminate\Console\Command;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Facades\DB;

class LikeableRecountCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'likeable:recount {model?} {type?}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Recount likes and dislikes for the models';

/**
* Type of likes to be recounted.
*
* @var string|null
*/
protected $likeType;

/**
* Likeable service.
*
* @var \Turahe\Likeable\Contracts\LikeableService
*/
protected $service;

/**
* Execute the console command.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*
* @throws \Turahe\Likeable\Exceptions\ModelInvalidException
*/
public function handle(Dispatcher $events)
{
$model = $this->argument('model');
$this->likeType = $this->argument('type');
$this->service = app(LikeableServiceContract::class);

if (empty($model)) {
$this->recountLikesOfAllModelTypes();
} else {
$this->recountLikesOfModelType($model);
}
}

/**
* Recount likes of all model types.
*
* @return void
*
* @throws \Turahe\Likeable\Exceptions\ModelInvalidException
*/
protected function recountLikesOfAllModelTypes()
{
$likeableTypes = app(LikeContract::class)->groupBy('likeable_type')->get();
foreach ($likeableTypes as $like) {
$this->recountLikesOfModelType($like->likeable_type);
}
}

/**
* Recount likes of model type.
*
* @param string $modelType
* @return void
*
* @throws \Turahe\Likeable\Exceptions\ModelInvalidException
*/
protected function recountLikesOfModelType($modelType)
{
$modelType = $this->normalizeModelType($modelType);

$counters = $this->service->fetchLikesCounters($modelType, $this->likeType);

$this->service->removeLikeCountersOfType($modelType, $this->likeType);

DB::table(app(LikeCounterContract::class)->getTable())->insert($counters);

$this->info('All [' . $modelType . '] records likes has been recounted.');
}

/**
* Normalize likeable model type.
*
* @param string $modelType
* @return string
*
* @throws \Turahe\Likeable\Exceptions\ModelInvalidException
*/
protected function normalizeModelType($modelType)
{
$morphMap = Relation::morphMap();

if (class_exists($modelType)) {
$model = new $modelType;
$modelType = $model->getMorphClass();
} else {
if (!isset($morphMap[$modelType])) {
throw new ModelInvalidException("[$modelType] class and morph map are not found.");
}

$modelClass = $morphMap[$modelType];
$model = new $modelClass;
}

if (!$model instanceof LikeableContract) {
throw new ModelInvalidException("[$modelType] not implements Likeable contract.");
}

return $modelType;
}

}
23 changes: 23 additions & 0 deletions src/Contracts/Like.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php


namespace Turahe\Likeable\Contracts;
/**
* Interface Like.
*
* @property \Turahe\Likeable\Contracts\Likeable likeable
* @property int type_id
* @property int user_id
* @package Turahe\Likeable\Contract
*/

interface Like
{
/**
* Likeable model relation.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function likeable();

}
22 changes: 22 additions & 0 deletions src/Contracts/LikeCounter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php


namespace Turahe\Likeable\Contracts;

/**
* Interface LikeCounter.
*
* @property int type_id
* @property int count
* @package Turahe\Likeable\Contracts
*/
interface LikeCounter
{
/**
* Likeable model relation.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function likeable();

}
Loading

0 comments on commit f81cdf2

Please sign in to comment.