diff --git a/app/Http/Controllers/Admin/CreatorCrudController.php b/app/Http/Controllers/Admin/CreatorCrudController.php new file mode 100644 index 000000000..6fb0a6ce4 --- /dev/null +++ b/app/Http/Controllers/Admin/CreatorCrudController.php @@ -0,0 +1,37 @@ +crud->setModel('App\Models\Creator'); + $this->crud->setRoute(config('backpack.base.route_prefix').'/creator'); + $this->crud->setEntityNameStrings('creator', 'creators'); + } + + protected function setupListOperation() + { + $this->crud->addColumn('name'); + $this->crud->addColumn([ + 'type' => 'relationship_count', + 'name' => 'snippets', + 'label' => 'Snippets', + 'suffix' => ' snippets', + 'link' => function ($entry) { + return backpack_url('creator/'.$entry->id.'/snippet'); + }, + ]); + } +} diff --git a/app/Http/Controllers/Admin/CreatorSnippetCrudController.php b/app/Http/Controllers/Admin/CreatorSnippetCrudController.php new file mode 100644 index 000000000..e0d2e1b1a --- /dev/null +++ b/app/Http/Controllers/Admin/CreatorSnippetCrudController.php @@ -0,0 +1,31 @@ +parameter('user_id'); + + $this->crud->setModel('App\Models\Snippet'); + $this->crud->setRoute(config('backpack.base.route_prefix').'/creator/'.$user_id.'/snippet'); + $this->crud->setEntityNameStrings('snippet', 'snippets'); + + // filter List operation (with search) to only show this users' entries + $this->crud->addClause('where', 'created_by', $user_id); + } +} diff --git a/app/Http/Controllers/Admin/MonsterCrudController.php b/app/Http/Controllers/Admin/MonsterCrudController.php index 0a0f4187f..14c47f35c 100644 --- a/app/Http/Controllers/Admin/MonsterCrudController.php +++ b/app/Http/Controllers/Admin/MonsterCrudController.php @@ -568,10 +568,10 @@ protected function setupCreateOperation() ]); $this->crud->addField([ // Browse multiple - 'name' => 'browse_multiple', - 'label' => 'Browse multiple', - 'type' => 'browse_multiple', - 'tab' => 'Uploads', + 'name' => 'browse_multiple', + 'label' => 'Browse multiple', + 'type' => 'browse_multiple', + 'tab' => 'Uploads', 'sortable' => true, // 'multiple' => true, // enable/disable the multiple selection functionality // 'mime_types' => null, // visible mime prefixes; ex. ['image'] or ['application/pdf'] diff --git a/app/Http/Controllers/Admin/MySnippetCrudController.php b/app/Http/Controllers/Admin/MySnippetCrudController.php new file mode 100644 index 000000000..b9bc59b0b --- /dev/null +++ b/app/Http/Controllers/Admin/MySnippetCrudController.php @@ -0,0 +1,36 @@ +crud->setModel('App\Models\Snippet'); + $this->crud->setRoute(config('backpack.base.route_prefix').'/my-snippet'); + $this->crud->setEntityNameStrings('snippet', 'snippets'); + + // filter List operation (with search) to only show this users' entries + $this->crud->addClause('where', 'created_by', backpack_auth()->user()->id); + + // if the user tries to access somone else's entries, block him + $entry = $this->crud->getCurrentEntry(); + + if ($entry && $entry->created_by != backpack_auth()->user()->id) { + abort(403, "You don't have access to this entry."); + } + } +} diff --git a/app/Http/Controllers/Admin/SnippetCrudController.php b/app/Http/Controllers/Admin/SnippetCrudController.php new file mode 100644 index 000000000..fa1742a8f --- /dev/null +++ b/app/Http/Controllers/Admin/SnippetCrudController.php @@ -0,0 +1,102 @@ +crud->setModel('App\Models\Snippet'); + $this->crud->setRoute(config('backpack.base.route_prefix').'/snippet'); + $this->crud->setEntityNameStrings('snippet', 'snippets'); + } + + protected function setupListOperation() + { + $this->crud->addColumn('name'); + $this->crud->addColumn([ + 'label' => 'Category', + 'type' => 'select', + 'name' => 'category_id', + 'entity' => 'category', + 'attribute' => 'name', + ]); + $this->crud->addColumn([ + 'label' => 'Created by', + 'type' => 'select', + 'name' => 'created_by', + 'entity' => 'creator', + 'attribute' => 'name', + ]); + + $this->crud->addColumn([ + 'label' => 'Updated by', + 'type' => 'select', + 'name' => 'updated_by', + 'entity' => 'updater', + 'attribute' => 'name', + ]); + } + + protected function setupShowOperation() + { + $this->setupListOperation(); + + $this->crud->addColumn('description'); + $this->crud->addColumn('content'); + } + + protected function setupCreateOperation() + { + $this->crud->setValidation(SnippetRequest::class); + + $this->crud->addField([ + 'type' => 'text', + 'name' => 'name', + 'label' => 'Name', + 'wrapperAttributes' => [ + 'class' => 'form-group col-md-6', + ], + ]); + $this->crud->addField([ + 'label' => 'Category', + 'type' => 'select', + 'name' => 'category_id', + 'entity' => 'category', + 'attribute' => 'name', + 'wrapperAttributes' => [ + 'class' => 'form-group col-md-6', + ], + ]); + $this->crud->addField([ + 'type' => 'simplemde', + 'name' => 'description', + 'label' => 'Description', + ]); + $this->crud->addField([ + 'type' => 'textarea', + 'name' => 'content', + 'label' => 'Content', + ]); + } + + protected function setupUpdateOperation() + { + $this->setupCreateOperation(); + } +} diff --git a/app/Http/Requests/CreatorRequest.php b/app/Http/Requests/CreatorRequest.php new file mode 100644 index 000000000..422b2a3df --- /dev/null +++ b/app/Http/Requests/CreatorRequest.php @@ -0,0 +1,55 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + // 'name' => 'required|min:5|max:255' + ]; + } + + /** + * Get the validation attributes that apply to the request. + * + * @return array + */ + public function attributes() + { + return [ + // + ]; + } + + /** + * Get the validation messages that apply to the request. + * + * @return array + */ + public function messages() + { + return [ + // + ]; + } +} diff --git a/app/Http/Requests/SnippetRequest.php b/app/Http/Requests/SnippetRequest.php new file mode 100644 index 000000000..c0e8a3c57 --- /dev/null +++ b/app/Http/Requests/SnippetRequest.php @@ -0,0 +1,56 @@ +check(); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'name' => 'required|min:5|max:255', + 'category_id' => 'required', + ]; + } + + /** + * Get the validation attributes that apply to the request. + * + * @return array + */ + public function attributes() + { + return [ + // + ]; + } + + /** + * Get the validation messages that apply to the request. + * + * @return array + */ + public function messages() + { + return [ + // + ]; + } +} diff --git a/app/Models/Creator.php b/app/Models/Creator.php new file mode 100644 index 000000000..46ace3a22 --- /dev/null +++ b/app/Models/Creator.php @@ -0,0 +1,25 @@ +hasMany('App\Models\Snippet', 'created_by'); + } +} diff --git a/app/Models/Snippet.php b/app/Models/Snippet.php new file mode 100644 index 000000000..63d206745 --- /dev/null +++ b/app/Models/Snippet.php @@ -0,0 +1,61 @@ +belongsTo('Backpack\NewsCRUD\app\Models\Category', 'category_id'); + } + + /* + |-------------------------------------------------------------------------- + | SCOPES + |-------------------------------------------------------------------------- + */ + + /* + |-------------------------------------------------------------------------- + | ACCESSORS + |-------------------------------------------------------------------------- + */ + + /* + |-------------------------------------------------------------------------- + | MUTATORS + |-------------------------------------------------------------------------- + */ +} diff --git a/app/Models/Traits/CreatedByTrait.php b/app/Models/Traits/CreatedByTrait.php new file mode 100644 index 000000000..7750e192e --- /dev/null +++ b/app/Models/Traits/CreatedByTrait.php @@ -0,0 +1,37 @@ +check() ? backpack_auth()->user() : (\Auth::check() ? \Auth::user() : false); + + if ($user) { + $this->created_by = $this->created_by ?? $user->id; + $this->updated_by = $user->id; + } + + parent::save(); + } + + /* + |-------------------------------------------------------------------------- + | RELATIONS + |-------------------------------------------------------------------------- + */ + + public function creator() + { + return $this->belongsTo('App\User', 'created_by'); + } + + public function updater() + { + return $this->belongsTo('App\User', 'updated_by'); + } +} diff --git a/database/migrations/2019_12_03_115109_create_snippets_table.php b/database/migrations/2019_12_03_115109_create_snippets_table.php new file mode 100644 index 000000000..92b79149c --- /dev/null +++ b/database/migrations/2019_12_03_115109_create_snippets_table.php @@ -0,0 +1,37 @@ +increments('id'); + $table->string('name'); + $table->integer('category_id')->unsigned(); + $table->text('description')->nullable(); + $table->text('content')->nullable(); + $table->integer('created_by')->nullable()->unsigned(); + $table->integer('updated_by')->nullable()->unsigned(); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('snippets'); + } +} diff --git a/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php b/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php index a09d901f3..31dfdda1c 100644 --- a/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php +++ b/resources/views/vendor/backpack/base/inc/sidebar_content.blade.php @@ -36,4 +36,10 @@ - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/resources/views/vendor/backpack/crud/columns/relationship_count.blade.php b/resources/views/vendor/backpack/crud/columns/relationship_count.blade.php new file mode 100644 index 000000000..9ac431d8c --- /dev/null +++ b/resources/views/vendor/backpack/crud/columns/relationship_count.blade.php @@ -0,0 +1,8 @@ +{{-- snippets column - used to show Nested CRUDs inside Backpack Demo --}} +@php + $value = $entry->{$column['name']}->count(); + $link = isset($column['link']) ? $column['link']($entry) : false; + $target = isset($column['target']) ? $column['target'] : false; +@endphp + +{{ (array_key_exists('prefix', $column) ? $column['prefix'] : '').str_limit(strip_tags($value), array_key_exists('limit', $column) ? $column['limit'] : 40, "[...]").(array_key_exists('suffix', $column) ? $column['suffix'] : '') }} \ No newline at end of file diff --git a/routes/backpack/custom.php b/routes/backpack/custom.php index 46866425a..e0a8e33f4 100644 --- a/routes/backpack/custom.php +++ b/routes/backpack/custom.php @@ -20,13 +20,24 @@ Route::crud('icon', 'IconCrudController'); Route::crud('product', 'ProductCrudController'); + // --------------------- + // Backpack Nested CRUDs + // --------------------- + Route::crud('snippet', 'SnippetCrudController'); + Route::crud('my-snippet', 'MySnippetCrudController'); + + Route::crud('creator', 'CreatorCrudController'); + Route::group(['prefix' => 'creator/{user_id}'], function () { + Route::crud('snippet', 'CreatorSnippetCrudController'); + }); + // --------------------------- // Backpack DEMO Custom Routes // Prevent people from doing nasty stuff in the online demo // --------------------------- if (app('env') == 'production') { // disable delete and bulk delete for all CRUDs - $cruds = ['article', 'category', 'tag', 'monster', 'icon', 'product', 'page', 'menu-item', 'user', 'role', 'permission']; + $cruds = ['article', 'category', 'tag', 'monster', 'icon', 'product', 'page', 'menu-item', 'user', 'role', 'permission', 'snippet', 'my-snippet', 'creator', 'creator/{user_id}/snippet']; foreach ($cruds as $name) { Route::delete($name.'/{id}', function () { return false;