]> BookStack Code Mirror - bookstack/commitdiff
Started working on chapters
authorDan Brown <redacted>
Mon, 27 Jul 2015 19:17:08 +0000 (20:17 +0100)
committerDan Brown <redacted>
Mon, 27 Jul 2015 19:17:08 +0000 (20:17 +0100)
17 files changed:
app/Book.php
app/Chapter.php [new file with mode: 0644]
app/Http/Controllers/BookController.php
app/Http/Controllers/ChapterController.php [new file with mode: 0644]
app/Http/routes.php
app/Page.php
app/Repos/ChapterRepo.php [new file with mode: 0644]
app/Repos/PageRepo.php
database/migrations/2015_07_12_190027_create_pages_table.php
database/migrations/2015_07_27_172342_create_chapters_table.php [new file with mode: 0644]
gulpfile.js
readme.md
resources/assets/sass/styles.scss
resources/views/base.blade.php
resources/views/books/show.blade.php
resources/views/chapters/create.blade.php [new file with mode: 0644]
resources/views/chapters/form.blade.php [new file with mode: 0644]

index cdd512c97475562a7c7b8caa45cdd020c02a22f1..cdad27879962c221e8ce247a5f14ee8fa223a7d2 100644 (file)
@@ -24,4 +24,17 @@ class Book extends Model
         return $this->hasMany('Oxbow\Page');
     }
 
+    public function chapters()
+    {
+        return $this->hasMany('Oxbow\Chapter');
+    }
+
+    public function children()
+    {
+        $pages = $this->pages()->get();
+        $chapters = $this->chapters()->get();
+        $children = $pages->merge($chapters);
+        return $children->sortBy('priority');
+    }
+
 }
diff --git a/app/Chapter.php b/app/Chapter.php
new file mode 100644 (file)
index 0000000..f4e9dce
--- /dev/null
@@ -0,0 +1,25 @@
+<?php namespace Oxbow;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Chapter extends Model
+{
+
+    protected $fillable = ['name', 'description', 'priority', 'book_id'];
+
+    public function book()
+    {
+        return $this->belongsTo('Oxbow\Book');
+    }
+
+    public function children()
+    {
+        return $this->hasMany('Oxbow\Page')->orderBy('priority', 'ASC');
+    }
+
+    public function getUrl()
+    {
+        return '/books/' . $this->book->slug . '/chapter/' . $this->slug;
+    }
+
+}
index 03954fc51737a0a955508372d2fcd3f14a51bf5b..fcb8c77528fdd8b28684fb2fa9a74dc6aafe09df 100644 (file)
@@ -79,7 +79,6 @@ class BookController extends Controller
     {
         $book = $this->bookRepo->getBySlug($slug);
         $pageTree = $this->pageRepo->getTreeByBookId($book->id);
-       // dd($pageTree);
         return view('books/show', ['book' => $book, 'pageTree' => $pageTree]);
     }
 
