]> BookStack Code Mirror - bookstack/commitdiff
Added initial settings interface, Fixes #9.
authorDan Brown <redacted>
Sun, 30 Aug 2015 14:31:16 +0000 (15:31 +0100)
committerDan Brown <redacted>
Sun, 30 Aug 2015 14:31:16 +0000 (15:31 +0100)
17 files changed:
app/Http/Controllers/SettingController.php [new file with mode: 0644]
app/Http/routes.php
app/Providers/CustomFacadeProvider.php
app/Services/ActivityService.php
app/Services/Facades/Setting.php [new file with mode: 0644]
app/Services/SettingService.php [new file with mode: 0644]
app/Setting.php [new file with mode: 0644]
config/app.php
database/migrations/2015_08_30_125859_create_settings_table.php [new file with mode: 0644]
resources/assets/sass/_forms.scss
resources/assets/sass/styles.scss
resources/views/base.blade.php
resources/views/books/show.blade.php
resources/views/settings/index.blade.php [new file with mode: 0644]
resources/views/settings/navbar.blade.php [new file with mode: 0644]
resources/views/users/edit.blade.php
resources/views/users/index.blade.php

diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php
new file mode 100644 (file)
index 0000000..e0695f2
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+
+namespace Oxbow\Http\Controllers;
+
+use Illuminate\Http\Request;
+
+use Oxbow\Http\Requests;
+use Oxbow\Http\Controllers\Controller;
+use Setting;
+
+class SettingController extends Controller
+{
+    /**
+     * Display a listing of the settings.
+     *
+     * @return Response
+     */
+    public function index()
+    {
+        $this->checkPermission('settings-update');
+        return view('settings/index');
+    }
+
+
+
+    /**
+     * Update the specified settings in storage.
+     *
+     * @param  Request  $request
+     * @return Response
+     */
+    public function update(Request $request)
+    {
+        $this->checkPermission('settings-update');
+        // Cycles through posted settings and update them
+        foreach($request->all() as $name => $value) {
+            if(strpos($name, 'setting-') !== 0) continue;
+            $key = str_replace('setting-', '', trim($name));
+            Setting::put($key, $value);
+        }
+        return redirect('/settings');
+    }
+
+}
index eb945c72f64b8220e477ec4301367c9072942833..2dfd35abd261403633ee9fc9a98650b04d9b66ab 100644 (file)
@@ -71,6 +71,10 @@ Route::group(['middleware' => 'auth'], function () {
     Route::get('/', 'HomeController@index');
     Route::get('/home', 'HomeController@index');
 
+    // Settings
+    Route::get('/settings', 'SettingController@index');
+    Route::post('/settings', 'SettingController@update');
+
 
 });
 
index bb4520c187848222d904e84e345b5cb7232a0b37..6e631882455d2238d0569071445946a8ef997732 100644 (file)
@@ -4,6 +4,7 @@ namespace Oxbow\Providers;
 
 use Illuminate\Support\ServiceProvider;
 use Oxbow\Services\ActivityService;
+use Oxbow\Services\SettingService;
 
 class CustomFacadeProvider extends ServiceProvider
 {
@@ -27,5 +28,9 @@ class CustomFacadeProvider extends ServiceProvider
         $this->app->bind('activity', function() {
             return new ActivityService($this->app->make('Oxbow\Activity'));
         });
+
+        $this->app->bind('setting', function() {
+            return new SettingService($this->app->make('Oxbow\Setting'));
+        });
     }
 }
index a4259bf12dfbbb41c0d364fb5404e5f71454feff..a515eea1c2b4ffa7369ff02d45ece30dbd1e8534 100644 (file)
@@ -81,11 +81,13 @@ class ActivityService
      * Gets the latest activity.
      * @param int $count
      * @param int $page
