Skip to content

Commit

Permalink
Following each other. #63
Browse files Browse the repository at this point in the history
  • Loading branch information
artisan committed Aug 31, 2018
1 parent 510e222 commit 2830aa6
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 15 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ $user->unfollow($targets)
$user->toggleFollow($targets)
$user->followings()->get() // App\User:class
$user->followings(App\Post::class)->get()
$user->areFollowingEachOther($anotherUser);
$user->isFollowing($target)
```

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "overtrue/laravel-follow",
"description": "Laravel 5 User Based System",
"require": {
"php": ">=5.5.9"
"php": ">=5.6.0"
},
"require-dev": {
"laravel/laravel": "5.*",
Expand Down
13 changes: 12 additions & 1 deletion src/Follow.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ class Follow
public static function isRelationExists(Model $model, $relation, $target, $class = null)
{
$target = self::formatTargets($target, $class ?: config('follow.user_model'));
$field = self::tablePrefixedField($class ? 'followable_id' : config('follow.users_table_foreign_key', 'user_id'));

return $model->{$relation}($target->classname)
->where($class ? 'followable_id' : config('follow.users_table_foreign_key', 'user_id'), head($target->ids))->exists();
->where($field, head($target->ids))->exists();
}

/**
Expand Down Expand Up @@ -216,4 +217,14 @@ protected static function getRelationTypeFromRelation(MorphToMany $relation)

return self::RELATION_TYPES[$relation->getRelationName()];
}

/**
* @param string $field
*
* @return string
*/
protected static function tablePrefixedField($field)
{
return \sprintf('%s.%s', config('follow.followable_table'), $field);
}
}
15 changes: 14 additions & 1 deletion src/Traits/CanBeFollowed.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Overtrue\LaravelFollow\Traits;

use Illuminate\Support\Facades\DB;
use Overtrue\LaravelFollow\Follow;

/**
Expand All @@ -37,8 +38,20 @@ public function isFollowedBy($user)
*/
public function followers()
{
$table = config('follow.followable_table');
$class = \get_class($this);
$userTable = config('follow.user_table', 'users');
$foreignKey = config('follow.users_table_foreign_key', 'user_id');

return $this->morphToMany(config('follow.user_model'), config('follow.morph_prefix'), config('follow.followable_table'))
->wherePivot('relation', '=', Follow::RELATION_FOLLOW)
->withPivot('followable_type', 'relation', 'created_at');
->withPivot('followable_type', 'relation', 'created_at')
->addSelect("{$userTable}.*", DB::raw("pivot_followables.{$foreignKey} IS NOT NULL AS pivot_each_other"))
->leftJoin("{$table} as pivot_followables", function($join) use ($table, $class, $foreignKey) {

$join->on('pivot_followables.followable_type', '=', DB::raw(\addcslashes("'{$class}'", '\\')))
->on('pivot_followables.followable_id', '=', "{$table}.{$foreignKey}")
->on("pivot_followables.{$foreignKey}", '=', "{$table}.followable_id");
});
}
}
29 changes: 27 additions & 2 deletions src/Traits/CanFollow.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Overtrue\LaravelFollow\Traits;

use Illuminate\Support\Facades\DB;
use Overtrue\LaravelFollow\Follow;

/**
Expand Down Expand Up @@ -74,6 +75,19 @@ public function isFollowing($target, $class = __CLASS__)
return Follow::isRelationExists($this, 'followings', $target, $class);
}

/**
* Check if user and target user is following each other.
*
* @param int|array|\Illuminate\Database\Eloquent\Model $target
* @param string $class
*
* @return bool
*/
public function areFollowingEachOther($target, $class = __CLASS__)
{
return Follow::isRelationExists($this, 'followings', $target, $class) && Follow::isRelationExists($target, 'followings', $this, $class);
}

/**
* Return item followings.
*
Expand All @@ -83,8 +97,19 @@ public function isFollowing($target, $class = __CLASS__)
*/
public function followings($class = __CLASS__)
{
return $this->morphedByMany($class, config('follow.morph_prefix'), config('follow.followable_table'))
$table = config('follow.followable_table');
$foreignKey = config('follow.users_table_foreign_key', 'user_id');
$targetTable = (new $class)->getTable();

return $this->morphedByMany($class, config('follow.morph_prefix'), $table)
->wherePivot('relation', '=', Follow::RELATION_FOLLOW)
->withPivot('followable_type', 'relation', 'created_at');
->withPivot('followable_type', 'relation', 'created_at')
->addSelect("{$targetTable}.*", DB::raw("pivot_followables.{$foreignKey} IS NOT NULL AS pivot_each_other"))
->leftJoin("{$table} as pivot_followables", function($join) use ($table, $class, $foreignKey) {

$join->on('pivot_followables.followable_type', '=', DB::raw(\addcslashes("'{$class}'", '\\')))
->on('pivot_followables.followable_id', '=', "{$table}.{$foreignKey}")
->on("pivot_followables.{$foreignKey}", '=', "{$table}.followable_id");
});
}
}
4 changes: 2 additions & 2 deletions tests/FollowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function testIsRelationExists()
$target = 12;
$model = \Mockery::mock(Model::class);
$model->shouldReceive('followings')->with($class)->andReturnSelf()->once();
$model->shouldReceive('where')->with('followable_id', $target)->andReturnSelf()->once();
$model->shouldReceive('where')->with('followables.followable_id', $target)->andReturnSelf()->once();
$model->shouldReceive('exists')->withNoArgs()->andReturn(true)->once();

$this->assertTrue(Follow::isRelationExists($model, 'followings', $target, $class));
Expand All @@ -35,7 +35,7 @@ public function testIsRelationExists()
$target = 12;
$model = \Mockery::mock(Model::class);
$model->shouldReceive('followings')->with('App\User')->andReturnSelf()->once();
$model->shouldReceive('where')->with('user_id', $target)->andReturnSelf()->once();
$model->shouldReceive('where')->with('followables.user_id', $target)->andReturnSelf()->once();
$model->shouldReceive('exists')->withNoArgs()->andReturn(true)->once();

$this->assertTrue(Follow::isRelationExists($model, 'followings', $target));
Expand Down
16 changes: 9 additions & 7 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@

use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Artisan;

class TestCase extends \Illuminate\Foundation\Testing\TestCase
{
use DatabaseTransactions;

protected $config;

/**
Expand All @@ -41,7 +41,7 @@ public function createApplication()
/**
* Setup DB before each test.
*/
public function setUp()
protected function setUp()
{
parent::setUp();

Expand All @@ -64,21 +64,23 @@ public function migrate()
$fileSystem = new Filesystem();

$fileSystem->copy(
__DIR__.'/../database/migrations/create_laravel_follow_tables.php',
__DIR__.'/../tests/database/migrations/create_laravel_follow_tables.php'
__DIR__.'/../database/migrations/2018_06_29_032244_create_laravel_follow_tables.php',
__DIR__.'/database/migrations/create_laravel_follow_tables.php'
);

foreach ($fileSystem->files(__DIR__.'/../tests/database/migrations') as $file) {
foreach ($fileSystem->files(__DIR__.'/database/migrations') as $file) {
$fileSystem->requireOnce($file);
}

(new \CreateLaravelFollowTables())->up();
(new \CreateUsersTable())->up();
(new \CreateOthersTable())->up();
(new \CreateLaravelFollowTables())->up();
}

public function tearDown()
{
parent::tearDown();

unlink(__DIR__.'/database/migrations/create_laravel_follow_tables.php');
}

Expand Down
15 changes: 14 additions & 1 deletion tests/Traits/CanFollowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public function test_user_can_follow_other_by_id()

$user->follow($other);

$this->assertCount(1, $user->followings(Other::class)->get());
$this->assertCount(1, $user->followings(Other::class)->get());
}

public function test_unfollow_other()
Expand All @@ -89,4 +89,17 @@ public function test_is_following_other()

$this->assertTrue($user->isFollowing($other));
}

public function test_following_each_other()
{
$user1 = User::find(1);
$user2 = User::find(2);

$user1->follow($user2);

$this->assertFalse($user1->areFollowingEachOther($user2));

$user2->follow($user1);
$this->assertTrue($user1->areFollowingEachOther($user2));
}
}

0 comments on commit 2830aa6

Please sign in to comment.