diff --git a/app/Http/Controllers/ChapterController.php b/app/Http/Controllers/ChapterController.php
new file mode 100644 (file)
index 0000000..e7d1f17
--- /dev/null
@@ -0,0 +1,116 @@
+<?php
+
+namespace Oxbow\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+use Oxbow\Http\Requests;
+use Oxbow\Http\Controllers\Controller;
+use Oxbow\Repos\BookRepo;
+use Oxbow\Repos\ChapterRepo;
+
+class ChapterController extends Controller
+{
+
+    protected $bookRepo;
+    protected $chapterRepo;
+
+    /**
+     * ChapterController constructor.
+     * @param $bookRepo
+     * @param $chapterRepo
+     */
+    public function __construct(BookRepo $bookRepo,ChapterRepo $chapterRepo)
+    {
+        $this->bookRepo = $bookRepo;
+        $this->chapterRepo = $chapterRepo;
+    }
+
+
+    /**
+     * Display a listing of the resource.
+     *
+     * @return Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Show the form for creating a new resource.
+     *
+     * @param $bookSlug
+     * @return Response
+     */
+    public function create($bookSlug)
+    {
+        $book = $this->bookRepo->getBySlug($bookSlug);
+        return view('chapters/create', ['book' => $book]);
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param $bookSlug
+     * @param  Request $request
+     * @return Response
+     */
+    public function store($bookSlug, Request $request)
+    {
+        $this->validate($request, [
+            'name' => 'required|string|max:255'
+        ]);
+
+        $book = $this->bookRepo->getBySlug($bookSlug);
+        $chapter = $this->chapterRepo->newFromInput($request->all());
+        $chapter->slug = $this->chapterRepo->findSuitableSlug($chapter->name, $book->id);
+        $book->chapters()->save($chapter);
+        return redirect($book->getUrl());
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  int  $id
+     * @return Response
+     */
+    public function show($id)
+    {
+        //
+    }
+
+    /**
+     * Show the form for editing the specified resource.
+     *
+     * @param  int  $id
+     * @return Response
+     */
+    public function edit($id)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  Request  $request
+     * @param  int  $id
+     * @return Response
+     */
+    public function update(Request $request, $id)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  int  $id
+     * @return Response
+     */
+    public function destroy($id)
+    {
+        //
+    }
+}
index 0dd0226a2bed5a140039f4483ce4a34695be8d52..8204599f5c45abb1f63c03735f5679fd13116c70 100644 (file)
@@ -26,10 +26,14 @@ Route::group(['prefix' => 'books'], function() {
     Route::post('/{bookSlug}/page', 'PageController@store');
     Route::get('/{bookSlug}/sort', 'PageController@sortPages');
     Route::put('/{bookSlug}/sort', 'PageController@savePageSort');
-    Route::get('/{bookSlug}/{pageSlug}', 'PageController@show');
-    Route::get('/{bookSlug}/{pageSlug}/create', 'PageController@create');
-    Route::get('/{bookSlug}/{pageSlug}/edit', 'PageController@edit');
-    Route::put('/{bookSlug}/{pageSlug}', 'PageController@update');
+    Route::get('/{bookSlug}/page/{pageSlug}', 'PageController@show');
+    Route::get('/{bookSlug}/page/{pageSlug}/create', 'PageController@create');
+    Route::get('/{bookSlug}/page/{pageSlug}/edit', 'PageController@edit');
+    Route::put('/{bookSlug}/page/{pageSlug}', 'PageController@update');
+
+    Route::get('/{bookSlug}/chapter/create', 'ChapterController@create');
+    Route::post('/{bookSlug}/chapter/create', 'ChapterController@store');
+
 });
 
 Route::post('/upload/image', 'ImageController@upload');
index 819b14024671c2f1158f7b0c0d9f3bd678823106..53cfc9ada9894cfb3ffcdf6ba6da056cf6e91f3e 100644 (file)
@@ -34,7 +34,7 @@ class Page extends Model
 
     public function getUrl()
     {
-        return '/books/' . $this->book->slug . '/' . $this->slug;
+        return '/books/' . $this->book->slug . '/page/' . $this->slug;
     }
 
 }
diff --git a/app/Repos/ChapterRepo.php b/app/Repos/ChapterRepo.php
new file mode 100644 (file)
index 0000000..7cf1db2
--- /dev/null
@@ -0,0 +1,65 @@
+<?php namespace Oxbow\Repos;
+
+
+use Illuminate\Support\Str;
+use Oxbow\Chapter;
+
+class ChapterRepo
+{
+
+    protected $chapter;
+
+    /**
+     * ChapterRepo constructor.
+     * @param $chapter
+     */
+    public function __construct(Chapter $chapter)
+    {
+        $this->chapter = $chapter;
+    }
+
+    public function getById($id)
+    {
+        return $this->chapter->findOrFail($id);
+    }
+
+    public function getAll()
+    {
+        return $this->chapter->all();
+    }
+
+    public function getBySlug($slug, $bookId)
+    {
+        return $this->chapter->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
+    }
+
+    public function newFromInput($input)
+    {
+        return $this->chapter->fill($input);
+    }
+
+    public function destroyById($id)
+    {
+        $page = $this->getById($id);
+        $page->delete();
+    }
+
+    public function doesSlugExist($slug, $bookId, $currentId = false)
+    {
+        $query = $this->chapter->where('slug', '=', $slug)->where('book_id', '=', $bookId);
+        if($currentId) {
+            $query = $query->where('id', '!=', $currentId);
+        }
+        return $query->count() > 0;
+    }
+
+    public function findSuitableSlug($name, $bookId)
+    {
+        $slug = Str::slug($name);
+        while($this->doesSlugExist($slug, $bookId)) {
+            $slug .= '-' . substr(md5(rand(1, 500)), 0, 3);
+        }
+        return $slug;
+    }
+
+}
\ No newline at end of file
index 0e2f136be18ad6dd40f6f9e01ab60f6b28dc2746..897c9ff7707a4c9026465e2f3bff868d8a8d7b92 100644 (file)
@@ -114,7 +114,7 @@ class PageRepo
      */
     private function getTopLevelPages($bookId)
     {
-        return $this->page->where('book_id', '=', $bookId)->where('page_id', '=', 0)->orderBy('priority')->get();
+        return $this->page->where('book_id', '=', $bookId)->where('chapter_id', '=', 0)->orderBy('priority')->get();
     }
 
     /**
index d42166db343513582d43ff078aa9db48c97a615e..b7b1dc1308387ff441e5bd577e51747b21f45a37 100644 (file)
@@ -15,7 +15,7 @@ class CreatePagesTable extends Migration
         Schema::create('pages', function (Blueprint $table) {
             $table->increments('id');
             $table->integer('book_id');
-            $table->integer('page_id');
+            $table->integer('chapter_id');
             $table->string('name');
             $table->string('slug')->indexed();
             $table->longText('html');
diff --git a/database/migrations/2015_07_27_172342_create_chapters_table.php b/database/migrations/2015_07_27_172342_create_chapters_table.php
new file mode 100644 (file)
index 0000000..5467e63
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateChaptersTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('chapters', function (Blueprint $table) {
+            $table->increments('id');
+            $table->integer('book_id');
+            $table->string('slug')->indexed();
+            $table->text('name');
+            $table->text('description');
+            $table->integer('priority');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::drop('chapters');
+    }
+}
index 1da6e0497775407c65a81c0f9758c18b390ed6f4..f5d59ff8ece161a814f575dabc02dbc51a0c2eb4 100644 (file)
@@ -1,5 +1,5 @@
 var elixir = require('laravel-elixir');
-require('laravel-elixir-livereload');
+//require('laravel-elixir-livereload');
 
 /*
  |--------------------------------------------------------------------------
@@ -13,5 +13,5 @@ require('laravel-elixir-livereload');
  */
 
 elixir(function(mix) {
-    mix.sass('styles.scss').livereload();
+    mix.sass('styles.scss');//.livereload();
 });
index f67a6cf7cef0b6b3964de3d43ec571b88acba23e..7d9210790536e3b714e3873e64a13e78f39cff97 100644 (file)
--- a/readme.md
+++ b/readme.md
@@ -1,27 +1,3 @@
-## Laravel PHP Framework
+# BookStack
 
-[![Build Status](https://travis-ci.org/laravel/framework.svg)](https://travis-ci.org/laravel/framework)
-[![Total Downloads](https://poser.pugx.org/laravel/framework/d/total.svg)](https://packagist.org/packages/laravel/framework)
-[![Latest Stable Version](https://poser.pugx.org/laravel/framework/v/stable.svg)](https://packagist.org/packages/laravel/framework)
-[![Latest Unstable Version](https://poser.pugx.org/laravel/framework/v/unstable.svg)](https://packagist.org/packages/laravel/framework)
-[![License](https://poser.pugx.org/laravel/framework/license.svg)](https://packagist.org/packages/laravel/framework)
-
-Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching.
-
-Laravel is accessible, yet powerful, providing powerful tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked.
-
-## Official Documentation
-
-Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs).
-
-## Contributing
-
-Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions).
-
-## Security Vulnerabilities
-
-If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
-
-### License
-
-The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
+A platform to create documentation/wiki content.
\ No newline at end of file
index b855a8067d665e60e6ec55b57e797519cd69dff4..1b1318f92194d58133b9546025afc8fb029cea1a 100644 (file)
@@ -379,4 +379,9 @@ body.dragging, body.dragging * {
 }
 .sortable-page-list li.placeholder:before {
   position: absolute;
+}
+
+.material-icons {
+  font-size: 1em;
+  line-height: 1.4em;
 }
\ No newline at end of file
index 47c4a13d39bda76380044e5f7af5dedb02d5c3c7..5fc10ce7455b368f08ee442e3a83067298123b2c 100644 (file)
@@ -4,7 +4,7 @@
     <title>BookStack</title>
     <meta name="viewport" content="width=device-width">
     <link rel="stylesheet" href="/css/app.css">
-    <link href='http://fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'>
+    <link href='//fonts.googleapis.com/css?family=Roboto:400,400italic,500,500italic,700,700italic,300italic,100,300' rel='stylesheet' type='text/css'>
     <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
     <script src="/bower/bootstrap/dist/js/bootstrap.js"></script>
index a4a31b995498bdb754df61f67eb04785fdce0efc..f9faff0f47b09253d69301fcced92642cb387ae1 100644 (file)
         <p class="text-muted">{{$book->description}}</p>
 
         <div class="clearfix header-group">
-            <h4 class="float">Pages</h4>
-            <a href="{{$book->getUrl() . '/page/create'}}" class="text-pos float right">+ New Page</a>
+            <h4 class="float">Contents</h4>
+            <div class="float right">
+                <a href="{{$book->getUrl() . '/page/create'}}" class="text-pos">+ New Page</a>
+                <a href="{{$book->getUrl() . '/chapter/create'}}" class="text-pos">+ New Chapter</a>
+            </div>
+        </div>
+
+        <div class="page-list">
+            @foreach($book->children() as $childElement)
+                <div class="page-list-item">
+                    @if(is_a($childElement, 'Oxbow\Chapter'))
+                        <i class="fa fa-archive"></i>
+                    @else
+                        <i class="fa fa-file"></i>
+                    @endif
+                    {{$childElement->name}}
+                </div>
+            @endforeach
         </div>
 
-        @include('pages/page-tree-list', ['pageTree' => $pageTree])
+        {{--@include('pages/page-tree-list', ['pageTree' => $pageTree])--}}
 
     </div>
 
diff --git a/resources/views/chapters/create.blade.php b/resources/views/chapters/create.blade.php
new file mode 100644 (file)
index 0000000..4e506fe
--- /dev/null
@@ -0,0 +1,12 @@
+@extends('base')
+
+@section('content')
+
+    <div class="page-content">
+        <h1>Create New Chapter</h1>
+        <form action="{{$book->getUrl()}}/chapter/create" method="POST">
+            @include('chapters/form')
+        </form>
+    </div>
+
+@stop
\ No newline at end of file
diff --git a/resources/views/chapters/form.blade.php b/resources/views/chapters/form.blade.php
new file mode 100644 (file)
index 0000000..4eb96fa
--- /dev/null
@@ -0,0 +1,11 @@
+
+{{ csrf_field() }}
+<div class="form-group title-input">
+    <label for="name">Chapter Name</label>
+    @include('form/text', ['name' => 'name'])
+</div>
+<div class="form-group description-input">
+    <label for="description">Description</label>
+    @include('form/textarea', ['name' => 'description'])
+</div>
+<button type="submit" class="button pos">Save</button>
\ No newline at end of file
Morty Proxy This is a proxified and sanitized view of the page, visit original site.