There is no category.
+ @else +{{ $category->name }} | +
diff --git a/app/Category.php b/app/Category.php new file mode 100644 index 0000000..e3f670b --- /dev/null +++ b/app/Category.php @@ -0,0 +1,15 @@ +belongsToMany('App\Post')->withTimestamps(); + } +} \ No newline at end of file diff --git a/app/Comment.php b/app/Comment.php index 5b4f806..761674b 100644 --- a/app/Comment.php +++ b/app/Comment.php @@ -8,8 +8,8 @@ class Comment extends Model { protected $guarded = ['id']; - public function ticket() + public function post() { - return $this->belongsTo('App\Ticket'); + return $this->morphTo(); } } \ No newline at end of file diff --git a/app/Http/Controllers/Admin/CategoriesController.php b/app/Http/Controllers/Admin/CategoriesController.php new file mode 100644 index 0000000..99d4b19 --- /dev/null +++ b/app/Http/Controllers/Admin/CategoriesController.php @@ -0,0 +1,94 @@ + $request->get('name'), + )); + + $category->save(); + + return redirect('/admin/categories/create')->with('status', 'A new category has been created!'); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + // + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + // + } +} diff --git a/app/Http/Controllers/Admin/PagesController.php b/app/Http/Controllers/Admin/PagesController.php new file mode 100644 index 0000000..c441d16 --- /dev/null +++ b/app/Http/Controllers/Admin/PagesController.php @@ -0,0 +1,14 @@ +id; + $post= new Post(array( + 'title' => $request->get('title'), + 'content' => $request->get('content'), + 'slug' => Str::slug($request->get('title'), '-'), + 'user_id' => $user_id + )); + + $post->save(); + $post->categories()->sync($request->get('categories')); + + return redirect('/admin/posts/create')->with('status', 'The post has been created!'); + } + + /** + * Display the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function show($id) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + $post = Post::whereId($id)->firstOrFail(); + $categories = Category::all(); + $selectedCategories = $post->categories->pluck('id')->toArray(); + return view('backend.posts.edit', compact('post', 'categories', 'selectedCategories')); + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update($id, PostEditFormRequest $request) + { + $post = Post::whereId($id)->firstOrFail(); + $post->title = $request->get('title'); + $post->content = $request->get('content'); + $post->slug = Str::slug($request->get('title'), '-'); + + $post->save(); + $post->categories()->sync($request->get('categories')); + + return redirect(action('Admin\PostsController@edit', $post->id))->with('status', 'The post has been updated!'); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + // + } +} diff --git a/app/Http/Controllers/Admin/RolesController.php b/app/Http/Controllers/Admin/RolesController.php new file mode 100644 index 0000000..c17575b --- /dev/null +++ b/app/Http/Controllers/Admin/RolesController.php @@ -0,0 +1,30 @@ + $request->get('name')]); + + return redirect('/admin/roles/create')->with('status', 'A new role has been created!'); + } + + public function index() + { + $roles = Role::all(); + return view('backend.roles.index', compact('roles')); + } +} diff --git a/app/Http/Controllers/Admin/UsersController.php b/app/Http/Controllers/Admin/UsersController.php new file mode 100644 index 0000000..70b4c90 --- /dev/null +++ b/app/Http/Controllers/Admin/UsersController.php @@ -0,0 +1,43 @@ +firstOrFail(); + $roles = Role::all(); + $selectedRoles = $user->roles()->pluck('name')->toArray(); + return view('backend.users.edit', compact('user', 'roles', 'selectedRoles')); + } + + public function update($id, UserEditFormRequest $request) + { + $user = User::whereId($id)->firstOrFail(); + $user->name = $request->get('name'); + $user->email = $request->get('email'); + $password = $request->get('password'); + if($password != "") { + $user->password = Hash::make($password); + } + $user->save(); + + $user->syncRoles($request->get('role')); + + return redirect(action('Admin\UsersController@edit', $user->id))->with('status', 'The user has been updated!'); + } +} diff --git a/app/Http/Controllers/BlogController.php b/app/Http/Controllers/BlogController.php new file mode 100644 index 0000000..d92cce2 --- /dev/null +++ b/app/Http/Controllers/BlogController.php @@ -0,0 +1,88 @@ +firstOrFail(); + $comments = $post->comments()->get(); + return view('blog.show', compact('post', 'comments')); + } + + /** + * Show the form for editing the specified resource. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function edit($id) + { + // + } + + /** + * Update the specified resource in storage. + * + * @param \Illuminate\Http\Request $request + * @param int $id + * @return \Illuminate\Http\Response + */ + public function update(Request $request, $id) + { + // + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return \Illuminate\Http\Response + */ + public function destroy($id) + { + // + } +} diff --git a/app/Http/Controllers/CommentsController.php b/app/Http/Controllers/CommentsController.php index 539fee8..05279a9 100644 --- a/app/Http/Controllers/CommentsController.php +++ b/app/Http/Controllers/CommentsController.php @@ -12,7 +12,8 @@ public function newComment(CommentFormRequest $request) { $comment = new Comment(array( 'post_id' => $request->get('post_id'), - 'content' => $request->get('content') + 'content' => $request->get('content'), + 'post_type' => $request->get('post_type') )); $comment->save(); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 0e5dff8..a36340a 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -60,5 +60,6 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'manager' => \App\Http\Middleware\Manager::class, ]; } diff --git a/app/Http/Middleware/Manager.php b/app/Http/Middleware/Manager.php new file mode 100644 index 0000000..7881b3f --- /dev/null +++ b/app/Http/Middleware/Manager.php @@ -0,0 +1,24 @@ +hasRole('manager')) + { + return $next($request); + } else { + return redirect('/'); + } + } + } +} \ No newline at end of file diff --git a/app/Http/Requests/CategoryFormRequest.php b/app/Http/Requests/CategoryFormRequest.php new file mode 100644 index 0000000..76441e3 --- /dev/null +++ b/app/Http/Requests/CategoryFormRequest.php @@ -0,0 +1,30 @@ + 'required|min:3', + ]; + } +} \ No newline at end of file diff --git a/app/Http/Requests/PostEditFormRequest.php b/app/Http/Requests/PostEditFormRequest.php new file mode 100644 index 0000000..0a108ee --- /dev/null +++ b/app/Http/Requests/PostEditFormRequest.php @@ -0,0 +1,32 @@ + 'required', + 'content'=> 'required', + 'categories' => 'required', + ]; + } +} diff --git a/app/Http/Requests/PostFormRequest.php b/app/Http/Requests/PostFormRequest.php new file mode 100644 index 0000000..05ab968 --- /dev/null +++ b/app/Http/Requests/PostFormRequest.php @@ -0,0 +1,32 @@ + 'required', + 'content'=> 'required', + 'categories' => 'required', + ]; + } +} diff --git a/app/Http/Requests/RoleFormRequest.php b/app/Http/Requests/RoleFormRequest.php new file mode 100644 index 0000000..2ffda13 --- /dev/null +++ b/app/Http/Requests/RoleFormRequest.php @@ -0,0 +1,30 @@ + 'required', + ]; + } +} diff --git a/app/Http/Requests/UserEditFormRequest.php b/app/Http/Requests/UserEditFormRequest.php new file mode 100644 index 0000000..e156bff --- /dev/null +++ b/app/Http/Requests/UserEditFormRequest.php @@ -0,0 +1,32 @@ + 'required', + 'email'=> 'required', + 'role'=> 'required', + ]; + } +} \ No newline at end of file diff --git a/app/Post.php b/app/Post.php new file mode 100644 index 0000000..c9bad92 --- /dev/null +++ b/app/Post.php @@ -0,0 +1,20 @@ +belongsToMany('App\Category')->withTimestamps(); + } + + public function comments() + { + return $this->morphMany('App\Comment', 'post'); + } +} \ No newline at end of file diff --git a/app/Ticket.php b/app/Ticket.php index cd4eba8..b6aeeb2 100644 --- a/app/Ticket.php +++ b/app/Ticket.php @@ -6,10 +6,10 @@ class Ticket extends Model { - protected $fillable = ['title', 'content', 'slug', 'status', 'user_id']; + protected $guarded = ['id']; public function comments() { - return $this->hasMany('App\Comment', 'post_id'); + return $this->morphMany('App\Comment', 'post'); } -} +} \ No newline at end of file diff --git a/app/User.php b/app/User.php index 2e4d6cf..bb7a097 100644 --- a/app/User.php +++ b/app/User.php @@ -2,14 +2,13 @@ namespace App; -use Illuminate\Auth\MustVerifyEmail; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; -use Illuminate\Contracts\Auth\MustVerifyEmail as MustVerifyEmailContract; +use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { - use Notifiable; + use HasRoles, Notifiable; /** * The attributes that are mass assignable. @@ -28,4 +27,4 @@ class User extends Authenticatable protected $hidden = [ 'password', 'remember_token', ]; -} +} \ No newline at end of file diff --git a/composer.json b/composer.json index 3cb9426..d7ff2d7 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ "php": "^7.1.3", "fideloper/proxy": "^4.0", "laravel/framework": "5.7.*", - "laravel/tinker": "^1.0" + "laravel/tinker": "^1.0", + "spatie/laravel-permission": "^2.21" }, "require-dev": { "beyondcode/laravel-dump-server": "^1.0", diff --git a/composer.lock b/composer.lock index ee1ba84..ffc9637 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "66ca7343889332c2b8ecca11c251430c", + "content-hash": "3364fa4ff081433b09357ebf03647bb6", "packages": [ { "name": "dnoegel/php-xdg-base-dir", @@ -1331,6 +1331,70 @@ ], "time": "2018-07-19T23:38:55+00:00" }, + { + "name": "spatie/laravel-permission", + "version": "2.21.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-permission.git", + "reference": "5415d29d54d15985b8cf56fef30d7514c8608309" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/5415d29d54d15985b8cf56fef30d7514c8608309", + "reference": "5415d29d54d15985b8cf56fef30d7514c8608309", + "shasum": "" + }, + "require": { + "illuminate/auth": "~5.3.0|~5.4.0|~5.5.0|~5.6.0|~5.7.0", + "illuminate/container": "~5.3.0|~5.4.0|~5.5.0|~5.6.0|~5.7.0", + "illuminate/contracts": "~5.3.0|~5.4.0|~5.5.0|~5.6.0|~5.7.0", + "illuminate/database": "~5.4.0|~5.5.0|~5.6.0|~5.7.0", + "php": ">=7.0" + }, + "require-dev": { + "orchestra/testbench": "~3.4.2|~3.5.0|~3.6.0|~3.7.0", + "phpunit/phpunit": "^5.7|6.2|^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Permission\\PermissionServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\Permission\\": "src" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Permission handling for Laravel 5.4 and up", + "homepage": "https://github.com/spatie/laravel-permission", + "keywords": [ + "acl", + "laravel", + "permission", + "security", + "spatie" + ], + "time": "2018-09-29T04:20:17+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.1.3", diff --git a/config/permission.php b/config/permission.php new file mode 100644 index 0000000..934a1a3 --- /dev/null +++ b/config/permission.php @@ -0,0 +1,100 @@ + [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your permissions. Of course, it + * is often just the "Permission" model but you may use whatever you like. + * + * The model you want to use as a Permission model needs to implement the + * `Spatie\Permission\Contracts\Permission` contract. + */ + + 'permission' => Spatie\Permission\Models\Permission::class, + + /* + * When using the "HasRoles" trait from this package, we need to know which + * Eloquent model should be used to retrieve your roles. Of course, it + * is often just the "Role" model but you may use whatever you like. + * + * The model you want to use as a Role model needs to implement the + * `Spatie\Permission\Contracts\Role` contract. + */ + + 'role' => Spatie\Permission\Models\Role::class, + + ], + + 'table_names' => [ + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'roles' => 'roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your permissions. We have chosen a basic + * default value but you may easily change it to any table you like. + */ + + 'permissions' => 'permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_permissions' => 'model_has_permissions', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your models roles. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'model_has_roles' => 'model_has_roles', + + /* + * When using the "HasRoles" trait from this package, we need to know which + * table should be used to retrieve your roles permissions. We have chosen a + * basic default value but you may easily change it to any table you like. + */ + + 'role_has_permissions' => 'role_has_permissions', + ], + + 'column_names' => [ + + /* + * Change this if you want to name the related model primary key other than + * `model_id`. + * + * For example, this would be nice if your primary keys are all UUIDs. In + * that case, name this `model_uuid`. + */ + 'model_morph_key' => 'model_id', + ], + + /* + * By default all permissions will be cached for 24 hours unless a permission or + * role is updated. Then the cache will be flushed immediately. + */ + + 'cache_expiration_time' => 60 * 24, + + /* + * When set to true, the required permission/role names are added to the exception + * message. This could be considered an information leak in some contexts, so + * the default setting is false here for optimum safety. + */ + + 'display_permission_in_exception' => false, +]; diff --git a/database/migrations/2018_10_03_132401_create_permission_tables.php b/database/migrations/2018_10_03_132401_create_permission_tables.php new file mode 100644 index 0000000..6b3b11d --- /dev/null +++ b/database/migrations/2018_10_03_132401_create_permission_tables.php @@ -0,0 +1,100 @@ +increments('id'); + $table->string('name'); + $table->string('guard_name'); + $table->timestamps(); + }); + + Schema::create($tableNames['roles'], function (Blueprint $table) { + $table->increments('id'); + $table->string('name'); + $table->string('guard_name'); + $table->timestamps(); + }); + + Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames) { + $table->unsignedInteger('permission_id'); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type', ]); + + $table->foreign('permission_id') + ->references('id') + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->primary(['permission_id', $columnNames['model_morph_key'], 'model_type'], + 'model_has_permissions_permission_model_type_primary'); + }); + + Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames) { + $table->unsignedInteger('role_id'); + + $table->string('model_type'); + $table->unsignedBigInteger($columnNames['model_morph_key']); + $table->index([$columnNames['model_morph_key'], 'model_type', ]); + + $table->foreign('role_id') + ->references('id') + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary(['role_id', $columnNames['model_morph_key'], 'model_type'], + 'model_has_roles_role_model_type_primary'); + }); + + Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) { + $table->unsignedInteger('permission_id'); + $table->unsignedInteger('role_id'); + + $table->foreign('permission_id') + ->references('id') + ->on($tableNames['permissions']) + ->onDelete('cascade'); + + $table->foreign('role_id') + ->references('id') + ->on($tableNames['roles']) + ->onDelete('cascade'); + + $table->primary(['permission_id', 'role_id']); + + app('cache')->forget('spatie.permission.cache'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $tableNames = config('permission.table_names'); + + Schema::drop($tableNames['role_has_permissions']); + Schema::drop($tableNames['model_has_roles']); + Schema::drop($tableNames['model_has_permissions']); + Schema::drop($tableNames['roles']); + Schema::drop($tableNames['permissions']); + } +} diff --git a/database/migrations/2018_10_03_182812_create_posts_table.php b/database/migrations/2018_10_03_182812_create_posts_table.php new file mode 100644 index 0000000..5d4d063 --- /dev/null +++ b/database/migrations/2018_10_03_182812_create_posts_table.php @@ -0,0 +1,36 @@ +increments('id'); + $table->string('title', 255); + $table->text('content'); + $table->string('slug')->nullable(); + $table->tinyInteger('status')->default(1); + $table->integer('user_id')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('posts'); + } +} diff --git a/database/migrations/2018_10_03_183309_create_categories_table.php b/database/migrations/2018_10_03_183309_create_categories_table.php new file mode 100644 index 0000000..351b61d --- /dev/null +++ b/database/migrations/2018_10_03_183309_create_categories_table.php @@ -0,0 +1,32 @@ +increments('id'); + $table->string('name', 255); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('categories'); + } +} diff --git a/database/migrations/2018_10_03_183424_create_category_post_table.php b/database/migrations/2018_10_03_183424_create_category_post_table.php new file mode 100644 index 0000000..c8e2f80 --- /dev/null +++ b/database/migrations/2018_10_03_183424_create_category_post_table.php @@ -0,0 +1,43 @@ +increments('id')->unsigned(); + $table->integer('post_id')->unsigned()->index(); + $table->integer('category_id')->unsigned()->index(); + $table->timestamps(); + + $table->foreign('category_id') + ->references('id')->on('categories') + ->onUpdate('cascade') + ->onDelete('cascade'); + + $table->foreign('post_id') + ->references('id')->on('posts') + ->onUpdate('cascade') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('category_post'); + } +} diff --git a/database/migrations/2018_10_03_192058_add_post_type_to_comments_table.php b/database/migrations/2018_10_03_192058_add_post_type_to_comments_table.php new file mode 100644 index 0000000..df6d356 --- /dev/null +++ b/database/migrations/2018_10_03_192058_add_post_type_to_comments_table.php @@ -0,0 +1,36 @@ +string('post_type')->nullable(); + }); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('comments', function (Blueprint $table) { + $table->dropColumn('post_type'); + }); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 91cb6d1..19fbf0f 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -11,6 +11,6 @@ class DatabaseSeeder extends Seeder */ public function run() { - // $this->call(UsersTableSeeder::class); + $this->call(UserTableSeeder::class); } } diff --git a/database/seeds/UserTableSeeder.php b/database/seeds/UserTableSeeder.php new file mode 100644 index 0000000..02eda2c --- /dev/null +++ b/database/seeds/UserTableSeeder.php @@ -0,0 +1,39 @@ +insert([ + [ + 'name' => 'Nathan', + 'email' => str_random(12).'@email.com', + 'password' => bcrypt('yourPassword'), + 'created_at' => new DateTime, + 'updated_at' => new DateTime, + ], + [ + 'name' => 'David', + 'email' => str_random(12).'@email.com', + 'password' => bcrypt('yourPassword'), + 'created_at' => new DateTime, + 'updated_at' => new DateTime, + + ], + [ + 'name' => 'Lisa', + 'email' => str_random(12).'@email.com', + 'password' => bcrypt('yourPassword'), + 'created_at' => new DateTime, + 'updated_at' => new DateTime, + ], + ]); + } +} diff --git a/resources/lang/en/main.php b/resources/lang/en/main.php new file mode 100644 index 0000000..cdf534a --- /dev/null +++ b/resources/lang/en/main.php @@ -0,0 +1,7 @@ + 'Fastest way to learn Laravel', + +]; \ No newline at end of file diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 0000000..7dfec5b --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,49 @@ +@extends('master') +@section('name', 'Login') + +@section('content') +
There is no category.
+ @else +{{ $category->name }} | +
There is no post.
+ @else +ID | +Title | +Slug | +Created At | +Updated At | + +
---|---|---|---|---|
{{ $post->id }} | ++ {{ $post->title }} + | +{{ $post->slug }} | +{{ $post->created_at }} | +{{ $post->updated_at }} | +
There is no role.
+ @else +Name | +
---|
{{ $role->name }} | +
There is no user.
+ @else +ID | +Name | +Joined at | + +|
---|---|---|---|
{{ $user->id }} | ++ {{ $user->name }} + | +{{ $user->email }} | +{{ $user->created_at }} | +
There is no post.
+ @else + @foreach ($posts as $post) +{{ $post->content }}
+