+     * @return array
      */
     public function latest($count = 20, $page = 0)
     {
-        return $this->activity->orderBy('created_at', 'desc')
+        $activityList =  $this->activity->orderBy('created_at', 'desc')
             ->skip($count * $page)->take($count)->get();
+        return $this->filterSimilar($activityList);
     }
 
     /**
@@ -99,7 +101,7 @@ class ActivityService
     function entityActivity($entity, $count = 20, $page = 0)
     {
         $activity = $entity->hasMany('Oxbow\Activity')->orderBy('created_at', 'desc')
-            ->skip($count*$page)->take($count)->get();
+            ->skip($count * $page)->take($count)->get();
 
         return $this->filterSimilar($activity);
     }
@@ -109,16 +111,17 @@ class ActivityService
      * @param Activity[] $activity
      * @return array
      */
-    protected function filterSimilar($activity) {
+    protected function filterSimilar($activity)
+    {
         $newActivity = [];
         $previousItem = false;
-        foreach($activity as $activityItem) {
-            if($previousItem === false) {
+        foreach ($activity as $activityItem) {
+            if ($previousItem === false) {
                 $previousItem = $activityItem;
                 $newActivity[] = $activityItem;
                 continue;
             }
-            if(!$activityItem->isSimilarTo($previousItem)) {
+            if (!$activityItem->isSimilarTo($previousItem)) {
                 $newActivity[] = $activityItem;
             }
             $previousItem = $activityItem;
diff --git a/app/Services/Facades/Setting.php b/app/Services/Facades/Setting.php
new file mode 100644 (file)
index 0000000..eb58441
--- /dev/null
@@ -0,0 +1,14 @@
+<?php namespace Oxbow\Services\Facades;
+
+
+use Illuminate\Support\Facades\Facade;
+
+class Setting extends Facade
+{
+    /**
+     * Get the registered name of the component.
+     *
+     * @return string
+     */
+    protected static function getFacadeAccessor() { return 'setting'; }
+}
\ No newline at end of file
diff --git a/app/Services/SettingService.php b/app/Services/SettingService.php
new file mode 100644 (file)
index 0000000..4c27035
--- /dev/null
@@ -0,0 +1,89 @@
+<?php namespace Oxbow\Services;
+
+use Oxbow\Setting;
+
+/**
+ * Class SettingService
+ *
+ * The settings are a simple key-value database store.
+ *
+ * @package Oxbow\Services
+ */
+class SettingService
+{
+
+    protected $setting;
+
+    /**
+     * SettingService constructor.
+     * @param $setting
+     */
+    public function __construct(Setting $setting)
+    {
+        $this->setting = $setting;
+    }
+
+    /**
+     * Gets a setting from the database,
+     * If not found, Returns default, Which is false by default.
+     * @param             $key
+     * @param string|bool $default
+     * @return bool|string
+     */
+    public function get($key, $default = false)
+    {
+        $setting = $this->getSettingObjectByKey($key);
+        return $setting === null ? $default : $setting->value;
+    }
+
+    /**
+     * Checks if a setting exists.
+     * @param $key
+     * @return bool
+     */
+    public function has($key)
+    {
+        $setting = $this->getSettingObjectByKey($key);
+        return $setting !== null;
+    }
+
+    /**
+     * Add a setting to the database.
+     * @param $key
+     * @param $value
+     * @return bool
+     */
+    public function put($key, $value)
+    {
+        $setting = $this->setting->firstOrNew([
+            'setting_key' => $key
+        ]);
+        $setting->value = $value;
+        $setting->save();
+        return true;
+    }
+
+    /**
+     * Removes a setting from the database.
+     * @param $key
+     * @return bool
+     */
+    public function remove($key)
+    {
+        $setting = $this->getSettingObjectByKey($key);
+        if($setting) {
+            $setting->delete();
+        }
+        return true;
+    }
+
+    /**
+     * Gets a setting model from the database for the given key.
+     * @param $key
+     * @return mixed
+     */
+    private function getSettingObjectByKey($key) {
+        return $this->setting->where('setting_key', '=', $key)->first();
+    }
+
+}
\ No newline at end of file
diff --git a/app/Setting.php b/app/Setting.php
new file mode 100644 (file)
index 0000000..af36a1a
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+namespace Oxbow;
+
+use Illuminate\Database\Eloquent\Model;
+
+class Setting extends Model
+{
+    protected $fillable = ['setting_key', 'value'];
+
+    protected $primaryKey = 'setting_key';
+}
index 5c76c595839b16b907c34413ef33eae38434e8e4..80012a3ede1f2ec2dc67b215c5dd180ba48d50a6 100644 (file)
@@ -13,7 +13,7 @@ return [
     |
     */
 
-    'debug' => env('APP_DEBUG', false),
+    'debug'           => env('APP_DEBUG', false),
 
     /*
     |--------------------------------------------------------------------------
@@ -26,7 +26,7 @@ return [
     |
     */
 
-    'url' => 'http://localhost',
+    'url'             => 'http://localhost',
 
     /*
     |--------------------------------------------------------------------------
@@ -39,7 +39,7 @@ return [
     |
     */
 
-    'timezone' => 'UTC',
+    'timezone'        => 'UTC',
 
     /*
     |--------------------------------------------------------------------------
@@ -52,7 +52,7 @@ return [
     |
     */
 
-    'locale' => 'en',
+    'locale'          => 'en',
 
     /*
     |--------------------------------------------------------------------------
@@ -78,9 +78,9 @@ return [
     |
     */
 
-    'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'),
+    'key'             => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'),
 
-    'cipher' => 'AES-256-CBC',
+    'cipher'          => 'AES-256-CBC',
 
     /*
     |--------------------------------------------------------------------------
@@ -95,7 +95,7 @@ return [
     |
     */
 
-    'log' => 'single',
+    'log'             => 'single',
 
     /*
     |--------------------------------------------------------------------------
@@ -108,7 +108,7 @@ return [
     |
     */
 
-    'providers' => [
+    'providers'       => [
 
         /*
          * Laravel Framework Service Providers...
@@ -165,7 +165,7 @@ return [
     |
     */
 
-    'aliases' => [
+    'aliases'         => [
 
         'App'       => Illuminate\Support\Facades\App::class,
         'Artisan'   => Illuminate\Support\Facades\Artisan::class,
@@ -210,7 +210,8 @@ return [
          * Custom
          */
 
-        'Activity' => Oxbow\Services\Facades\Activity::class,
+        'Activity'  => Oxbow\Services\Facades\Activity::class,
+        'Setting'   => Oxbow\Services\Facades\Setting::class,
 
     ],
 
diff --git a/database/migrations/2015_08_30_125859_create_settings_table.php b/database/migrations/2015_08_30_125859_create_settings_table.php
new file mode 100644 (file)
index 0000000..8437668
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateSettingsTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('settings', function (Blueprint $table) {
+            $table->string('setting_key')->primary()->indexed();
+            $table->text('value');
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::drop('settings');
+    }
+}
index 2e0c5cf0e244b1cc683aa004e55ef98b108e2414..1fb24cb4a1439e62014a67c57229f24279ec0fdf 100644 (file)
@@ -10,7 +10,7 @@
   color: #222;
   width: 250px;
   max-width: 100%;
-  -webkit-appearance:none;
+  //-webkit-appearance:none;
   &.neg, &.invalid {
     border: 1px solid $negative;
   }
 label {
   display: block;
   line-height: 1.4em;
-  font-size: 0.9em;
+  font-size: 0.94em;
   font-weight: 500;
-  color: #333;
+  color: #666;
+  padding-bottom: 2px;
 }
 
 label.radio, label.checkbox {
index 7be43ab6b706e57c2c96cc79efe2afa175e7444c..d6534789aceb989e25de3db928c3fbf6fc6bc33d 100644 (file)
@@ -485,4 +485,19 @@ body.dragging, body.dragging * {
     background-color: $negative;
     color: #EEE;
   }
+}
+
+.setting-nav {
+  margin-top: $-l;
+  border-top: 1px solid #DDD;
+  border-bottom: 1px solid #DDD;
+  a {
+    padding: $-m;
+    display: inline-block;
+    //color: #666;
+    &.selected {
+      //color: $primary;
+      background-color: #f8f8f8;
+    }
+  }
 }
\ No newline at end of file
index 06f21784861cd73651be2fb907e9588e7f1c3b02..4e1e74398b44c706ae05b5f6ccc9f69ecafca45a 100644 (file)
@@ -54,7 +54,7 @@
         <header>
             <div class="padded row clearfix">
                 <div class="col-md-12 logo-container">
-                    <a href="/" class="logo">BookStack</a>
+                    <a href="/" class="logo">{{ Setting::get('app-name', 'BookStack') }}</a>
                     <div class="user-overview">
                         <img class="avatar" src="{{Auth::user()->getAvatar(50)}}" alt="{{ Auth::user()->name }}">
                         <span class="user-name">
index 4f007e2439e04f58c8f626344b26a1bab31c1c41..d80cc09e1b5450657e674d991cf54df241913a06 100644 (file)
@@ -78,8 +78,6 @@
     </div>
 
 
-
-
     <script>
         $(function() {
 
diff --git a/resources/views/settings/index.blade.php b/resources/views/settings/index.blade.php
new file mode 100644 (file)
index 0000000..93e7862
--- /dev/null
@@ -0,0 +1,23 @@
+@extends('base')
+
+@section('content')
+
+    @include('settings/navbar', ['selected' => 'settings'])
+
+    <div class="page-content">
+        <h1>Settings</h1>
+
+        <form action="/settings" method="POST">
+            {!! csrf_field() !!}
+            <div class="form-group">
+                <label for="setting-app-name">Application Name</label>
+                <input type="text" value="{{ Setting::get('app-name') }}" name="setting-app-name" id="setting-app-name">
+            </div>
+            <div class="form-group">
+                <button type="submit" class="button pos">Update Settings</button>
+            </div>
+        </form>
+
+    </div>
+
+@stop
\ No newline at end of file
diff --git a/resources/views/settings/navbar.blade.php b/resources/views/settings/navbar.blade.php
new file mode 100644 (file)
index 0000000..3934a3c
--- /dev/null
@@ -0,0 +1,6 @@
+<div class="row">
+    <div class="col-md-6 col-md-offset-3 setting-nav">
+        <a href="/settings" @if($selected == 'settings') class="selected" @endif><i class="zmdi zmdi-settings"></i>Settings</a>
+        <a href="/users" @if($selected == 'users') class="selected" @endif><i class="zmdi zmdi-accounts"></i>Users</a>
+    </div>
+</div>
\ No newline at end of file
index cb56ad9052f06453b06a8d977e4c8de8b13c688c..a94582b889f5864830e753bad64b3ede95eb0605 100644 (file)
@@ -17,7 +17,7 @@
 
             <div class="row">
                 <div class="col-md-6">
-                    <h1>Edit User</h1>
+                    <h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1>
                     <form action="/users/{{$user->id}}" method="post">
                         {!! csrf_field() !!}
                         <input type="hidden" name="_method" value="put">
index 730ead8aacea6edf70b7ac517e1f9ca608eb8b43..57f9b88730c137c800c4aa23bcc667d844607379 100644 (file)
@@ -3,21 +3,15 @@
 
 @section('content')
 
-
-    <div class="row faded-small">
-        <div class="col-md-6"></div>
-        <div class="col-md-6 faded">
-            <div class="action-buttons">
-                @if($currentUser->can('user-create'))
-                    <a href="/users/create" class="text-pos"><i class="zmdi zmdi-account-add"></i>New User</a>
-                @endif
-            </div>
-        </div>
-    </div>
-
+    @include('settings/navbar', ['selected' => 'users'])
 
     <div class="page-content">
         <h1>Users</h1>
+        @if($currentUser->can('user-create'))
+            <p>
+                <a href="/users/create" class="text-pos"><i class="zmdi zmdi-account-add"></i>Add New User</a>
+            </p>
+        @endif
         <table class="table">
             <tr>
                 <th></th>