Showing
19 changed files
with
251 additions
and
22 deletions
| ... | @@ -7,19 +7,23 @@ use Illuminate\Http\Request; | ... | @@ -7,19 +7,23 @@ use Illuminate\Http\Request; |
| 7 | use Illuminate\Support\Str; | 7 | use Illuminate\Support\Str; |
| 8 | use Oxbow\Http\Requests; | 8 | use Oxbow\Http\Requests; |
| 9 | use Oxbow\Repos\BookRepo; | 9 | use Oxbow\Repos\BookRepo; |
| 10 | +use Oxbow\Repos\PageRepo; | ||
| 10 | 11 | ||
| 11 | class BookController extends Controller | 12 | class BookController extends Controller |
| 12 | { | 13 | { |
| 13 | 14 | ||
| 14 | protected $bookRepo; | 15 | protected $bookRepo; |
| 16 | + protected $pageRepo; | ||
| 15 | 17 | ||
| 16 | /** | 18 | /** |
| 17 | * BookController constructor. | 19 | * BookController constructor. |
| 18 | * @param BookRepo $bookRepo | 20 | * @param BookRepo $bookRepo |
| 21 | + * @param PageRepo $pageRepo | ||
| 19 | */ | 22 | */ |
| 20 | - public function __construct(BookRepo $bookRepo) | 23 | + public function __construct(BookRepo $bookRepo, PageRepo $pageRepo) |
| 21 | { | 24 | { |
| 22 | $this->bookRepo = $bookRepo; | 25 | $this->bookRepo = $bookRepo; |
| 26 | + $this->pageRepo = $pageRepo; | ||
| 23 | } | 27 | } |
| 24 | 28 | ||
| 25 | /** | 29 | /** |
| ... | @@ -58,7 +62,7 @@ class BookController extends Controller | ... | @@ -58,7 +62,7 @@ class BookController extends Controller |
| 58 | $book = $this->bookRepo->newFromInput($request->all()); | 62 | $book = $this->bookRepo->newFromInput($request->all()); |
| 59 | $slug = Str::slug($book->name); | 63 | $slug = Str::slug($book->name); |
| 60 | while($this->bookRepo->countBySlug($slug) > 0) { | 64 | while($this->bookRepo->countBySlug($slug) > 0) { |
| 61 | - $slug += '1'; | 65 | + $slug .= '1'; |
| 62 | } | 66 | } |
| 63 | $book->slug = $slug; | 67 | $book->slug = $slug; |
| 64 | $book->save(); | 68 | $book->save(); | ... | ... |
| ... | @@ -4,11 +4,29 @@ namespace Oxbow\Http\Controllers; | ... | @@ -4,11 +4,29 @@ namespace Oxbow\Http\Controllers; |
| 4 | 4 | ||
| 5 | use Illuminate\Http\Request; | 5 | use Illuminate\Http\Request; |
| 6 | 6 | ||
| 7 | +use Illuminate\Support\Str; | ||
| 7 | use Oxbow\Http\Requests; | 8 | use Oxbow\Http\Requests; |
| 8 | -use Oxbow\Http\Controllers\Controller; | 9 | +use Oxbow\Repos\BookRepo; |
| 10 | +use Oxbow\Repos\PageRepo; | ||
| 9 | 11 | ||
| 10 | class PageController extends Controller | 12 | class PageController extends Controller |
| 11 | { | 13 | { |
| 14 | + | ||
| 15 | + protected $pageRepo; | ||
| 16 | + protected $bookRepo; | ||
| 17 | + | ||
| 18 | + /** | ||
| 19 | + * PageController constructor. | ||
| 20 | + * @param $pageRepo | ||
| 21 | + * @param $bookRepo | ||
| 22 | + */ | ||
| 23 | + public function __construct(PageRepo $pageRepo, BookRepo $bookRepo) | ||
| 24 | + { | ||
| 25 | + $this->pageRepo = $pageRepo; | ||
| 26 | + $this->bookRepo = $bookRepo; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + | ||
| 12 | /** | 30 | /** |
| 13 | * Display a listing of the resource. | 31 | * Display a listing of the resource. |
| 14 | * | 32 | * |
| ... | @@ -22,56 +40,88 @@ class PageController extends Controller | ... | @@ -22,56 +40,88 @@ class PageController extends Controller |
| 22 | /** | 40 | /** |
| 23 | * Show the form for creating a new resource. | 41 | * Show the form for creating a new resource. |
| 24 | * | 42 | * |
| 43 | + * @param $bookSlug | ||
| 25 | * @return Response | 44 | * @return Response |
| 26 | */ | 45 | */ |
| 27 | - public function create() | 46 | + public function create($bookSlug) |
| 28 | { | 47 | { |
| 29 | - // | 48 | + $book = $this->bookRepo->getBySlug($bookSlug); |
| 49 | + return view('pages/create', ['book' => $book]); | ||
| 30 | } | 50 | } |
| 31 | 51 | ||
| 32 | /** | 52 | /** |
| 33 | * Store a newly created resource in storage. | 53 | * Store a newly created resource in storage. |
| 34 | * | 54 | * |
| 35 | - * @param Request $request | 55 | + * @param Request $request |
| 56 | + * @param $bookSlug | ||
| 36 | * @return Response | 57 | * @return Response |
| 37 | */ | 58 | */ |
| 38 | - public function store(Request $request) | 59 | + public function store(Request $request, $bookSlug) |
| 39 | { | 60 | { |
| 40 | - // | 61 | + $this->validate($request, [ |
| 62 | + 'name' => 'required|string|max:255', | ||
| 63 | + 'html' => 'required|string', | ||
| 64 | + 'priority' => 'integer' | ||
| 65 | + ]); | ||
| 66 | + $book = $this->bookRepo->getBySlug($bookSlug); | ||
| 67 | + $page = $this->pageRepo->newFromInput($request->all()); | ||
| 68 | + $slug = Str::slug($page->name); | ||
| 69 | + while($this->pageRepo->countBySlug($slug, $book->id) > 0) { | ||
| 70 | + $slug .= '1'; | ||
| 71 | + } | ||
| 72 | + $page->slug =$slug; | ||
| 73 | + $page->book_id = $book->id; | ||
| 74 | + $page->text = strip_tags($page->html); | ||
| 75 | + $page->save(); | ||
| 76 | + return redirect($page->getUrl()); | ||
| 41 | } | 77 | } |
| 42 | 78 | ||
| 43 | /** | 79 | /** |
| 44 | * Display the specified resource. | 80 | * Display the specified resource. |
| 45 | * | 81 | * |
| 46 | - * @param int $id | 82 | + * @param $bookSlug |
| 83 | + * @param $pageSlug | ||
| 47 | * @return Response | 84 | * @return Response |
| 48 | */ | 85 | */ |
| 49 | - public function show($id) | 86 | + public function show($bookSlug, $pageSlug) |
| 50 | { | 87 | { |
| 51 | - // | 88 | + $page = $this->pageRepo->getBySlug($pageSlug); |
| 89 | + return view('pages/show', ['page' => $page]); | ||
| 52 | } | 90 | } |
| 53 | 91 | ||
| 54 | /** | 92 | /** |
| 55 | * Show the form for editing the specified resource. | 93 | * Show the form for editing the specified resource. |
| 56 | * | 94 | * |
| 57 | - * @param int $id | 95 | + * @param $bookSlug |
| 96 | + * @param $pageSlug | ||
| 58 | * @return Response | 97 | * @return Response |
| 59 | */ | 98 | */ |
| 60 | - public function edit($id) | 99 | + public function edit($bookSlug, $pageSlug) |
| 61 | { | 100 | { |
| 62 | - // | 101 | + $page = $this->pageRepo->getBySlug($pageSlug); |
| 102 | + return view('pages/edit', ['page' => $page]); | ||
| 63 | } | 103 | } |
| 64 | 104 | ||
| 65 | /** | 105 | /** |
| 66 | * Update the specified resource in storage. | 106 | * Update the specified resource in storage. |
| 67 | * | 107 | * |
| 68 | - * @param Request $request | 108 | + * @param Request $request |
| 69 | - * @param int $id | 109 | + * @param $bookSlug |
| 110 | + * @param $pageSlug | ||
| 70 | * @return Response | 111 | * @return Response |
| 71 | */ | 112 | */ |
| 72 | - public function update(Request $request, $id) | 113 | + public function update(Request $request, $bookSlug, $pageSlug) |
| 73 | { | 114 | { |
| 74 | - // | 115 | + $page = $this->pageRepo->getBySlug($pageSlug); |
| 116 | + $book = $this->bookRepo->getBySlug($bookSlug); | ||
| 117 | + $page->fill($request->all()); | ||
| 118 | + $slug = Str::slug($page->name); | ||
| 119 | + while($this->pageRepo->countBySlug($slug, $book->id) > 0 && $slug != $pageSlug) { | ||
| 120 | + $slug .= '1'; | ||
| 121 | + } | ||
| 122 | + $page->text = strip_tags($page->html); | ||
| 123 | + $page->save(); | ||
| 124 | + return redirect($page->getUrl()); | ||
| 75 | } | 125 | } |
| 76 | 126 | ||
| 77 | /** | 127 | /** | ... | ... |
| ... | @@ -21,6 +21,12 @@ Route::group(['prefix' => 'books'], function() { | ... | @@ -21,6 +21,12 @@ Route::group(['prefix' => 'books'], function() { |
| 21 | Route::put('/{slug}', 'BookController@update'); | 21 | Route::put('/{slug}', 'BookController@update'); |
| 22 | Route::delete('/{id}/destroy', 'BookController@destroy'); | 22 | Route::delete('/{id}/destroy', 'BookController@destroy'); |
| 23 | Route::get('/{slug}', 'BookController@show'); | 23 | Route::get('/{slug}', 'BookController@show'); |
| 24 | + | ||
| 25 | + Route::get('/{bookSlug}/page/create', 'PageController@create'); | ||
| 26 | + Route::post('/{bookSlug}/page', 'PageController@store'); | ||
| 27 | + Route::get('/{bookSlug}/{pageSlug}', 'PageController@show'); | ||
| 28 | + Route::get('/{bookSlug}/{pageSlug}/edit', 'PageController@edit'); | ||
| 29 | + Route::put('/{bookSlug}/{pageSlug}', 'PageController@update'); | ||
| 24 | }); | 30 | }); |
| 25 | 31 | ||
| 26 | Route::get('/', function () { | 32 | Route::get('/', function () { | ... | ... |
| ... | @@ -6,5 +6,15 @@ use Illuminate\Database\Eloquent\Model; | ... | @@ -6,5 +6,15 @@ use Illuminate\Database\Eloquent\Model; |
| 6 | 6 | ||
| 7 | class Page extends Model | 7 | class Page extends Model |
| 8 | { | 8 | { |
| 9 | - // | 9 | + protected $fillable = ['name', 'html', 'priority']; |
| 10 | + | ||
| 11 | + public function book() | ||
| 12 | + { | ||
| 13 | + return $this->belongsTo('Oxbow\Book'); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + public function getUrl() | ||
| 17 | + { | ||
| 18 | + return '/books/' . $this->book->slug . '/' . $this->slug; | ||
| 19 | + } | ||
| 10 | } | 20 | } | ... | ... |
| ... | @@ -6,14 +6,17 @@ class BookRepo | ... | @@ -6,14 +6,17 @@ class BookRepo |
| 6 | { | 6 | { |
| 7 | 7 | ||
| 8 | protected $book; | 8 | protected $book; |
| 9 | + protected $pageRepo; | ||
| 9 | 10 | ||
| 10 | /** | 11 | /** |
| 11 | * BookRepo constructor. | 12 | * BookRepo constructor. |
| 12 | - * @param $book | 13 | + * @param Book $book |
| 14 | + * @param PageRepo $pageRepo | ||
| 13 | */ | 15 | */ |
| 14 | - public function __construct(Book $book) | 16 | + public function __construct(Book $book, PageRepo $pageRepo) |
| 15 | { | 17 | { |
| 16 | $this->book = $book; | 18 | $this->book = $book; |
| 19 | + $this->pageRepo = $pageRepo; | ||
| 17 | } | 20 | } |
| 18 | 21 | ||
| 19 | public function getById($id) | 22 | public function getById($id) |
| ... | @@ -44,6 +47,9 @@ class BookRepo | ... | @@ -44,6 +47,9 @@ class BookRepo |
| 44 | public function destroyById($id) | 47 | public function destroyById($id) |
| 45 | { | 48 | { |
| 46 | $book = $this->getById($id); | 49 | $book = $this->getById($id); |
| 50 | + foreach($book->pages as $page) { | ||
| 51 | + $this->pageRepo->destroyById($page->id); | ||
| 52 | + } | ||
| 47 | $book->delete(); | 53 | $book->delete(); |
| 48 | } | 54 | } |
| 49 | 55 | ... | ... |
app/Repos/PageRepo.php
0 → 100644
| 1 | +<?php namespace Oxbow\Repos; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +use Illuminate\Support\Str; | ||
| 5 | +use Oxbow\Page; | ||
| 6 | + | ||
| 7 | +class PageRepo | ||
| 8 | +{ | ||
| 9 | + protected $page; | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * PageRepo constructor. | ||
| 13 | + * @param $page | ||
| 14 | + */ | ||
| 15 | + public function __construct(Page $page) | ||
| 16 | + { | ||
| 17 | + $this->page = $page; | ||
| 18 | + } | ||
| 19 | + | ||
| 20 | + public function getById($id) | ||
| 21 | + { | ||
| 22 | + return $this->page->findOrFail($id); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + public function getAll() | ||
| 26 | + { | ||
| 27 | + return $this->page->all(); | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + public function getBySlug($slug) | ||
| 31 | + { | ||
| 32 | + return $this->page->where('slug', '=', $slug)->first(); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + public function newFromInput($input) | ||
| 36 | + { | ||
| 37 | + $page = $this->page->fill($input); | ||
| 38 | + return $page; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + public function countBySlug($slug, $bookId) | ||
| 42 | + { | ||
| 43 | + return $this->page->where('slug', '=', $slug)->where('book_id', '=', $bookId)->count(); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public function destroyById($id) | ||
| 47 | + { | ||
| 48 | + $page = $this->getById($id); | ||
| 49 | + $page->delete(); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -14,6 +14,13 @@ class CreatePagesTable extends Migration | ... | @@ -14,6 +14,13 @@ class CreatePagesTable extends Migration |
| 14 | { | 14 | { |
| 15 | Schema::create('pages', function (Blueprint $table) { | 15 | Schema::create('pages', function (Blueprint $table) { |
| 16 | $table->increments('id'); | 16 | $table->increments('id'); |
| 17 | + $table->integer('book_id'); | ||
| 18 | + $table->integer('page_id'); | ||
| 19 | + $table->string('name'); | ||
| 20 | + $table->string('slug')->indexed(); | ||
| 21 | + $table->longText('html'); | ||
| 22 | + $table->longText('text'); | ||
| 23 | + $table->integer('priority'); | ||
| 17 | $table->timestamps(); | 24 | $table->timestamps(); |
| 18 | }); | 25 | }); |
| 19 | } | 26 | } | ... | ... |
| ... | @@ -941,4 +941,9 @@ header .menu { | ... | @@ -941,4 +941,9 @@ header .menu { |
| 941 | display: inline-block; | 941 | display: inline-block; |
| 942 | margin-left: 16px; } | 942 | margin-left: 16px; } |
| 943 | 943 | ||
| 944 | +.page-title input { | ||
| 945 | + display: block; | ||
| 946 | + width: 100%; | ||
| 947 | + font-size: 1.4em; } | ||
| 948 | + | ||
| 944 | /*# sourceMappingURL=app.css.map */ | 949 | /*# sourceMappingURL=app.css.map */ |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
This diff is collapsed.
Click to expand it.
| ... | @@ -19,4 +19,10 @@ header .menu { | ... | @@ -19,4 +19,10 @@ header .menu { |
| 19 | display: inline-block; | 19 | display: inline-block; |
| 20 | margin-left: $-m; | 20 | margin-left: $-m; |
| 21 | } | 21 | } |
| 22 | +} | ||
| 23 | + | ||
| 24 | +.page-title input { | ||
| 25 | + display: block; | ||
| 26 | + width: 100%; | ||
| 27 | + font-size: 1.4em; | ||
| 22 | } | 28 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -5,7 +5,9 @@ | ... | @@ -5,7 +5,9 @@ |
| 5 | <meta name="viewport" content="width=device-width"> | 5 | <meta name="viewport" content="width=device-width"> |
| 6 | <link rel="stylesheet" href="/css/app.css"> | 6 | <link rel="stylesheet" href="/css/app.css"> |
| 7 | <link href='http://fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'> | 7 | <link href='http://fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'> |
| 8 | + <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> | ||
| 8 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> | 9 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> |
| 10 | + @yield('head') | ||
| 9 | </head> | 11 | </head> |
| 10 | <body> | 12 | <body> |
| 11 | 13 | ... | ... |
| ... | @@ -4,4 +4,14 @@ | ... | @@ -4,4 +4,14 @@ |
| 4 | 4 | ||
| 5 | <h2>{{$book->name}}</h2> | 5 | <h2>{{$book->name}}</h2> |
| 6 | <p class="text-muted">{{$book->description}}</p> | 6 | <p class="text-muted">{{$book->description}}</p> |
| 7 | + <a href="{{$book->getUrl() . '/page/create'}}">+ New Page</a> | ||
| 8 | + | ||
| 9 | + <h4>Pages:</h4> | ||
| 10 | + @if(count($book->pages) > 0) | ||
| 11 | + @foreach($book->pages as $page) | ||
| 12 | + <a href="{{$page->getUrl()}}">{{$page->name}}</a><br> | ||
| 13 | + @endforeach | ||
| 14 | + @else | ||
| 15 | + <p class="text-muted">This book has no pages</p> | ||
| 16 | + @endif | ||
| 7 | @stop | 17 | @stop |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | <input type="text" id="{{ $name }}" name="{{ $name }}" | 1 | <input type="text" id="{{ $name }}" name="{{ $name }}" |
| 2 | @if($errors->has($name)) class="neg" @endif | 2 | @if($errors->has($name)) class="neg" @endif |
| 3 | + @if(isset($placeholder)) placeholder="{{$placeholder}}" @endif | ||
| 3 | @if(isset($model) || old($name)) value="{{ old($name) ? old($name) : $model->$name}}" @endif> | 4 | @if(isset($model) || old($name)) value="{{ old($name) ? old($name) : $model->$name}}" @endif> |
| 4 | @if($errors->has($name)) | 5 | @if($errors->has($name)) |
| 5 | <div class="text-neg text-small">{{ $errors->first($name) }}</div> | 6 | <div class="text-neg text-small">{{ $errors->first($name) }}</div> | ... | ... |
resources/views/pages/create.blade.php
0 → 100644
| 1 | +@extends('base') | ||
| 2 | + | ||
| 3 | +@section('head') | ||
| 4 | + <link rel="stylesheet" href="/plugins/css/froala_editor.min.css"> | ||
| 5 | + <link rel="stylesheet" href="/plugins/css/froala_style.min.css"> | ||
| 6 | + <script src="/plugins/js/froala_editor.min.js"></script> | ||
| 7 | +@stop | ||
| 8 | + | ||
| 9 | +@section('content') | ||
| 10 | + <form action="{{$book->getUrl() . '/page'}}" method="POST"> | ||
| 11 | + @include('pages/form') | ||
| 12 | + </form> | ||
| 13 | + | ||
| 14 | + <script> | ||
| 15 | + $(function() { | ||
| 16 | + $('#html').editable({inlineMode: false}); | ||
| 17 | + }); | ||
| 18 | + </script> | ||
| 19 | +@stop | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
resources/views/pages/edit.blade.php
0 → 100644
| 1 | +@extends('base') | ||
| 2 | + | ||
| 3 | +@section('head') | ||
| 4 | + <link rel="stylesheet" href="/plugins/css/froala_editor.min.css"> | ||
| 5 | + <link rel="stylesheet" href="/plugins/css/froala_style.min.css"> | ||
| 6 | + <script src="/plugins/js/froala_editor.min.js"></script> | ||
| 7 | +@stop | ||
| 8 | + | ||
| 9 | +@section('content') | ||
| 10 | + <form action="{{$page->getUrl()}}" method="POST"> | ||
| 11 | + <input type="hidden" name="_method" value="PUT"> | ||
| 12 | + @include('pages/form', ['model' => $page]) | ||
| 13 | + </form> | ||
| 14 | + | ||
| 15 | + <script> | ||
| 16 | + $(function() { | ||
| 17 | + $('#html').editable({inlineMode: false}); | ||
| 18 | + }); | ||
| 19 | + </script> | ||
| 20 | +@stop | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
resources/views/pages/form.blade.php
0 → 100644
| 1 | +{{ csrf_field() }} | ||
| 2 | +<div class="page-title row"> | ||
| 3 | + <div class="col-md-10"> | ||
| 4 | + @include('form/text', ['name' => 'name', 'placeholder' => 'Enter Page Title']) | ||
| 5 | + </div> | ||
| 6 | + <div class="col-md-2"> | ||
| 7 | + <button type="submit" class="button pos">Save</button> | ||
| 8 | + </div> | ||
| 9 | +</div> | ||
| 10 | +<div class="edit-area"> | ||
| 11 | + @include('form/textarea', ['name' => 'html']) | ||
| 12 | +</div> | ||
| 13 | + |
resources/views/pages/show.blade.php
0 → 100644
-
Please register or sign in to post a comment