mirror of
https://github.com/flarum/core.git
synced 2025-10-26 21:21:28 +01:00
Upgrade to L5 + huge refactor + more. closes #2
New stuff: - Signup + email confirmation. - Updated authentication strategy with remember cookies. closes #5 - New search system with some example gambits! This is cool - check out the source. Fulltext drivers will be implemented as decorators overriding the EloquentPostRepository’s findByContent method. - Lay down the foundation for bootstrapping the Ember app. - Update Web layer’s asset manager to properly publish CSS/JS files. - Console commands to run installation migrations and seeds. Refactoring: - New structure: move models, repositories, commands, and events into their own namespaces, rather than grouping by entity. - All events are classes. - Use L5 middleware and command bus implementations. - Clearer use of repositories and the Active Record pattern. Repositories are used only for retrieval of ActiveRecord objects, and then save/delete operations are called directly on those ActiveRecords. This way, we don’t over-abstract at the cost of Eloquent magic, but testing is still easy. - Refactor of Web layer so that it uses the Actions routing architecture. - “Actor” concept instead of depending on Laravel’s Auth. - General cleanup!
This commit is contained in:
33
src/Core/Repositories/DiscussionRepositoryInterface.php
Normal file
33
src/Core/Repositories/DiscussionRepositoryInterface.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php namespace Flarum\Core\Repositories;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
interface DiscussionRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Get a new query builder for ths discussions table.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function query();
|
||||
|
||||
/**
|
||||
* Find a discussion by ID, optionally making sure it is visible to a certain
|
||||
* user, or throw an exception.
|
||||
*
|
||||
* @param integer $id
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Flarum\Core\Models\Discussion
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail($id, User $user = null);
|
||||
|
||||
/**
|
||||
* Get the IDs of discussions which a user has read completely.
|
||||
*
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return array
|
||||
*/
|
||||
public function getReadIds(User $user);
|
||||
}
|
||||
65
src/Core/Repositories/EloquentDiscussionRepository.php
Normal file
65
src/Core/Repositories/EloquentDiscussionRepository.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php namespace Flarum\Core\Repositories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Flarum\Core\Models\Discussion;
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
class EloquentDiscussionRepository implements DiscussionRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Get a new query builder for ths discussions table.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return Discussion::query();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a discussion by ID, optionally making sure it is visible to a certain
|
||||
* user, or throw an exception.
|
||||
*
|
||||
* @param integer $id
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Flarum\Core\Models\Discussion
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail($id, User $user = null)
|
||||
{
|
||||
$query = Discussion::where('id', $id);
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IDs of discussions which a user has read completely.
|
||||
*
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return array
|
||||
*/
|
||||
public function getReadIds(User $user)
|
||||
{
|
||||
return Discussion::leftJoin('users_discussions', 'users_discussions.discussion_id', '=', 'discussions.id')
|
||||
->where('user_id', $user->id)
|
||||
->where('read_number', '<', 'last_post_number')
|
||||
->lists('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include records that are visible to a user.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function scopeVisibleForUser(Builder $query, User $user = null)
|
||||
{
|
||||
if ($user !== null) {
|
||||
$query->whereCan($user, 'view');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
121
src/Core/Repositories/EloquentPostRepository.php
Normal file
121
src/Core/Repositories/EloquentPostRepository.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php namespace Flarum\Core\Repositories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Flarum\Core\Models\Post;
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
class EloquentPostRepository implements PostRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Find a post by ID, optionally making sure it is visible to a certain
|
||||
* user, or throw an exception.
|
||||
*
|
||||
* @param integer $id
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Flarum\Core\Models\Post
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail($id, User $user = null)
|
||||
{
|
||||
$query = Post::where('id', $id);
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find posts in a discussion, optionally making sure they are visible to
|
||||
* a certain user, and/or using other criteria.
|
||||
*
|
||||
* @param integer $discussionId
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @param string $sort
|
||||
* @param string $order
|
||||
* @param integer $count
|
||||
* @param integer $start
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findByDiscussion($discussionId, User $user = null, $sort = 'time', $order = 'asc', $count = null, $start = 0)
|
||||
{
|
||||
$query = Post::where('discussion_id', $discussionId)
|
||||
->orderBy($sort, $order)
|
||||
->skip($start)
|
||||
->take($count);
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find posts by their IDs, optionally making sure they are visible to a
|
||||
* certain user.
|
||||
*
|
||||
* @param array $ids
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findByIds(array $ids, User $user = null)
|
||||
{
|
||||
$query = Post::whereIn('id', (array) $ids);
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find posts by matching a string of words against their content,
|
||||
* optionally making sure they are visible to a certain user.
|
||||
*
|
||||
* @param string $string
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findByContent($string, User $user = null)
|
||||
{
|
||||
$query = Post::select('id', 'discussion_id')
|
||||
->where('content', 'like', '%'.$string.'%');
|
||||
// ->whereRaw('MATCH (`content`) AGAINST (? IN BOOLEAN MODE)', [$string])
|
||||
// ->orderByRaw('MATCH (`content`) AGAINST (?) DESC', [$string])
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position within a discussion where a post with a certain number
|
||||
* is. If the post with that number does not exist, the index of the
|
||||
* closest post to it will be returned.
|
||||
*
|
||||
* @param integer $discussionId
|
||||
* @param integer $number
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @return integer
|
||||
*/
|
||||
public function getIndexForNumber($discussionId, $number, User $user = null)
|
||||
{
|
||||
$query = Post::where('discussion_id', $discussionId)
|
||||
->where('time', '<', function ($query) use ($discussionId, $number) {
|
||||
$query->select('time')
|
||||
->from('posts')
|
||||
->where('discussion_id', $discussionId)
|
||||
->whereNotNull('number')
|
||||
->orderByRaw('ABS(CAST(number AS SIGNED) - ?)', [$number])
|
||||
->take(1);
|
||||
});
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include records that are visible to a user.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function scopeVisibleForUser(Builder $query, User $user = null)
|
||||
{
|
||||
if ($user !== null) {
|
||||
$query->whereCan($user, 'view');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
67
src/Core/Repositories/EloquentUserRepository.php
Normal file
67
src/Core/Repositories/EloquentUserRepository.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php namespace Flarum\Core\Repositories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
class EloquentUserRepository implements UserRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Find a user by ID, optionally making sure it is visible to a certain
|
||||
* user, or throw an exception.
|
||||
*
|
||||
* @param integer $id
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Flarum\Core\Models\User
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail($id, User $user = null)
|
||||
{
|
||||
$query = User::where('id', $id);
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a user by an identification (username or email).
|
||||
*
|
||||
* @param string $identification
|
||||
* @return \Flarum\Core\Models\User|null
|
||||
*/
|
||||
public function findByIdentification($identification)
|
||||
{
|
||||
$field = filter_var($identification, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
|
||||
|
||||
return User::where($field, $identification)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of a user with the given username.
|
||||
*
|
||||
* @param string $username
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return integer|null
|
||||
*/
|
||||
public function getIdForUsername($username, User $user = null)
|
||||
{
|
||||
$query = User::where('username', 'like', $username);
|
||||
|
||||
return $this->scopeVisibleForUser($query, $user)->pluck('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include records that are visible to a user.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function scopeVisibleForUser(Builder $query, User $user = null)
|
||||
{
|
||||
if ($user !== null) {
|
||||
$query->whereCan($user, 'view');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
64
src/Core/Repositories/PostRepositoryInterface.php
Normal file
64
src/Core/Repositories/PostRepositoryInterface.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php namespace Flarum\Core\Repositories;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
interface PostRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Find a post by ID, optionally making sure it is visible to a certain
|
||||
* user, or throw an exception.
|
||||
*
|
||||
* @param integer $id
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Flarum\Core\Models\Post
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail($id, User $user = null);
|
||||
|
||||
/**
|
||||
* Find posts in a discussion, optionally making sure they are visible to
|
||||
* a certain user, and/or using other criteria.
|
||||
*
|
||||
* @param integer $discussionId
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @param string $sort
|
||||
* @param string $order
|
||||
* @param integer $count
|
||||
* @param integer $start
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findByDiscussion($discussionId, User $user = null, $sort = 'time', $order = 'asc', $count = null, $start = 0);
|
||||
|
||||
/**
|
||||
* Find posts by their IDs, optionally making sure they are visible to a
|
||||
* certain user.
|
||||
*
|
||||
* @param array $ids
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findByIds(array $ids, User $user = null);
|
||||
|
||||
/**
|
||||
* Find posts by matching a string of words against their content,
|
||||
* optionally making sure they are visible to a certain user.
|
||||
*
|
||||
* @param string $string
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function findByContent($string, User $user = null);
|
||||
|
||||
/**
|
||||
* Get the position within a discussion where a post with a certain number
|
||||
* is. If the post with that number does not exist, the index of the
|
||||
* closest post to it will be returned.
|
||||
*
|
||||
* @param integer $discussionId
|
||||
* @param integer $number
|
||||
* @param \Flarum\Core\Models\User|null $user
|
||||
* @return integer
|
||||
*/
|
||||
public function getIndexForNumber($discussionId, $number, User $user = null);
|
||||
}
|
||||
35
src/Core/Repositories/UserRepositoryInterface.php
Normal file
35
src/Core/Repositories/UserRepositoryInterface.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php namespace Flarum\Core\Repositories;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
interface UserRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Find a user by ID, optionally making sure it is visible to a certain
|
||||
* user, or throw an exception.
|
||||
*
|
||||
* @param integer $id
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return \Flarum\Core\Models\User
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
|
||||
*/
|
||||
public function findOrFail($id, User $user = null);
|
||||
|
||||
/**
|
||||
* Find a user by an identification (username or email).
|
||||
*
|
||||
* @param string $identification
|
||||
* @return \Flarum\Core\Models\User|null
|
||||
*/
|
||||
public function findByIdentification($identification);
|
||||
|
||||
/**
|
||||
* Get the ID of a user with the given username.
|
||||
*
|
||||
* @param string $username
|
||||
* @param \Flarum\Core\Models\User $user
|
||||
* @return integer|null
|
||||
*/
|
||||
public function getIdForUsername($username, User $user = null);
|
||||
}
|
||||
Reference in New Issue
Block a user