Refresh
This commit is contained in:
24
app/Http/Controllers/Controller.php
Executable file
24
app/Http/Controllers/Controller.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
|
||||
public function s3resource(Request $request, $path)
|
||||
{
|
||||
return response(Storage::get($path), 200, [
|
||||
'Content-Type' => Storage::mimeType($path)
|
||||
]);
|
||||
}
|
||||
}
|
||||
136
app/Http/Controllers/DocumentController.php
Executable file
136
app/Http/Controllers/DocumentController.php
Executable file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Documents\StoreRequest;
|
||||
use App\Models\Document;
|
||||
use App\Models\Folder;
|
||||
use App\Notifications\UnreadItemsChanged;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Storage;
|
||||
|
||||
class DocumentController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Document::class, 'document');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param App\Http\Requests\Documents\StoreRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$user = $request->user();
|
||||
$url = $validated['url'];
|
||||
$folder = Folder::find($validated['folder_id']);
|
||||
$document = Document::firstOrCreate(['url' => $url]);
|
||||
|
||||
$folder->documents()->save($document, [
|
||||
'initial_url' => $url,
|
||||
]);
|
||||
|
||||
return $folder->listDocuments($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Request $request, Document $document)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$document->findDupplicatesFor($user);
|
||||
|
||||
$document->loadMissing('feeds')->loadCount(['feedItemStates' => function ($query) use ($user) {
|
||||
$query->where('is_read', false)->where('user_id', $user->id);
|
||||
}]);
|
||||
|
||||
if (Storage::exists($document->getStoragePath().'/meta.json')) {
|
||||
$document->meta_data = \json_decode(Storage::get($document->getStoragePath().'/meta.json'));
|
||||
}
|
||||
|
||||
if (Storage::exists($document->getStoragePath().'/response.json')) {
|
||||
$document->response = \json_decode(Storage::get($document->getStoragePath().'/response.json'));
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move document into specified folder.
|
||||
*
|
||||
* @param Folder $folder
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function move(Request $request, Folder $sourceFolder, Folder $targetFolder)
|
||||
{
|
||||
$this->authorize('createBookmarkIn', $targetFolder);
|
||||
$this->authorize('deleteBookmarkFrom', $sourceFolder);
|
||||
|
||||
$bookmarks = $sourceFolder->documents()->whereIn('documents.id', $request->input('documents'))->get();
|
||||
|
||||
foreach ($bookmarks as $bookmark) {
|
||||
$sourceFolder->documents()->updateExistingPivot($bookmark->id, ['folder_id' => $targetFolder->id]);
|
||||
}
|
||||
|
||||
$usersToNotify = $sourceFolder->group->activeUsers->merge($targetFolder->group->activeUsers);
|
||||
|
||||
Notification::send($usersToNotify, new UnreadItemsChanged([
|
||||
'folders' => [
|
||||
$sourceFolder->id,
|
||||
$targetFolder->id,
|
||||
],
|
||||
]));
|
||||
|
||||
return $request->user()->countUnreadItems([
|
||||
'folders' => [
|
||||
$sourceFolder->id,
|
||||
$targetFolder->id,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove documents from specified folder.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroyBookmarks(Request $request, Folder $folder)
|
||||
{
|
||||
$this->authorize('deleteBookmarkFrom', $folder);
|
||||
|
||||
$user = $request->user();
|
||||
$documents = $folder->documents()->whereIn('documents.id', $request->input('documents'))->get();
|
||||
|
||||
foreach ($documents as $document) {
|
||||
$folder->documents()->detach($document);
|
||||
}
|
||||
|
||||
Notification::send($folder->group->activeUsers()->get(), new UnreadItemsChanged(['folders' => [$folder]]));
|
||||
|
||||
return $folder->listDocuments($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment visits for specified document in specified folder.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function visit(Request $request, Document $document)
|
||||
{
|
||||
++$document->visits;
|
||||
$document->save();
|
||||
|
||||
return $this->show($request, $document);
|
||||
}
|
||||
}
|
||||
43
app/Http/Controllers/FeedController.php
Executable file
43
app/Http/Controllers/FeedController.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Feed;
|
||||
use App\Models\IgnoredFeed;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FeedController extends Controller
|
||||
{
|
||||
/**
|
||||
* Ignore specified feed.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function ignore(Request $request, Feed $feed)
|
||||
{
|
||||
$ignoredFeed = IgnoredFeed::where('user_id', $request->user()->id)->where('feed_id', $feed->id)->first();
|
||||
|
||||
if (!$ignoredFeed) {
|
||||
$ignoredFeed = new IgnoredFeed();
|
||||
|
||||
$ignoredFeed->user()->associate($request->user());
|
||||
$ignoredFeed->feed()->associate($feed);
|
||||
|
||||
$ignoredFeed->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow specified feed.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function follow(Request $request, Feed $feed)
|
||||
{
|
||||
$ignoredFeed = IgnoredFeed::where('user_id', $request->user()->id)->where('feed_id', $feed->id)->first();
|
||||
|
||||
if ($ignoredFeed) {
|
||||
$ignoredFeed->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
81
app/Http/Controllers/FeedItemController.php
Executable file
81
app/Http/Controllers/FeedItemController.php
Executable file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Feed;
|
||||
use App\Models\FeedItem;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FeedItemController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$feedIds = $request->input('feeds', []);
|
||||
|
||||
if (empty($feedIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$user = $request->user();
|
||||
$folder = $user->selectedFolder();
|
||||
|
||||
$queryBuilder = FeedItem::with('feeds:feeds.id,title', 'feeds.documents:documents.id')->inFeeds($feedIds);
|
||||
|
||||
$queryBuilder->select([
|
||||
'feed_items.id',
|
||||
'url',
|
||||
'title',
|
||||
'published_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]);
|
||||
|
||||
if ($folder->type === 'unread_items') {
|
||||
$queryBuilder->unreadFor($user);
|
||||
}
|
||||
|
||||
return $queryBuilder->countStates($user)->orderBy('published_at', 'desc')->simplePaginate(15);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Request $request, FeedItem $feedItem)
|
||||
{
|
||||
$feedItem->loadCount(['feedItemStates' => function ($query) use ($request) {
|
||||
$query->where('is_read', false)->where('user_id', $request->user()->id);
|
||||
}]);
|
||||
|
||||
$feedItem->loadMissing('feeds');
|
||||
|
||||
return $feedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark feed items as read.
|
||||
*/
|
||||
public function markAsRead(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
if ($request->has('folders')) {
|
||||
return $user->markFeedItemsReadInFolders($request->input('folders'));
|
||||
}
|
||||
if ($request->has('documents')) {
|
||||
return $user->markFeedItemsReadInDocuments($request->input('documents'));
|
||||
}
|
||||
if ($request->has('feeds')) {
|
||||
return $user->markFeedItemsReadInFeeds($request->input('feeds'));
|
||||
}
|
||||
if ($request->has('feed_items')) {
|
||||
return $user->markFeedItemsRead($request->input('feed_items'));
|
||||
}
|
||||
}
|
||||
}
|
||||
253
app/Http/Controllers/FolderController.php
Executable file
253
app/Http/Controllers/FolderController.php
Executable file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Folders\SetPermissionsRequest;
|
||||
use App\Http\Requests\Folders\StoreRequest;
|
||||
use App\Http\Requests\Folders\UpdateRequest;
|
||||
use App\Models\Folder;
|
||||
use App\Models\Group;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class FolderController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Folder::class, 'folder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
return $user->getFlatTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Folder\StoreRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$user = $request->user();
|
||||
$parentFolder = Folder::find($validated['parent_id']);
|
||||
$group = Group::find($validated['group_id']);
|
||||
|
||||
$user->createdFolders()->save(new Folder([
|
||||
'title' => $validated['title'],
|
||||
'parent_id' => $parentFolder->id,
|
||||
'group_id' => $group->id,
|
||||
]));
|
||||
|
||||
$user->setFolderExpandedState(true, $parentFolder);
|
||||
|
||||
return $user->getFlatTree($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Request $request, Folder $folder)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$user->setSelectedFolder($folder);
|
||||
|
||||
return $folder->listDocuments($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load every details of specified folder.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function details(Request $request, Folder $folder)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
if (!$user->can('view', $folder)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
if ($folder->type === 'unread_items') {
|
||||
$folder->feed_item_states_count = $folder->group->feedItemStatesCount;
|
||||
} else {
|
||||
$folder->user_permissions = $folder->getUserPermissions($user);
|
||||
$folder->default_permissions = $folder->getDefaultPermissions();
|
||||
|
||||
$folder->loadCount(['feedItemStates' => function ($query) use ($user) {
|
||||
$query->where('is_read', false)->where('user_id', $user->id);
|
||||
}]);
|
||||
|
||||
$folder->group->loadCount('activeUsers');
|
||||
}
|
||||
|
||||
return $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load per-user permissions for specified folder.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function perUserPermissions(Request $request, Folder $folder)
|
||||
{
|
||||
if (!$request->user()->can('setPermission', $folder)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$users = $folder->group->activeUsers()->whereNotIn('users.id', [$request->user()->id])
|
||||
->whereHas('permissions', function ($query) use ($folder) {
|
||||
$query->where('folder_id', $folder->id);
|
||||
})
|
||||
->with(['permissions'=> function ($query) use ($folder) {
|
||||
$query->where('folder_id', $folder->id);
|
||||
}])
|
||||
->select(['users.id', 'users.name', 'users.email'])
|
||||
->get();
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load list of users with no expicit permissions for specified folder.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function usersWithoutPermissions(Request $request, Folder $folder)
|
||||
{
|
||||
if (!$request->user()->can('setPermission', $folder)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$users = $folder->group->activeUsers()->whereNotIn('users.id', [$request->user()->id])
|
||||
->whereDoesntHave('permissions', function ($query) use ($folder) {
|
||||
$query->where('folder_id', $folder->id);
|
||||
})
|
||||
->select(['users.id', 'users.name', 'users.email'])
|
||||
->get();
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param App\Http\Requests\Folder\UpdateRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateRequest $request, Folder $folder)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$user = $request->user();
|
||||
|
||||
if ($request->has('is_expanded')) {
|
||||
$user->setFolderExpandedState($validated['is_expanded'], $folder);
|
||||
}
|
||||
|
||||
$folder->title = $validated['title'];
|
||||
$folder->parent_id = $validated['parent_id'];
|
||||
|
||||
if ($folder->isDirty()) {
|
||||
$folder->save();
|
||||
}
|
||||
|
||||
if (!empty($folder->parent_id)) {
|
||||
$user->setFolderExpandedState(true, $folder->parent);
|
||||
}
|
||||
|
||||
return $folder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Request $request, Folder $folder)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$user->setSelectedFolder(null, $folder->group);
|
||||
|
||||
$folder->delete();
|
||||
|
||||
return $user->getFlatTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle expanded/collapsed a whole folder's branch.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function toggleBranch(Request $request, Folder $folder)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$user->setFolderExpandedState(!$folder->is_expanded, $folder, $folder->group, true);
|
||||
|
||||
return $user->getFlatTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set permissions for specified folder, optionally for specified user.
|
||||
*
|
||||
* @param App\Http\Requests\Folder\SetPermissionsRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function setPermission(SetPermissionsRequest $request, Folder $folder)
|
||||
{
|
||||
if (!$request->user()->can('setPermission', $folder)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$validated = $request->validated();
|
||||
|
||||
$ability = !empty($validated['ability']) ? $validated['ability'] : null;
|
||||
$granted = !empty($validated['granted']) ? $validated['granted'] : false;
|
||||
|
||||
if (empty($validated['user_id'])) {
|
||||
$folder->setDefaultPermission($ability, $granted);
|
||||
|
||||
return $this->details($request, $folder);
|
||||
}
|
||||
|
||||
$user = $folder->group->activeUsers()->findOrFail($validated['user_id']);
|
||||
|
||||
$user->setFolderPermissions($folder, $ability, $granted);
|
||||
|
||||
return $this->perUserPermissions($request, $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove permissions for specified user in specified folder.
|
||||
*
|
||||
* @param App\Http\Requests\Folder\SetPermissionsRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function removePermissions(Request $request, Folder $folder, User $user)
|
||||
{
|
||||
if (!$request->user()->can('setPermission', $folder)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$user->permissions()->where('folder_id', $folder->id)->delete();
|
||||
|
||||
return $this->perUserPermissions($request, $folder);
|
||||
}
|
||||
}
|
||||
254
app/Http/Controllers/GroupController.php
Executable file
254
app/Http/Controllers/GroupController.php
Executable file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\Groups\InviteUserRequest;
|
||||
use App\Http\Requests\Groups\StoreRequest;
|
||||
use App\Http\Requests\Groups\UpdateRequest;
|
||||
use App\Models\Group;
|
||||
use App\Models\User;
|
||||
use App\Notifications\AsksToJoinGroup;
|
||||
use App\Notifications\InvitedToJoinGroup;
|
||||
use Illuminate\Http\Request;
|
||||
use Notification;
|
||||
|
||||
class GroupController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Group::class, 'group');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
$search = $request->input('search');
|
||||
|
||||
$query = Group::visible()
|
||||
->whereNotIn('id', $user->groups->pluck('id'))
|
||||
->with('creator:id,name')
|
||||
->withCount('activeUsers');
|
||||
|
||||
if (!empty($search)) {
|
||||
$query = $query->where('groups.name', 'like', '%'.$search.'%');
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy('name')
|
||||
->simplePaginate(25);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource (active groups).
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexActive(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
return $user->listActiveGroups();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource (my groups).
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function indexMyGroups(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
return $user->groups()->withCount('activeUsers', 'pendingUsers')
|
||||
->whereNotIn('status', [
|
||||
Group::$STATUS_REJECTED,
|
||||
Group::$STATUS_LEFT,
|
||||
])->orderBy('position')->orderBy('id')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\StoreRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$user = $request->user();
|
||||
$validated['user_id'] = $user->id;
|
||||
$group = Group::create($validated);
|
||||
|
||||
$user->groups()->save($group, [
|
||||
'status' => 'created',
|
||||
]);
|
||||
|
||||
return $user->groups()->withCount('activeUsers')->orderBy('position')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(Request $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$user->setSelectedGroup($group);
|
||||
|
||||
return $user->getFlatTree($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(UpdateRequest $request, Group $group)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
$group->name = $validated['name'];
|
||||
$group->description = $validated['description'];
|
||||
$group->invite_only = $validated['invite_only'];
|
||||
$group->auto_accept_users = $validated['auto_accept_users'];
|
||||
|
||||
$group->save();
|
||||
|
||||
return $request->user()->groups()->withCount('activeUsers', 'pendingUsers')->find($group->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Request $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$group->delete();
|
||||
|
||||
return $user->groups()->withCount('activeUsers')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update my groups positions.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updatePositions(Request $request)
|
||||
{
|
||||
if (!$request->has('positions')) {
|
||||
abort(422);
|
||||
}
|
||||
|
||||
$positions = $request->input('positions');
|
||||
|
||||
if (!is_array($positions)) {
|
||||
abort(422);
|
||||
}
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
foreach ($positions as $groupId => $position) {
|
||||
if (!is_numeric($groupId) || !is_numeric($position)) {
|
||||
abort(422);
|
||||
}
|
||||
|
||||
$group = $user->groups()->findOrFail($groupId);
|
||||
|
||||
$user->groups()->updateExistingPivot($group, ['position' => $position]);
|
||||
}
|
||||
|
||||
return $user->groups()->withCount('activeUsers')->orderBy('position')->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invite user to join specified group.
|
||||
*
|
||||
* @param \App\Requests\Groups\InviteUserRequest $request
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function inviteUser(InviteUserRequest $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
if (!$user->can('invite', $group)) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validated = $request->validated();
|
||||
$invitedUser = User::where('email', $validated['email'])->first();
|
||||
|
||||
if ($invitedUser) {
|
||||
$invitedUser->updateGroupStatus($group, Group::$STATUS_INVITED);
|
||||
}
|
||||
|
||||
Notification::route('mail', $validated['email'])
|
||||
->notify(new InvitedToJoinGroup($request->user(), $group));
|
||||
|
||||
return $request->user()->groups()->withCount('activeUsers', 'pendingUsers')->find($group->id);
|
||||
}
|
||||
|
||||
public function acceptInvitation(Request $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
$user->updateGroupStatus($group, Group::$STATUS_ACCEPTED);
|
||||
|
||||
if ($request->ajax()) {
|
||||
return $user->groups()->withCount('activeUsers', 'pendingUsers')->find($group->id);
|
||||
}
|
||||
|
||||
return redirect()->route('account.groups');
|
||||
}
|
||||
|
||||
public function approveUser(Request $request, Group $group, User $user)
|
||||
{
|
||||
$creator = $request->user();
|
||||
|
||||
if (!$creator->can('approve', $group)) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$user->updateGroupStatus($group, Group::$STATUS_ACCEPTED);
|
||||
|
||||
return redirect()->route('account.groups');
|
||||
}
|
||||
|
||||
public function rejectInvitation(Request $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
$user->updateGroupStatus($group, Group::$STATUS_REJECTED);
|
||||
|
||||
return $user->groups()->withCount('activeUsers', 'pendingUsers')->find($group->id);
|
||||
}
|
||||
|
||||
public function leave(Request $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
$user->groups()->detach($group);
|
||||
}
|
||||
|
||||
public function join(Request $request, Group $group)
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
if ($group->auto_accept_users) {
|
||||
$user->updateGroupStatus($group, Group::$STATUS_ACCEPTED);
|
||||
} else {
|
||||
$user->updateGroupStatus($group, Group::$STATUS_JOINING);
|
||||
|
||||
Notification::route('mail', $group->creator->email)
|
||||
->notify(new AsksToJoinGroup($request->user(), $group));
|
||||
}
|
||||
}
|
||||
}
|
||||
103
app/Http/Controllers/HighlightController.php
Executable file
103
app/Http/Controllers/HighlightController.php
Executable file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\StoreHighlightRequest;
|
||||
use App\Models\Highlight;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HighlightController extends Controller
|
||||
{
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(StoreHighlightRequest $request)
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$highlight = new Highlight();
|
||||
|
||||
$highlight->user_id = $request->user()->id;
|
||||
$highlight->expression = $data['expression'];
|
||||
$highlight->color = $data['color'];
|
||||
|
||||
$highlight->save();
|
||||
|
||||
return $request->user()->highlights()->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Models\Models\Highlight $highlight
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(StoreHighlightRequest $request, Highlight $highlight)
|
||||
{
|
||||
if ($highlight->user_id !== $request->user()->id) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$data = $request->validated();
|
||||
|
||||
$highlight->expression = $data['expression'];
|
||||
$highlight->color = $data['color'];
|
||||
|
||||
$highlight->save();
|
||||
|
||||
return $request->user()->highlights()->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Models\Hightlight $hightlight
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Request $request, Highlight $highlight)
|
||||
{
|
||||
if ($highlight->user_id !== $request->user()->id) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$highlight->delete();
|
||||
|
||||
return $request->user()->highlights()->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update my groups positions.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updatePositions(Request $request)
|
||||
{
|
||||
if (!$request->has('positions')) {
|
||||
abort(422);
|
||||
}
|
||||
|
||||
$positions = $request->input('positions');
|
||||
|
||||
if (!is_array($positions)) {
|
||||
abort(422);
|
||||
}
|
||||
|
||||
$user = $request->user();
|
||||
|
||||
foreach ($positions as $highlightId => $position) {
|
||||
if (!is_numeric($highlightId) || !is_numeric($position)) {
|
||||
abort(422);
|
||||
}
|
||||
|
||||
$highlight = $user->highlights()->findOrFail($highlightId);
|
||||
|
||||
$highlight->position = $positions[$highlightId];
|
||||
|
||||
$highlight->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
102
app/Http/Controllers/HomeController.php
Executable file
102
app/Http/Controllers/HomeController.php
Executable file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Services\Exporter;
|
||||
use App\Services\Importer;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('home');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show application's about page'.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function about()
|
||||
{
|
||||
return view('account.about');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show user's account page.
|
||||
*/
|
||||
public function account()
|
||||
{
|
||||
return view('account.my_account');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show user's password update page.
|
||||
*/
|
||||
public function password()
|
||||
{
|
||||
return view('account.password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage user's highlights.
|
||||
*/
|
||||
public function highlights()
|
||||
{
|
||||
return view('account.highlights');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the import form.
|
||||
*/
|
||||
public function showImportForm()
|
||||
{
|
||||
return view('account.import');
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a file.
|
||||
*/
|
||||
public function import(Request $request)
|
||||
{
|
||||
(new Importer())->fromRequest($request)->import();
|
||||
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
/**
|
||||
* Export user's data.
|
||||
*/
|
||||
public function export(Request $request)
|
||||
{
|
||||
$data = (new Exporter())->forUser($request->user())->export();
|
||||
|
||||
return response()->streamDownload(function () use ($data) {
|
||||
echo json_encode($data);
|
||||
}, sprintf('%s - Export.json', $request->user()->name), [
|
||||
'Content-Type' => 'application/x-json',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage groups.
|
||||
*/
|
||||
public function groups()
|
||||
{
|
||||
return view('account.groups');
|
||||
}
|
||||
}
|
||||
68
app/Http/Kernel.php
Executable file
68
app/Http/Kernel.php
Executable file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\SetLang::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
];
|
||||
}
|
||||
22
app/Http/Middleware/Authenticate.php
Executable file
22
app/Http/Middleware/Authenticate.php
Executable file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (!$request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
||||
16
app/Http/Middleware/CheckForMaintenanceMode.php
Executable file
16
app/Http/Middleware/CheckForMaintenanceMode.php
Executable file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
|
||||
|
||||
class CheckForMaintenanceMode extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
}
|
||||
16
app/Http/Middleware/EncryptCookies.php
Executable file
16
app/Http/Middleware/EncryptCookies.php
Executable file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Executable file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
26
app/Http/Middleware/RedirectIfAuthenticated.php
Executable file
26
app/Http/Middleware/RedirectIfAuthenticated.php
Executable file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param null|string $guard
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(route('home'));
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
27
app/Http/Middleware/SetLang.php
Executable file
27
app/Http/Middleware/SetLang.php
Executable file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SetLang
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
$lang = config('app.locale');
|
||||
|
||||
if ($request->user()) {
|
||||
$lang = $request->user()->lang;
|
||||
}
|
||||
|
||||
app()->setLocale(trim($lang));
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
18
app/Http/Middleware/TrimStrings.php
Executable file
18
app/Http/Middleware/TrimStrings.php
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Executable file
20
app/Http/Middleware/TrustHosts.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
app/Http/Middleware/TrustProxies.php
Executable file
23
app/Http/Middleware/TrustProxies.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var null|array|string
|
||||
*/
|
||||
protected $proxies = '*';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
}
|
||||
16
app/Http/Middleware/VerifyCsrfToken.php
Executable file
16
app/Http/Middleware/VerifyCsrfToken.php
Executable file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
}
|
||||
56
app/Http/Requests/Documents/StoreRequest.php
Executable file
56
app/Http/Requests/Documents/StoreRequest.php
Executable file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Documents;
|
||||
|
||||
use App\Models\Folder;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$folder = Folder::find($this->folder_id);
|
||||
|
||||
return $this->user()->can('createBookmarkIn', $folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'url' => [
|
||||
'required',
|
||||
'url',
|
||||
],
|
||||
'group_id' => [
|
||||
'required',
|
||||
Rule::exists(Group::class, 'id'),
|
||||
],
|
||||
'folder_id' => [
|
||||
'required',
|
||||
Rule::exists(Folder::class, 'id'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'url' => urldecode($this->url),
|
||||
]);
|
||||
}
|
||||
}
|
||||
48
app/Http/Requests/Folders/SetPermissionsRequest.php
Executable file
48
app/Http/Requests/Folders/SetPermissionsRequest.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Folders;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class SetPermissionsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return $this->user()->can('setPermission', $this->folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'ability' => [
|
||||
'nullable',
|
||||
Rule::in([
|
||||
'can_create_folder',
|
||||
'can_update_folder',
|
||||
'can_delete_folder',
|
||||
'can_create_document',
|
||||
'can_delete_document',
|
||||
]),
|
||||
],
|
||||
'granted' => [
|
||||
'nullable',
|
||||
'boolean',
|
||||
],
|
||||
'user_id' => [
|
||||
'nullable',
|
||||
Rule::exists('users', 'id'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
51
app/Http/Requests/Folders/StoreRequest.php
Executable file
51
app/Http/Requests/Folders/StoreRequest.php
Executable file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Folders;
|
||||
|
||||
use App\Models\Folder;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
$parentFolder = Folder::find($this->parent_id);
|
||||
|
||||
return $this->user()->can('createIn', $parentFolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$groupId = $this->group_id;
|
||||
|
||||
return [
|
||||
'title' => [
|
||||
'required',
|
||||
'max:255',
|
||||
],
|
||||
// Parent folder ID must exist and in the same group as requested
|
||||
'parent_id' => [
|
||||
'required',
|
||||
Rule::exists(Folder::class, 'id')->where(function ($query) use ($groupId) {
|
||||
$query->where('group_id', '=', $groupId);
|
||||
}),
|
||||
],
|
||||
'group_id' => [
|
||||
'required',
|
||||
Rule::exists(Group::class, 'id'),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
107
app/Http/Requests/Folders/UpdateRequest.php
Executable file
107
app/Http/Requests/Folders/UpdateRequest.php
Executable file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Folders;
|
||||
|
||||
use App\Models\Folder;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
if (empty($this->parent_id)) {
|
||||
return 'root' === $this->folder->type;
|
||||
}
|
||||
|
||||
$parent = Folder::find($this->parent_id);
|
||||
|
||||
return $this->user()->can('createIn', $parent) && $this->user()->can('update', $this->folder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$groupId = $this->group_id;
|
||||
|
||||
return [
|
||||
'title' => [
|
||||
'required',
|
||||
'max:255',
|
||||
],
|
||||
'parent_id' => [
|
||||
'nullable',
|
||||
Rule::exists('App\Models\Folder', 'id')->where(function ($query) use ($groupId) {
|
||||
$query->where('group_id', '=', $groupId);
|
||||
}),
|
||||
],
|
||||
'group_id' => [
|
||||
'required',
|
||||
Rule::exists('App\Models\Group', 'id'),
|
||||
],
|
||||
'is_expanded' => [
|
||||
'sometimes',
|
||||
'boolean',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the validator instance.
|
||||
*
|
||||
* @param \Illuminate\Validation\Validator $validator
|
||||
*/
|
||||
public function withValidator($validator)
|
||||
{
|
||||
$validator->after(function ($validator) {
|
||||
if ($this->isMoving()) {
|
||||
if ('folder' !== $this->folder->type) {
|
||||
// Trying to move a "special" folder like root
|
||||
$validator->errors()->add('parent_id', __('You cannot move this folder'));
|
||||
} elseif ($this->targetParentIsDescendant()) {
|
||||
$validator->errors()->add('parent_id', __('You cannot move this folder to a descendant'));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean value indicating if we're moving a folder.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isMoving()
|
||||
{
|
||||
return $this->parent_id !== $this->folder->parent_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a boolean value indicating if we're trying to move a folder into
|
||||
* one of its descendants.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function targetParentIsDescendant()
|
||||
{
|
||||
$parent = Folder::find($this->parent_id);
|
||||
|
||||
while ($parent) {
|
||||
if ($parent->id === $this->folder->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$parent = $parent->parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
33
app/Http/Requests/Groups/InviteUserRequest.php
Executable file
33
app/Http/Requests/Groups/InviteUserRequest.php
Executable file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Groups;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class InviteUserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return $this->user()->can('invite', $this->group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => [
|
||||
'required',
|
||||
'email',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
41
app/Http/Requests/Groups/StoreRequest.php
Executable file
41
app/Http/Requests/Groups/StoreRequest.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Groups;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
'description' => [
|
||||
'nullable',
|
||||
],
|
||||
'invite_only' => [
|
||||
'boolean',
|
||||
],
|
||||
'auto_accept_users' => [
|
||||
'boolean',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
41
app/Http/Requests/Groups/UpdateRequest.php
Executable file
41
app/Http/Requests/Groups/UpdateRequest.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Groups;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return $this->user()->can('update', $this->group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
],
|
||||
'description' => [
|
||||
'nullable',
|
||||
],
|
||||
'invite_only' => [
|
||||
'boolean',
|
||||
],
|
||||
'auto_accept_users' => [
|
||||
'boolean',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
36
app/Http/Requests/StoreHighlightRequest.php
Executable file
36
app/Http/Requests/StoreHighlightRequest.php
Executable file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreHighlightRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'expression' => [
|
||||
'required',
|
||||
],
|
||||
'color' => [
|
||||
'required',
|
||||
'regex:/^#[0-9a-f]{3,6}$/i',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user