1
0

提交代码

This commit is contained in:
2020-08-06 14:50:07 +08:00
parent 9d0d5f4be9
commit d7a848c824
11299 changed files with 1321854 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2015 Jens Segers
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,75 @@
laravel-admin
=====
[![Build Status](https://travis-ci.org/z-song/laravel-admin.svg?branch=master)](https://travis-ci.org/z-song/laravel-admin)
[![StyleCI](https://styleci.io/repos/48796179/shield)](https://styleci.io/repos/48796179)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/z-song/laravel-admin/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/z-song/laravel-admin/?branch=master)
[![Packagist](https://img.shields.io/packagist/l/encore/laravel-admin.svg?maxAge=2592000)](https://packagist.org/packages/encore/laravel-admin)
[![Total Downloads](https://img.shields.io/packagist/dt/encore/laravel-admin.svg?style=flat-square)](https://packagist.org/packages/encore/laravel-admin)
[![Awesome Laravel](https://img.shields.io/badge/Awesome-Laravel-brightgreen.svg)](https://github.com/z-song/laravel-admin)
`laravel-admin` is administrative interface builder for laravel which can help you build CRUD backends just with few lines of code.
[Demo](http://laravel-admin.org/demo) use `username/password:admin/admin`
Inspired by [SleepingOwlAdmin](https://github.com/sleeping-owl/admin) and [rapyd-laravel](https://github.com/zofe/rapyd-laravel).
[Documentation](http://laravel-admin.org/docs) | [中文文档](http://laravel-admin.org/docs/#/zh/)
Screenshots
------------
![laravel-admin](https://cloud.githubusercontent.com/assets/1479100/19625297/3b3deb64-9947-11e6-807c-cffa999004be.jpg)
Installation
------------
> This package requires PHP 7+ and Laravel 5.5, for old versions please refer to [1.4](http://laravel-admin.org/docs/v1.4/#/)
First, install laravel 5.5, and make sure that the database connection settings are correct.
```
composer require encore/laravel-admin 1.5.*
```
Then run these commands to publish assets and config
```
php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"
```
After run command you can find config file in `config/admin.php`, in this file you can change the install directory,db connection or table names.
At last run following command to finish install.
```
php artisan admin:install
```
Open `http://localhost/admin/` in browser,use username `admin` and password `admin` to login.
Default Settings
------------
The file in `config/admin.php` contains an array of settings, you can find the default settings in there.
Other
------------
`laravel-admin` based on following plugins or services:
+ [Laravel](https://laravel.com/)
+ [AdminLTE](https://almsaeedstudio.com/)
+ [Datetimepicker](http://eonasdan.github.io/bootstrap-datetimepicker/)
+ [font-awesome](http://fontawesome.io)
+ [moment](http://momentjs.com/)
+ [Google map](https://www.google.com/maps)
+ [Tencent map](http://lbs.qq.com/)
+ [bootstrap-fileinput](https://github.com/kartik-v/bootstrap-fileinput)
+ [jquery-pjax](https://github.com/defunkt/jquery-pjax)
+ [Nestable](http://dbushell.github.io/Nestable/)
+ [toastr](http://codeseven.github.io/toastr/)
+ [X-editable](http://github.com/vitalets/x-editable)
+ [bootstrap-number-input](https://github.com/wpic/bootstrap-number-input)
+ [fontawesome-iconpicker](https://github.com/itsjavi/fontawesome-iconpicker)
License
------------
`laravel-admin` is licensed under [The MIT License (MIT)](LICENSE).

View File

@@ -0,0 +1,34 @@
- Getting started
- [Installation](/en/installation.md)
- [Quick start](/en/quick-start.md)
- [Page content & Layout](/en/content-layout.md)
- Model grid
- [Basic usage](/en/model-grid.md)
- [Row actions](/en/model-grid-actions.md)
- [Column actions](/en/model-grid-column.md)
- [Custom tools](/en/model-grid-custom-tools.md)
- [Filters](/en/model-grid-filters.md)
- [Data export](/en/model-grid-export.md)
- Model form
- [Basic usage](/en/model-form.md)
- [Image/File upload](/en/model-form-upload.md)
- [Form fields](/en/model-form-fields.md)
- [Form field management](/en/model-form-field-management.md)
- [Form validation](/en/model-form-validation.md)
- [Save callback](/en/model-form-callback.md)
- [Model-tree](/en/model-tree.md)
- Admin extensions
- [Helpers](/en/extension-helpers.md)
- [Media manager](/en/extension-media-manager.md)
- [API tester](/en/extension-api-tester.md)
- [Config manager](/en/extension-config.md)
- [Task scheduling](/en/extension-scheduling.md)
- [Widgets](/en/widgets.md)
- [Permissions](/en/permission.md)
- [Custom authentication](/en/custom-authentication.md)
- [Custom Navbar](/en/custom-navbar.md)
- [Custom chart](/en/custom-chart.md)
- [Helpers](/en/helpers.md)
- [Upgrade precautions](/en/upgrade.md)
- [Change log](/en/change-log.md)

View File

@@ -0,0 +1,12 @@
# Change log
## v1.2.9、v1.3.3、v1.4.1
- Add user settings and modify avatar function
- Embedded form support
- Support for customize navigation bar (upper right corner)
- Add scaffolding, database command line tool, web artisan help tool
- Support for customize login page and login logic
- The form supports setting the width and setting the action
- Optimize table filters
- Fix bugs, optimize code and logic

View File

@@ -0,0 +1,153 @@
# Page content
The layout usage of `laravel-admin` can be found in the `index()` method of the home page's layout file [HomeController.php](https://github.com/z-song/laravel-admin/blob/master/src/Console/stubs/HomeController.stub).
The `Encore\Admin\Layout\Content` class is used to implement the layout of the content area. The `Content::body ($element)` method is used to add page content:
The page code for an unfilled content is as follows
```php
public function index()
{
return Admin::content(function (Content $content) {
// optional
$content->header('page header');
// optional
$content->description('page description');
// add breadcrumb since v1.5.7
$content->breadcrumb(
['text' => 'Dashboard', 'url' => '/admin'],
['text' => 'User management', 'url' => '/admin/users'],
['text' => 'Edit user']
);
// Fill the page body part, you can put any renderable objects here
$content->body('hello world');
});
}
```
Method `$content->body();` can accepts any renderable objects, like string, number, class that has method `__toString`, or implements `Renderable``Htmlable` interface , include Laravel View objects.
## Layout
`laravel-admin` use grid system of bootstrap,The length of each line is 12, the following is a few simple examples:
Add a line of content:
```php
$content->row('hello')
---------------------------------
|hello |
| |
| |
| |
| |
| |
---------------------------------
```
Add multiple columns within the line
```php
$content->row(function(Row $row) {
$row->column(4, 'foo');
$row->column(4, 'bar');
$row->column(4, 'baz');
});
----------------------------------
|foo |bar |baz |
| | | |
| | | |
| | | |
| | | |
| | | |
----------------------------------
$content->row(function(Row $row) {
$row->column(4, 'foo');
$row->column(8, 'bar');
});
----------------------------------
|foo |bar |
| | |
| | |
| | |
| | |
| | |
----------------------------------
```
Column in the column
```php
$content->row(function (Row $row) {
$row->column(4, 'xxx');
$row->column(8, function (Column $column) {
$column->row('111');
$column->row('222');
$column->row('333');
});
});
----------------------------------
|xxx |111 |
| |---------------------|
| |222 |
| |---------------------|
| |333 |
| | |
----------------------------------
```
Add rows in rows and add columns
```php
$content->row(function (Row $row) {
$row->column(4, 'xxx');
$row->column(8, function (Column $column) {
$column->row('111');
$column->row('222');
$column->row(function(Row $row) {
$row->column(6, '444');
$row->column(6, '555');
});
});
});
----------------------------------
|xxx |111 |
| |---------------------|
| |222 |
| |---------------------|
| |444 |555 |
| | | |
----------------------------------
```
Add body into a page
Create a blade view file inside `/project/resources/views/admin/custom.blade.php`
```php
public function customPage($id)
{
$content = new Content();
$content->header('View');
$content->description('Description...');
$content->body('admin.custom',['id' => $id]);
return $content;
}
```

View File

@@ -0,0 +1,111 @@
# Custom authentication
If you do not use the `laravel-admin` built-in authentication login logic, you can refer to the following way to customize the login authentication logic.
First of all, you need define a `User provider`, used to obtain the user identity, such as `app/Providers/CustomUserProvider.php`:
```php
<?php
namespace App\Providers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
class CustomUserProvider implements UserProvider
{
public function retrieveById($identifier)
{}
public function retrieveByToken($identifier, $token)
{}
public function updateRememberToken(Authenticatable $user, $token)
{}
public function retrieveByCredentials(array $credentials)
{
// Use $credentials to get the user data, and then return an object implements interface `Illuminate\Contracts\Auth\Authenticatable`
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
// Verify the user with the username password in $ credentials, return `true` or `false`
}
}
```
In the methods `retrieveByCredentials` and `validateCredentials` the parameter `$credentials` is the user name and password array submitted on the login page, you can use `$credentials` to implement your own login logic.
The definition of interface `Illuminate\Contracts\Auth\Authenticatable`:
```php
<?php
namespace Illuminate\Contracts\Auth;
interface Authenticatable {
public function getAuthIdentifierName();
public function getAuthIdentifier();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
}
```
For more details about custom authentication please refer to [adding-custom-user-providers](https://laravel.com/docs/5.5/authentication#adding-custom-user-providers).
After you created cusom user provider, you will need to extend Laravel with it:
```php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('custom', function ($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new CustomUserProvider();
});
}
}
```
Finally modify the configuration, open `config/admin.php`, find the `auth` part:
```php
'auth' => [
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'admin',
]
],
// Modify the following
'providers' => [
'admin' => [
'driver' => 'custom',
]
],
],
```
This completes the logic of custom authentication.

View File

@@ -0,0 +1,78 @@
# Custom chart
`laravel-admin 1.5` has removed all the chart components. If you want to add chart components to the page, you can refer to the following process
Use `chartjs` for example, first download [chartjs](http://chartjs.org/), put it under the public directory, such as in the `public/vendor/chartjs` directory
Then import the component in `app/Admin/bootstrap.php`:
```php
use Encore\Admin\Facades\Admin;
Admin::js('/vendor/chartjs/dist/Chart.min.js');
```
Create a new view file `resources/views/admin/charts/bar.blade.php`
```php
<canvas id="myChart" width="400" height="400"></canvas>
<script>
$(function () {
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
});
</script>
```
And then you can introduce this chart view anywhere on the page:
```php
public function index()
{
return Admin::content(function (Content $content) {
$content->header('chart');
$content->description('.....');
$content->body(view('admin.charts.bar'));
});
}
```
In the above way you can introduce any chart library. multi-chart page layout, refer to [view layout] (/en/layout.md)

View File

@@ -0,0 +1,148 @@
# Customize the head navigation bar
Since version `1.5.6`, you can add the html element to the top navigation bar, open `app/Admin/bootstrap.php`:
```php
use Encore\Admin\Facades\Admin;
Admin::navbar(function (\Encore\Admin\Widgets\Navbar $navbar) {
$navbar->left('html...');
$navbar->right('html...');
});
```
Methods `left` and `right` are used to add content to the left and right sides of the head, the method parameters can be any object that can be rendered (objects which impletements `Htmlable`, `Renderable`, or has method `__toString()`) or strings.
## Add elements to the left
For example, add a search bar on the left, first create a view `resources/views/search-bar.blade.php`:
```php
<style>
.search-form {
width: 250px;
margin: 10px 0 0 20px;
border-radius: 3px;
float: left;
}
.search-form input[type="text"] {
color: #666;
border: 0;
}
.search-form .btn {
color: #999;
background-color: #fff;
border: 0;
}
</style>
<form action="/admin/posts" method="get" class="search-form" pjax-container>
<div class="input-group input-group-sm ">
<input type="text" name="title" class="form-control" placeholder="Search...">
<span class="input-group-btn">
<button type="submit" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i></button>
</span>
</div>
</form>
```
Then add it to the head navigation bar:
```php
$navbar->left(view('search-bar'));
```
## Add elements to the right
You can only add the `<li>` tag on the right side of the navigation, such as adding some prompt icons, creating a new rendering class `app/Admin/Extensions/Nav/Links.php`
```php
<?php
namespace App\Admin\Extensions\Nav;
class Links
{
public function __toString()
{
return <<<HTML
<li>
<a href="#">
<i class="fa fa-envelope-o"></i>
<span class="label label-success">4</span>
</a>
</li>
<li>
<a href="#">
<i class="fa fa-bell-o"></i>
<span class="label label-warning">7</span>
</a>
</li>
<li>
<a href="#">
<i class="fa fa-flag-o"></i>
<span class="label label-danger">9</span>
</a>
</li>
HTML;
}
}
```
Then add it to the head navigation bar:
```php
$navbar->right(new \App\Admin\Extensions\Nav\Links());
```
Or use the following html to add a drop-down menu:
```html
<li class="dropdown notifications-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<i class="fa fa-bell-o"></i>
<span class="label label-warning">10</span>
</a>
<ul class="dropdown-menu">
<li class="header">You have 10 notifications</li>
<li>
<!-- inner menu: contains the actual data -->
<ul class="menu">
<li>
<a href="#">
<i class="fa fa-users text-aqua"></i> 5 new members joined today
</a>
</li>
<li>
<a href="#">
<i class="fa fa-warning text-yellow"></i> Very long description here that may not fit into the
page and may cause design problems
</a>
</li>
<li>
<a href="#">
<i class="fa fa-users text-red"></i> 5 new members joined
</a>
</li>
<li>
<a href="#">
<i class="fa fa-shopping-cart text-green"></i> 25 sales made
</a>
</li>
<li>
<a href="#">
<i class="fa fa-user text-red"></i> You changed your username
</a>
</li>
</ul>
</li>
<li class="footer"><a href="#">View all</a></li>
</ul>
</li>
```
More components can be found here [Bootstrap](https://getbootstrap.com/)

View File

@@ -0,0 +1,60 @@
# Laravel API tester
`api-tester` is an API testing tool developed for `laravel` that helps you test your laravel API like `postman`.
![wx20170809-164424](https://user-images.githubusercontent.com/1479100/29112946-1e32971c-7d22-11e7-8cc0-5b7ad25d084e.png)
## Installation
```shell
$ composer require laravel-admin-ext/api-tester -vvv
$ php artisan vendor:publish --tag=api-tester
```
And then run the following command to import menus and permissions (which can also be added manually)
```shell
$ php artisan admin:import api-tester
```
Then you can find the entry link in the admin menu, `http://localhost/admin/api-tester`.
## Usage
Open `routes/api.php` try to add an api:
```php
Route::get('test', function () {
return 'hello world';
});
```
Open the `api-tester` page, you can see `api/test` on the left, select it and click the `Send` button to send request to the api
### Login as
`Login as` Fill in the user id you want to log in, you can log in as the user to request the API, add the following API:
```php
use Illuminate\Http\Request;
Route::middleware('auth:api')->get('user', function (Request $request) {
return $request->user();
});
```
Fill in the user ID in `Login as` input , then request the api and will respond with the user's model
### Parameters
Used to set the request parameters for api , the type can be a string or file, add the following API:
```php
use Illuminate\Http\Request;
Route::get('parameters', function (Request $request) {
return $request->all();
});
```
Fill in the parameters send request and you can see the results

View File

@@ -0,0 +1,44 @@
# Configuration management
This tool will store the configuration data in the database
![wx20170810-100226](https://user-images.githubusercontent.com/1479100/29151322-0879681a-7db3-11e7-8005-03310686c884.png)
## Installation
```
$ composer require laravel-admin-ext/config
$ php artisan migrate
```
Open `app/Providers/AppServiceProvider.php`, and call the `Config::load()` method within the `boot` method:
```php
<?php
namespace App\Providers;
use Encore\Admin\Config\Config;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Config::load(); // Add this
}
}
```
Then run the command to import menus and permissions (which can also be added manually)
```
$ php artisan admin:import config
```
Open `http://localhost/admin/config`.
## Usage
After add config in the panel, use `config($key)` to get value you configured.

View File

@@ -0,0 +1,45 @@
# Helpers
Added support for developers, available in development to help improve efficiency, currently providing `scaffolding`, `database command line` and `artisan command line `three tools, if there are better other utilities The idea of welcome to provide advice.
Installation:
```php
composer require laravel-admin-ext/helpers
php artisan admin:import helpers
```
> Part of the function of the tool will create or delete files in the project, there may be some file or directory permissions errors, the problem needs to be resolved.
> Another part of the database and artisan command can not be used in the web environment.
## Scaffold
This Tool can help you build controller, model, migrate files, and run migration files.
access by visit `http://localhost/admin/helpers/scaffold`.
Which set the migration table structure, the primary key field is automatically generated do not need to fill out.
![qq20170220-2](https://cloud.githubusercontent.com/assets/1479100/23147949/cbf03e84-f81d-11e6-82b7-d7929c3033a0.png)
## Database command line
Database command line tool for web integration,Currently supports `mysql`,` mongodb` and `redis`,access by visit `http://localhost/admin/helpers/terminal/database`.
Change the database connection in the upper right corner, and then in the bottom of the input box to enter the corresponding database query and then enter, you can get the query results:
![qq20170220-3](https://cloud.githubusercontent.com/assets/1479100/23147951/ce08e5d6-f81d-11e6-8b20-605e8cd06167.png)
The use of the database and the operation of the database is consistent, you can run the selected database support query.
## Artisan command line
Web version of `Laravel`'s `artisan` command line,you can run artisan commands in it,access it by visit `http://localhost/admin/helpers/terminal/artisan`.
![qq20170220-1](https://cloud.githubusercontent.com/assets/1479100/23147963/da8a5d30-f81d-11e6-97b9-239eea900ad3.png)
## Route list
This tool can use more intuitive to show all the routes, including uri, http methods and middleware, and also you can query routes. access it by visit`http://localhost/admin/helpers/routes`.
![helpers_routes](https://user-images.githubusercontent.com/1479100/30899066-e8bdd5ca-a390-11e7-809d-4ceccd0da27f.png)

View File

@@ -0,0 +1,50 @@
# Media manager
This tool for manage local files
![wx20170809-170104](https://user-images.githubusercontent.com/1479100/29113762-99886c32-7d24-11e7-922d-5981a5849c7a.png)
## Installation
```
$ composer require laravel-admin-ext/media-manager -vvv
$ php artisan admin:import media-manager
```
## Configuration
Open `config/admin.php` specify the disk you want to manage
```php
'extensions' => [
'media-manager' => [
'disk' => 'public' // Points to the disk set in config/filesystem.php
],
],
```
`disk` is the local disk you configured in `config/filesystem.php`, visit by access `http://localhost/admin/media`.
Note If you want to preview the picture in the disk, you must set the access url in the disk configuration:
`config/filesystem.php`
```php
'disks' => [
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage', // set url
'visibility' => 'public',
],
...
]
```

View File

@@ -0,0 +1,34 @@
# Task scheduling
This tool is a web interface for manage Laravel's scheduled tasks
![wx20170810-101048](https://user-images.githubusercontent.com/1479100/29151552-8affc0b2-7db4-11e7-932a-a10d8a42ec50.png)
## Installation
```
$ composer require laravel-admin-ext/scheduling -vvv
$ php artisan admin:import scheduling
```
Then open `http://localhost/admin/scheduling`
## Add tasks
Open `app/Console/Kernel.php`, try adding two scheduled tasks:
```php
class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')->everyTenMinutes();
$schedule->command('route:list')->dailyAt('02:00');
}
}
```
And then you can see the tasks with details in the page, and you can also directly run these two tasks in the page.

View File

@@ -0,0 +1,57 @@
# Installation
> This package requires PHP 7+ and Laravel 5.5, for old versions please refer to [1.4](http://laravel-admin.org/docs/v1.4/#/)
First, install laravel, and make sure that the database connection settings are correct.
Then install require this package with command:
```
composer require encore/laravel-admin "1.5.*"
```
Publish assets and config with command
```
php artisan vendor:publish --provider="Encore\Admin\AdminServiceProvider"
```
After runnung previous command you can find config file in `config/admin.php`, in this file you can change default install directory (```/app/Admin```), db connection or table names.
At last run following command to finish install:
```
php artisan admin:install
```
To check that all is working, run `php artisan serve` and open `http://localhost/admin/` in browser, use username `admin` and password `admin` to login.
## Generated files
After the installation is complete, the following files are generated in the project directory:
### Configuration file
After the installation is complete, all configurations are in the `config/admin.php` file.
### Admin files
After install,you can find directory`app/Admin`,and then most of our develop work is under this directory.
```
app/Admin
├── Controllers
│   ├── ExampleController.php
│   └── HomeController.php
├── bootstrap.php
└── routes.php
```
`app/Admin/routes.php` is used to define routes.
`app/Admin/bootstrap.php` is bootstrapper for laravel-admin, for usage examples see comments inside it.
The `app/Admin/Controllers` directory is used to store all the controllers.
The `HomeController.php` file under this directory is used to handle home request of admin.
The `ExampleController.php` file is a controller example.
### Static assets
The front-end static files are in the `/public/packages/admin` directory.

View File

@@ -0,0 +1,103 @@
# Model form callback
`model-form` currently has three methods for receiving callback functions:
```php
// callback after form submission
$form->submitted(function (Form $form) {
//...
});
// callback before save
$form->saving(function (Form $form) {
//...
});
// callback after save
$form->saved(function (Form $form) {
//...
});
```
If required, you can add additional fields to ignore using the submitted function e.g.
```php
$form->submitted(function (Form $form) {
$form->ignore('username');
});
```
The form data that is currently submitted can be retrieved from the callback parameter `$form`:
```php
$form->saving(function (Form $form) {
dump($form->username);
});
```
Get data in model
```php
$form->saved(function (Form $form) {
$form->model()->id;
});
```
Can redirect other urls by returning an instance of `Symfony\Component\HttpFoundation\Response` directly in the callback:
```php
$form->saving(function (Form $form) {
// returns a simple response
return response('xxxx');
});
$form->saving(function (Form $form) {
// redirect url
return redirect('/admin/users');
});
$form->saving(function (Form $form) {
// throws an exception
throw new \Exception('Error friends. . .');
});
```
Return error or success information on the page:
```php
use Illuminate\Support\MessageBag;
// redirect back with an error message
$form->saving(function ($form) {
$error = new MessageBag([
'title' => 'title...',
'message' => 'message....',
]);
return back()->with(compact('error'));
});
// redirect back with a successful message
$form->saving(function ($form) {
$success = new MessageBag([
'title' => 'title...',
'message' => 'message....',
]);
return back()->with(compact('success'));
});
```

View File

@@ -0,0 +1,188 @@
# Fields management
## Remove field
The built-in `map` and `editor` fields requires the front-end files via cdn, and if there are problems with the network, they can be removed in the following ways
Locate the file `app/Admin/bootstrap.php`. If the file does not exist, update `laravel-admin` and create this file.
```php
<?php
use Encore\Admin\Form;
Form::forget('map');
Form::forget('editor');
// or
Form::forget(['map', 'editor']);
```
This removes the two fields, which can be used to remove the other fields.
## Extend the custom field
Extend a PHP code editor based on [codemirror](http://codemirror.net/index.html) with the following steps.
see [PHP mode](http://codemirror.net/mode/php/).
Download and unzip the [codemirror](http://codemirror.net/codemirror.zip) library to the front-end resource directory, for example, in the directory `public/packages/codemirror-5.20.2`.
Create a new field class `app/Admin/Extensions/PHPEditor.php`:
```php
<?php
namespace App\Admin\Extensions;
use Encore\Admin\Form\Field;
class PHPEditor extends Field
{
protected $view = 'admin.php-editor';
protected static $css = [
'/packages/codemirror-5.20.2/lib/codemirror.css',
];
protected static $js = [
'/packages/codemirror-5.20.2/lib/codemirror.js',
'/packages/codemirror-5.20.2/addon/edit/matchbrackets.js',
'/packages/codemirror-5.20.2/mode/htmlmixed/htmlmixed.js',
'/packages/codemirror-5.20.2/mode/xml/xml.js',
'/packages/codemirror-5.20.2/mode/javascript/javascript.js',
'/packages/codemirror-5.20.2/mode/css/css.js',
'/packages/codemirror-5.20.2/mode/clike/clike.js',
'/packages/codemirror-5.20.2/mode/php/php.js',
];
public function render()
{
$this->script = <<<EOT
CodeMirror.fromTextArea(document.getElementById("{$this->id}"), {
lineNumbers: true,
mode: "text/x-php",
extraKeys: {
"Tab": function(cm){
cm.replaceSelection(" " , "end");
}
}
});
EOT;
return parent::render();
}
}
```
>Static resources in the class can also be imported from outside, see [Editor.php](https://github.com/z-song/laravel-admin/blob/1.3/src/Form/Field/Editor.php)
Create a view file `resources/views/admin/php-editor.blade.php`:
```php
<div class="form-group {!! !$errors->has($label) ?: 'has-error' !!}">
<label for="{{$id}}" class="col-sm-2 control-label">{{$label}}</label>
<div class="col-sm-6">
@include('admin::form.error')
<textarea class="form-control" id="{{$id}}" name="{{$name}}" placeholder="{{ trans('admin::lang.input') }} {{$label}}" {!! $attributes !!} >{{ old($column, $value) }}</textarea>
</div>
</div>
```
Finally, find the file `app/Admin/bootstrap.php`, if the file does not exist, update `laravel-admin`, and then create this file, add the following code:
```
<?php
use App\Admin\Extensions\PHPEditor;
use Encore\Admin\Form;
Form::extend('php', PHPEditor::class);
```
And then you can use PHP editor in [model-form](/en/model-form.md):
```
$form->php('code');
```
In this way, you can add any form fields you want to add.
## Integrate CKEditor
Here is another example to show you how to integrate ckeditor.
At first download [CKEditor](http://ckeditor.com/download), unzip to public directory, for example `public/packages/ckeditor/`.
Then Write Extension class `app/Admin/Extensions/Form/CKEditor.php`:
```php
<?php
namespace App\Admin\Extensions\Form;
use Encore\Admin\Form\Field;
class CKEditor extends Field
{
public static $js = [
'/packages/ckeditor/ckeditor.js',
'/packages/ckeditor/adapters/jquery.js',
];
protected $view = 'admin.ckeditor';
public function render()
{
$this->script = "$('textarea.{$this->getElementClass()}').ckeditor();";
return parent::render();
}
}
```
Add blade file `resources/views/admin/ckeditor.blade.php` for view `admin.ckeditor` :
```php
<div class="form-group {!! !$errors->has($errorKey) ?: 'has-error' !!}">
<label for="{{$id}}" class="col-sm-2 control-label">{{$label}}</label>
<div class="col-sm-6">
@include('admin::form.error')
<textarea class="form-control {{$class}}" id="{{$id}}" name="{{$name}}" placeholder="{{ $placeholder }}" {!! $attributes !!} >{{ old($column, $value) }}</textarea>
@include('admin::form.help-block')
</div>
</div>
```
Register this extension in `app/Admin/bootstrap.php`:
```php
use Encore\Admin\Form;
use App\Admin\Extensions\Form\CKEditor;
Form::extend('ckeditor', CKEditor::class);
```
After this you can use ckeditor in your form:
```php
$form->ckeditor('content');
```

View File

@@ -0,0 +1,655 @@
# Builtin form fields
There are a lots of form components built into the `model-form` to help you quickly build forms.
## Public methods
### Set the value to save
```php
$form->text('title')->value('text...');
```
### Set default value
```php
$form->text('title')->default('text...');
```
### Set help message
```php
$form->text('title')->help('help...');
```
### Set fa-icon class
```php
$form->text('title')->icon('fa-copy');
```
### Set attributes of field element
```php
$form->text('title')->attribute(['data-title' => 'title...']);
$form->text('title')->attribute('data-title', 'title...');
```
### Set placeholder
```php
$form->text('title')->placeholder('Please input...');
```
### Model-form-tab
If the form contains too many fields, will lead to form page is too long, in which case you can use the tab to separate the form:
```php
$form->tab('Basic info', function ($form) {
$form->text('username');
$form->email('email');
})->tab('Profile', function ($form) {
$form->image('avatar');
$form->text('address');
$form->mobile('phone');
})->tab('Jobs', function ($form) {
$form->hasMany('jobs', function () {
$form->text('company');
$form->date('start_date');
$form->date('end_date');
});
})
```
## Text input
```php
$form->text($column, [$label]);
// Add a submission validation rule
$form->text($column, [$label])->rules('required|min:10');
```
## Select
```php
$form->select($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
```
If have too many options, you can load option by ajax:
```php
$form->select('user_id')->options(function ($id) {
$user = User::find($id);
if ($user) {
return [$user->id => $user->name];
}
})->ajax('/admin/api/users');
// using ajax and show selected item:
$form->select('user_id')->options(User::class)->ajax('/admin/api/users');
// or specifying the name and id
$form->select('user_id')->options(User::class, 'name', 'id')->ajax('/admin/api/users');
```
<sub>Noticeif you have modified the value of the `route.prefix` in the `config/admin.php` file, this api route should be modified to `config('admin.route.prefix').'/api/users'`.</sub>
The controller method for api `/admin/api/users` is:
```php
public function users(Request $request)
{
$q = $request->get('q');
return User::where('name', 'like', "%$q%")->paginate(null, ['id', 'name as text']);
}
```
The json returned from api `/admin/demo/options`:
```
{
"total": 4,
"per_page": 15,
"current_page": 1,
"last_page": 1,
"next_page_url": null,
"prev_page_url": null,
"from": 1,
"to": 3,
"data": [
{
"id": 9,
"text": "xxx"
},
{
"id": 21,
"text": "xxx"
},
{
"id": 42,
"text": "xxx"
},
{
"id": 48,
"text": "xxx"
}
]
}
```
### Select linkage
`select` component supports one-way linkage of parent-child relationship:
```php
$form->select('province')->options(...)->load('city', '/api/city');
$form->select('city');
```
Where `load('city', '/api/city');` means that, after the current select option is changed, the current option will call the api `/api/city` via the argument` q` api returns the data to fill the options for the city selection box, where api `/api/city` returns the data format that must match:
```php
[
{
"id": 1,
"text": "foo"
},
{
"id": 2,
"text": "bar"
},
...
]
```
The code for the controller action is as follows:
```php
public function city(Request $request)
{
$provinceId = $request->get('q');
return ChinaArea::city()->where('parent_id', $provinceId)->get(['id', DB::raw('name as text')]);
}
```
## Multiple select
```php
$form->multipleSelect($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
// using ajax and show selected items:
$form->multipleSelect($column[, $label])->options(Model::class)->ajax('ajax_url');
// or specifying the name and id
$form->multipleSelect($column[, $label])->options(Model::class, 'name', 'id')->ajax('ajax_url');
```
You can store value of multiple select in two ways, one is `many-to-many` relation.
```
class Post extends Models
{
public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
$form->multipleSelect('tags')->options(Tag::all()->pluck('name', 'id'));
```
The second is to store the option array into a single field. If the field is a string type, it is necessary to define [accessor and Mutator](https://laravel.com/docs/5.5/eloquent-mutators) for the field.
If have too many options, you can load option by ajax
```php
$form->select('user_id')->options(function ($id) {
$user = User::find($id);
if ($user) {
return [$user->id => $user->name];
}
})->ajax('/admin/api/users');
```
<sub>NoticeIf you have modified the value of the `route.prefix` in the `config/admin.php` file, this api route should be modified to `config('admin.route.prefix').'/api/users'`.</sub>
The controller method for api `/admin/api/users` is:
```php
public function users(Request $request)
{
$q = $request->get('q');
return User::where('name', 'like', "%$q%")->paginate(null, ['id', 'name as text']);
}
```
The json returned from api `/admin/demo/options`:
```
{
"total": 4,
"per_page": 15,
"current_page": 1,
"last_page": 1,
"next_page_url": null,
"prev_page_url": null,
"from": 1,
"to": 3,
"data": [
{
"id": 9,
"text": "xxx"
},
{
"id": 21,
"text": "xxx"
},
{
"id": 42,
"text": "xxx"
},
{
"id": 48,
"text": "xxx"
}
]
}
```
## Listbox
The usage is as same as mutipleSelect.
```php
$form->listbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
```
## Textarea
```php
$form->textarea($column[, $label])->rows(10);
```
## Radio
```php
$form->radio($column[, $label])->options(['m' => 'Female', 'f'=> 'Male'])->default('m');
$form->radio($column[, $label])->options(['m' => 'Female', 'f'=> 'Male'])->default('m')->stacked();
```
## Checkbox
`checkbox` can store values in two ways, see[multiple select](#Multiple select)
The `options()` method is used to set options:
```php
$form->checkbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name']);
$form->checkbox($column[, $label])->options([1 => 'foo', 2 => 'bar', 'val' => 'Option name'])->stacked();
```
## Email input
```php
$form->email($column[, $label]);
```
## Password input
```php
$form->password($column[, $label]);
```
## URL input
```php
$form->url($column[, $label]);
```
## Ip input
```php
$form->ip($column[, $label]);
```
## Phone number input
```php
$form->mobile($column[, $label])->options(['mask' => '999 9999 9999']);
```
## Color select
```php
$form->color($column[, $label])->default('#ccc');
```
## Time input
```php
$form->time($column[, $label]);
// Set the time format, more formats reference http://momentjs.com/docs/#/displaying/format/
$form->time($column[, $label])->format('HH:mm:ss');
```
## Date input
```php
$form->date($column[, $label]);
// Date format setting,more format please see http://momentjs.com/docs/#/displaying/format/
$form->date($column[, $label])->format('YYYY-MM-DD');
```
## Datetime input
```php
$form->datetime($column[, $label]);
// Set the date format, more format reference http://momentjs.com/docs/#/displaying/format/
$form->datetime($column[, $label])->format('YYYY-MM-DD HH:mm:ss');
```
## Time range select
`$startTime``$endTime`is the start and end time fields:
```php
$form->timeRange($startTime, $endTime, 'Time Range');
```
## Date range select
`$startDate``$endDate`is the start and end date fields:
```php
$form->dateRange($startDate, $endDate, 'Date Range');
```
## Datetime range select
`$startDateTime``$endDateTime` is the start and end datetime fields:
```php
$form->datetimeRange($startDateTime, $endDateTime, 'DateTime Range');
```
## Currency input
```php
$form->currency($column[, $label]);
// set the unit symbol
$form->currency($column[, $label])->symbol('¥');
```
## Number input
```php
$form->number($column[, $label]);
```
## Rate input
```php
$form->rate($column[, $label]);
```
## Image upload
Before use upload field, you must complete upload configuration, see [image/file upload](/en/model-form-upload.md).
You can use compression, crop, add watermarks and other methods, please refer to [[Intervention] (http://image.intervention.io/getting_started/introduction)], picture upload directory in the file `config / admin.php` `Upload.image` configuration, if the directory does not exist, you need to create the directory and open write permissions:
```php
$form->image($column[, $label]);
// Modify the image upload path and file name
$form->image($column[, $label])->move($dir, $name);
// Crop picture
$form->image($column[, $label])->crop(int $width, int $height, [int $x, int $y]);
// Add a watermark
$form->image($column[, $label])->insert($watermark, 'center');
// add delete button
$form->image($column[, $label])->removable();
```
## File upload
Before use upload field, you must complete upload configuration, see [image/file upload](/en/model-form-upload.md).
The file upload directory is configured in `upload.file` in the file `config/admin.php`. If the directory does not exist, it needs to be created and write-enabled.
```php
$form->file($column[, $label]);
// Modify the file upload path and file name
$form->file($column[, $label])->move($dir, $name);
// And set the upload file type
$form->file($column[, $label])->rules('mimes:doc,docx,xlsx');
// add delete button
$form->file($column[, $label])->removable();
```
## Multiple image/file upload
```php
// multiple image
$form->multipleImage($column[, $label]);
// multiple file
$form->multipleFile($column[, $label]);
// add delete button
$form->multipleFile($column[, $label])->removable();
```
The type of data submitted from multiple image/file field is array, if you the type of column in mysql table is array, or use mongodb, then you can save the array directly,
but if you use string type to store the array data ,you need to specify a string format, For example, if you want to use json string to store the array data, you need to define
a mutator for the column in model mutator, such as the field named `pictures`, define mutator:
```php
public function setPicturesAttribute($pictures)
{
if (is_array($pictures)) {
$this->attributes['pictures'] = json_encode($pictures);
}
}
public function getPicturesAttribute($pictures)
{
return json_decode($pictures, true);
}
```
Of course, you can also specify any other format.
## Map
The map field refers to the network resource, and if there is a problem with the network refer to [form Component Management](/en/model-form-field-management.md) to remove the component.
Used to select the latitude and longitude, `$ latitude`,` $ longitude` for the latitude and longitude field, using Tencent map when `locale` set of laravel is` zh_CN`, otherwise use Google Maps:
```php
$form->map($latitude, $longitude, $label);
// Use Tencent map
$form->map($latitude, $longitude, $label)->useTencentMap();
// Use google map
$form->map($latitude, $longitude, $label)->useGoogleMap();
```
## Slider
Can be used to select the type of digital fields, such as age:
```php
$form->slider($column[, $label])->options(['max' => 100, 'min' => 1, 'step' => 1, 'postfix' => 'years old']);
```
More options please ref to https://github.com/IonDen/ion.rangeSlider#settings
## Rich text editor
The editor field refers to the network resource, and if there is a problem with the network refer to [form Component Management](/en/model-form-field-management.md) to remove the component.
```php
$form->editor($column[, $label]);
```
## Hidden field
```php
$form->hidden($column);
```
## Switch
`On` and` off` pairs of switches with the values `1` and` 0`:
```php
$states = [
'on' => ['value' => 1, 'text' => 'enable', 'color' => 'success'],
'off' => ['value' => 0, 'text' => 'disable', 'color' => 'danger'],
];
$form->switch($column[, $label])->states($states);
```
## Display field
Only display the fields and without any action:
```php
$form->display($column[, $label]);
```
## Divide
```php
$form->divide();
```
## Html
insert html,the argument passed in could be objects which impletements `Htmlable``Renderable`, or has method `__toString()`
```php
$form->html('html contents');
```
## Tags
Insert the comma (,) separated string `tags`
```php
$form->tags('keywords');
```
## Icon
Select the `font-awesome` icon.
```php
$form->icon('icon');
```
## HasMany
One-to-many built-in tables for dealing with one-to-many relationships. Here is a simple example:
There are two tables are one-to-many relationship:
```sql
CREATE TABLE `demo_painters` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`bio` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `demo_paintings` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`painter_id` int(10) unsigned NOT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`body` text COLLATE utf8_unicode_ci NOT NULL,
`completed_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY painter_id (`painter_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
```
The model of tables are:
```php
<?php
namespace App\Models\Demo;
use Illuminate\Database\Eloquent\Model;
class Painter extends Model
{
public function paintings()
{
return $this->hasMany(Painting::class, 'painter_id');
}
}
<?php
namespace App\Models\Demo;
use Illuminate\Database\Eloquent\Model;
class Painting extends Model
{
protected $fillable = ['title', 'body', 'completed_at'];
public function painter()
{
return $this->belongsTo(Painter::class, 'painter_id');
}
}
```
Build the form code as follows:
```php
$form->display('id', 'ID');
$form->text('username')->rules('required');
$form->textarea('bio')->rules('required');
$form->hasMany('paintings', function (Form\NestedForm $form) {
$form->text('title');
$form->image('body');
$form->datetime('completed_at');
});
$form->display('created_at', 'Created At');
$form->display('updated_at', 'Updated At');
```
## Embeds
Used to handle the `JSON` type field data of `mysql` or `object` type data of `mongodb`, or the data values of multiple fields can be stored in the form of the` JSON` string in the character type of mysql
Such as the `extra` column of the `JSON` or string type in the orders table, used to store data for multiple fields:
```php
class Order extends Model
{
protected $casts = [
'extra' => 'json',
];
}
```
And then use in the form:
```php
$form->embeds('extra', function ($form) {
$form->text('extra1')->rules('required');
$form->email('extra2')->rules('required');
$form->mobile('extra3');
$form->datetime('extra4');
$form->dateRange('extra5', 'extra6', 'Date range')->rules('required');
});
// Customize the title
$form->embeds('extra', 'Extra', function ($form) {
...
});
```
Callback function inside the form element to create the method call and the outside is the same.

View File

@@ -0,0 +1,115 @@
# File/Image upload
[model-form](/en/model-form.md) can build file and image upload field with following codes
```php
$form->file('file_column');
$form->image('image_column');
```
### Change store path and name
```php
// change upload path
$form->image('picture')->move('public/upload/image1/');
// use a unique name (md5(uniqid()).extension)
$form->image('picture')->uniqueName();
// specify filename
$form->image('picture')->name(function ($file) {
return 'test.'.$file->guessExtension();
});
```
[model-form](/en/model-form.md) both support for local and cloud storage upload
### Upload to local
first add storage configuration, add a disk in `config/filesystems.php`:
```php
'disks' => [
... ,
'admin' => [
'driver' => 'local',
'root' => public_path('uploads'),
'visibility' => 'public',
'url' => env('APP_URL').'/uploads',
],
],
```
set upload path to `public/upload`(public_path('upload')).
And then in `config/admin.php` select the `disk` set up above
```php
'upload' => [
'disk' => 'admin',
'directory' => [
'image' => 'image',
'file' => 'file',
],
],
```
Set `disk` to the` admin` that you added above,`directory.image` and `directory.file` is the upload path for `$form->image($column)` and `$form->file($column)`.
`host` is url prefix for your uploaded files.
### Upload to cloud
If you need to upload to the cloud storage, need to install a driver which supports `flysystem` adapter, take `qiniu` cloud storage as example.
first install [zgldh/qiniu-laravel-storage](https://github.com/zgldh/qiniu-laravel-storage).
Also configure the disk, in the `config/filesystems.php` add an item:
```php
'disks' => [
... ,
'qiniu' => [
'driver' => 'qiniu',
'domains' => [
'default' => 'xxxxx.com1.z0.glb.clouddn.com',
'https' => 'dn-yourdomain.qbox.me',
'custom' => 'static.abc.com',
],
'access_key'=> '', //AccessKey
'secret_key'=> '', //SecretKey
'bucket' => '', //Bucket
'notify_url'=> '', //
'url' => 'http://of8kfibjo.bkt.clouddn.com/',
],
],
```
Then modify the upload configuration of `laravel-admin` and open `config/admin.php` to find:
```php
'upload' => [
'disk' => 'qiniu',
'directory' => [
'image' => 'image',
'file' => 'file',
],
],
```
Select the above configuration` qiniu` for `disk`

View File

@@ -0,0 +1,36 @@
Form validation
========
`model-form` uses laravel's validation rules to verify the data submitted by the form:
```php
$form->text('title')->rules('required|min:3');
// Complex validation rules can be implemented in the callback
$form->text('title')->rules(function ($form) {
// If it is not an edit state, add field unique verification
if (!$id = $form->model()->id) {
return 'unique:users,email_address';
}
});
```
You can also customize the error message for the validation rule:
```php
$form->text('code')->rules('required|regex:/^\d+$/|min:10', [
'regex' => 'code must be numbers',
'min' => 'code can not be less than 10 characters',
]);
```
If you want to allow the field to be empty, first in the database table to face the field set to `NULL`, and then
```php
$form->text('title')->rules('nullable');
```
Please refer to the more rules [Validation](https://laravel.com/docs/5.5/validation).

View File

@@ -0,0 +1,179 @@
# Model-Form
The `Encore\Admin\Form` class is used to generate a data model-based form. For example, there is a` movies` table in the database
```sql
CREATE TABLE `movies` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`director` int(10) unsigned NOT NULL,
`describe` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`rate` tinyint unsigned NOT NULL,
`released` enum(0, 1),
`release_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
```
The corresponding data model is `App\Models\Movie`, and the following code can generate the` movies` data form:
```php
use App\Models\Movie;
use Encore\Admin\Form;
use Encore\Admin\Facades\Admin;
$grid = Admin::form(Movie::class, function(Form $grid){
// Displays the record id
$form->display('id', 'ID');
// Add an input box of type text
$form->text('title', 'Movie title');
$directors = [
1 => 'John',
2 => 'Smith',
3 => 'Kate',
];
$form->select('director', 'Director')->options($directors);
// Add textarea for the describe field
$form->textarea('describe', 'Describe');
// Number input
$form->number('rate', 'Rate');
// Add a switch field
$form->switch('released', 'Released?');
// Add a date and time selection box
$form->dateTime('release_at', 'release time');
// Display two time column
$form->display('created_at', 'Created time');
$form->display('updated_at', 'Updated time');
});
```
## Custom tools
The top right corner of the form has two button tools by default. You can modify it in the following way:
```php
$form->tools(function (Form\Tools $tools) {
// Disable back btn.
$tools->disableBackButton();
// Disable list btn
$tools->disableListButton();
// Add a button, the argument can be a string, or an instance of the object that implements the Renderable or Htmlable interface
$tools->add('<a class="btn btn-sm btn-danger"><i class="fa fa-trash"></i>&nbsp;&nbsp;delete</a>');
});
```
## Other methods
Disable submit btn:
```php
$form->disableSubmit();
```
Disable reset btn:
```php
$form->disableReset();
```
Ignore fields to store
```php
$form->ignore('column1', 'column2', 'column3');
```
Set width for label and field
```php
$form->setWidth(10, 2);
```
Set form action
```php
$form->setAction('admin/users');
```
## Model relationship
### One to One
The `users` table and the `profiles` table are generated one-to-one relation through the `profiles.user_id` field.
```sql
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`age` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
```
The corresponding data model are:
```php
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
class Profile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
```
You can associate them in a form with the following code:
```php
Admin::form(User::class, function (Form $form) {
$form->display('id');
$form->text('name');
$form->text('email');
$form->text('profile.age');
$form->text('profile.gender');
$form->datetime('created_at');
$form->datetime('updated_at');
});
```

View File

@@ -0,0 +1,105 @@
# Model grid row actions
`model-grid` By default, there are two actions `edit` and `delete`, which can be turned off in the following way:
```php
$grid->actions(function ($actions) {
$actions->disableDelete();
$actions->disableEdit();
});
```
You can get the data for the current row by `$actions` parameter passed in:
```php
$grid->actions(function ($actions) {
// the array of data for the current row
$actions->row;
// gets the current row primary key value
$actions->getKey();
});
```
If you have a custom action button, you can add the following:
```php
$grid->actions(function ($actions) {
// append an action.
$actions->append('<a href=""><i class="fa fa-eye"></i></a>');
// prepend an action.
$actions->prepend('<a href=""><i class="fa fa-paper-plane"></i></a>');
}
```
If you have more complex actions, you can refer to the following ways:
First define the action class:
```php
<?php
namespace App\Admin\Extensions;
use Encore\Admin\Admin;
class CheckRow
{
protected $id;
public function __construct($id)
{
$this->id = $id;
}
protected function script()
{
return <<<SCRIPT
$('.grid-check-row').on('click', function () {
// Your code.
console.log($(this).data('id'));
});
SCRIPT;
}
protected function render()
{
Admin::script($this->script());
return "<a class='btn btn-xs btn-success fa fa-check grid-check-row' data-id='{$this->id}'></a>";
}
public function __toString()
{
return $this->render();
}
}
```
Then add the action:
```php
$grid->actions(function ($actions) {
// add action
$actions->append(new CheckRow($actions->getKey()));
}
```
Row manipulations with column conditions:
For row attributes, you can use `$row->model()` array or `$row->column()` method.
You need to set style after setting attributes. Otherwise style method will be by-passed
```php
$grid->rows(function ($row) {
// if relased column value is Yes
if ( $row->column('released') == 'Yes' ) {
// Set attributes for row.
$row->setAttributes([ 'data-row-id' => $row->model()['id'], 'data-row-date' => $row->column('release_date') ]);
// Set style of row
$row->style("background-color:green");
}
});
```

View File

@@ -0,0 +1,335 @@
# Model-grid column
`model-grid` built-in a lot of the operation of the column, you can use these methods very flexible operation of the column data.
The `Encore\Admin\Grid\Column` object has a built-in `display()` method to handle the value of the current column through the incoming callback function:
```php
$grid->column('title')->display(function ($title) {
return "<span style='color:blue'>$title</span>";
});
```
The `display` callback bound to the current row data object as a parent object, you can use the data in current row by this way:
```php
$grid->first_name();
$grid->last_name();
$grid->column('full_name')->display(function () {
return $this->first_name . ' ' . $this->last_name;
});
```
> method `value()` is a alias to method `display()`.
## Built-in methods
`model-grid` has built-in methods to help you extend the column functionality
### editable
With the help of `editable.js`, you can edit the data in the grid directly:
```php
$grid->title()->editable();
$grid->title()->editable('textarea');
$grid->title()->editable('select', [1 => 'option1', 2 => 'option2', 3 => 'option3']);
$grid->birth()->editable('date');
$grid->published_at()->editable('datetime');
$grid->column('year')->editable('year');
$grid->column('month')->editable('month');
$grid->column('day')->editable('day');
```
### switch
> notice: If set up a switch for a column the grid, then need to set the column in the form of the same switch
Quickly turn a column into a switch component using the following methods:
```php
$grid->status()->switch();
// set the `text`、`color`、and `value`
$states = [
'on' => ['value' => 1, 'text' => 'YES', 'color' => 'primary'],
'off' => ['value' => 2, 'text' => 'NO', 'color' => 'default'],
];
$grid->status()->switch($states);
```
### switchGroup
> notice: If set up switch for some columns the grid, then need to set these columns in the form of the same switch
To quickly change a column into a switch component group, use the following method:
```php
$states = [
'on' => ['text' => 'YES'],
'off' => ['text' => 'NO'],
];
$grid->column('switch_group')->switchGroup([
'hot' => 'Hot',
'new' => 'New',
'recommend' => 'Recommend',
], $states);
```
### select
```php
$grid->options()->select([
1 => 'Sed ut perspiciatis unde omni',
2 => 'voluptatem accusantium doloremque',
3 => 'dicta sunt explicabo',
4 => 'laudantium, totam rem aperiam',
]);
```
### radio
```php
$grid->options()->radio([
1 => 'Sed ut perspiciatis unde omni',
2 => 'voluptatem accusantium doloremque',
3 => 'dicta sunt explicabo',
4 => 'laudantium, totam rem aperiam',
]);
```
### checkbox
```php
$grid->options()->checkbox([
1 => 'Sed ut perspiciatis unde omni',
2 => 'voluptatem accusantium doloremque',
3 => 'dicta sunt explicabo',
4 => 'laudantium, totam rem aperiam',
]);
```
### image
```php
$grid->picture()->image();
//Set host, width and height
$grid->picture()->image('http://xxx.com', 100, 100);
// display multiple images
$grid->pictures()->display(function ($pictures) {
return json_decode($pictures, true);
})->image('http://xxx.com', 100, 100);
```
### label
```php
$grid->name()->label();
//Set color,defaults to `success`, other options `danger`、`warning`、`info`、`primary`、`default`、`success`
$grid->name()->label('danger');
// can handle a array
$grid->keywords()->label();
```
### badge
```php
$grid->name()->badge();
//Set color,defaults to `success`, other options `danger`、`warning`、`info`、`primary`、`default`、`success`
$grid->name()->badge('danger');
// can handle a array
$grid->keywords()->badge();
```
## Extend the column
There are two ways to extend the column function, the first one is through the anonymous function.
Add following code to `app/Admin/bootstrap.php`:
```php
use Encore\Admin\Grid\Column;
Column::extend('color', function ($value, $color) {
return "<span style='color: $color'>$value</span>";
});
```
Use this extension in `model-grid`:
```php
$grid->title()->color('#ccc');
```
If the column display logic is more complex, you can implement with an extension class.
Extension class `app/Admin/Extensions/Popover.php`:
```php
<?php
namespace App\Admin\Extensions;
use Encore\Admin\Admin;
use Encore\Admin\Grid\Displayers\AbstractDisplayer;
class Popover extends AbstractDisplayer
{
public function display($placement = 'left')
{
Admin::script("$('[data-toggle=\"popover\"]').popover()");
return <<<EOT
<button type="button"
class="btn btn-secondary"
title="popover"
data-container="body"
data-toggle="popover"
data-placement="$placement"
data-content="{$this->value}"
>
Popover
</button>
EOT;
}
}
```
And then register the extension in `app/Admin/bootstrap.php`
```php
use Encore\Admin\Grid\Column;
use App\Admin\Extensions\Popover;
Column::extend('popover', Popover::class);
```
Use the extension in `model-grid`
```php
$grid->desciption()->popover('right');
```
## helpers
### String operations
If the current output data is a string, you can call the method of class `Illuminate\Support\Str`.
For example, the following column shows the string value of the `title` field:
```php
$grid->title();
```
Call `Str::limit()` on `title` colum.
Can call `Str::limit()` method on the output string of the `title` column.
```php
$grid->title()->limit(30);
```
Continue to call `Illuminate\Support\Str` method:
```php
$grid->title()->limit(30)->ucfirst();
$grid->title()->limit(30)->ucfirst()->substr(1, 10);
```
### Array operations
If the current output data is a array, you can call the method of class `Illuminate\Support\Collection`.
For example, the `tags` column is an array of data retrieved from a one-to-many relationship:
```php
$grid->tags();
array (
0 =>
array (
'id' => '16',
'name' => 'php',
'created_at' => '2016-11-13 14:03:03',
'updated_at' => '2016-12-25 04:29:35',
),
1 =>
array (
'id' => '17',
'name' => 'python',
'created_at' => '2016-11-13 14:03:09',
'updated_at' => '2016-12-25 04:30:27',
),
)
```
Call the `Collection::pluck()` method to get the `name` column from the array
```php
$grid->tags()->pluck('name');
array (
0 => 'php',
1 => 'python',
),
```
The output data is still a array after above, so you can call methods of `Illuminate\Support\Collection` continue.
```php
$grid->tags()->pluck('name')->map('ucwords');
array (
0 => 'Php',
1 => 'Python',
),
```
Outputs the array as a string
```php
$grid->tags()->pluck('name')->map('ucwords')->implode('-');
"Php-Python"
```
### Mixed use
In the above two types of method calls, as long as the output of the previous step is to determine the type of value, you can call the corresponding type of method, it can be very flexible mix.
For example, the `images` field is a JSON-formatted string type that stores a multiple-picture address array:
```php
$grid->images();
"['foo.jpg', 'bar.png']"
// chain method calls to display multiple images
$grid->images()->display(function ($images) {
return json_decode($images, true);
})->map(function ($path) {
return 'http://localhost/images/'. $path;
})->image();
```

View File

@@ -0,0 +1,175 @@
# Custom tools
`model-grid` has `batch delete` and `refresh` operations tools as default, `model-grid` provides custom tool functionality if there are more operational requirements, the following example will show you how to add a `Gender selector` button group tool.
First define the tool class `app/Admin/Extensions/Tools/UserGender.php`
```php
<?php
namespace App\Admin\Extensions\Tools;
use Encore\Admin\Admin;
use Encore\Admin\Grid\Tools\AbstractTool;
use Illuminate\Support\Facades\Request;
class UserGender extends AbstractTool
{
protected function script()
{
$url = Request::fullUrlWithQuery(['gender' => '_gender_']);
return <<<EOT
$('input:radio.user-gender').change(function () {
var url = "$url".replace('_gender_', $(this).val());
$.pjax({container:'#pjax-container', url: url });
});
EOT;
}
public function render()
{
Admin::script($this->script());
$options = [
'all' => 'All',
'm' => 'Male',
'f' => 'Female',
];
return view('admin.tools.gender', compact('options'));
}
}
```
The blade file of view `admin.tools.gender` is `resources/views/admin/tools/gender.blade.php`:
```php
<div class="btn-group" data-toggle="buttons">
@foreach($options as $option => $label)
<label class="btn btn-default btn-sm {{ \Request::get('gender', 'all') == $option ? 'active' : '' }}">
<input type="radio" class="user-gender" value="{{ $option }}">{{$label}}
</label>
@endforeach
</div>
```
Import this tool in `model-grid`
```php
$grid->tools(function ($tools) {
$tools->append(new UserGender());
});
```
In the `model-grid`, pass `gender` query to model
```php
if (in_array(Request::get('gender'), ['m', 'f'])) {
$grid->model()->where('gender', Request::get('gender'));
}
```
You can refer to the above way to add your own tools.
## Batch operation
At present, the default implementation of the batch delete operation, if you want to turn off the batch delete operation:
```php
$grid->tools(function ($tools) {
$tools->batch(function ($batch) {
$batch->disableDelete();
});
});
```
If you want to add a custom batch operation, you can refer to the following example.
The following example will show you how to implements a `post batch release` operation:
First define the tool class `app/Admin/Extensions/Tools/ReleasePost.php`
```php
<?php
namespace App\Admin\Extensions\Tools;
use Encore\Admin\Grid\Tools\BatchAction;
class ReleasePost extends BatchAction
{
protected $action;
public function __construct($action = 1)
{
$this->action = $action;
}
public function script()
{
return <<<EOT
$('{$this->getElementClass()}').on('click', function() {
$.ajax({
method: 'post',
url: '{$this->resource}/release',
data: {
_token:LA.token,
ids: selectedRows(),
action: {$this->action}
},
success: function () {
$.pjax.reload('#pjax-container');
toastr.success('操作成功');
}
});
});
EOT;
}
}
```
See the code above, use ajax to pass the selected `ids` to back-end api through a POST request, the back-end api modifies the state of the corresponding data according to the received `ids`, and then front-end refresh the page (pjax reload), and pop-up a `toastr` prompt operation is successful.
Import this operation in `model-grid`
```php
$grid->tools(function ($tools) {
$tools->batch(function ($batch) {
$batch->add('Release post', new ReleasePost(1));
$batch->add('Unrelease post', new ReleasePost(0));
});
});
```
So that the batch operation of the drop-down button will add the following two operations, the final step is to add an api to handle the request of the batch operation, the api code is as follows:
```php
class PostController extends Controller
{
...
public function release(Request $request)
{
foreach (Post::find($request->get('ids')) as $post) {
$post->released = $request->get('action');
$post->save();
}
}
...
}
```
Then add a route for the api above:
```php
$router->post('posts/release', 'PostController@release');
```
This completes the entire process.

View File

@@ -0,0 +1,57 @@
Data export
=======
`model-grid` built-in export function is to achieve a simple csv format file export, if you encounter a file coding problem or can not meet their own needs, you can follow the steps below to customize the export function
This example uses [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel) as an excel library, and of course you can use any other excel library.
First install it:
```shell
composer require maatwebsite/excel:~2.1.0
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"
```
And then create a new custom export class, such as `app/Admin/Extensions/ExcelExpoter.php`:
```php
<?php
namespace App\Admin\Extensions;
use Encore\Admin\Grid\Exporters\AbstractExporter;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Arr;
class ExcelExpoter extends AbstractExporter
{
public function export()
{
Excel::create('Filename', function($excel) {
$excel->sheet('Sheetname', function($sheet) {
// This logic get the columns that need to be exported from the table data
$rows = collect($this->getData())->map(function ($item) {
return Arr::only($item, ['id', 'title', 'content', 'rate', 'keywords']);
});
$sheet->rows($rows);
});
})->export('xls');
}
}
```
And then use this class in `model-grid`:
```php
use App\Admin\Extensions\ExcelExpoter;
$grid->exporter(new ExcelExpoter());
```
For more information on how to use `Laravel-Excel`, refer to [laravel-excel/docs](http://www.maatwebsite.nl/laravel-excel/docs)

View File

@@ -0,0 +1,258 @@
# Model grid filters
`model-grid`Provides a set of data filters:
```php
$grid->filter(function($filter){
// Remove the default id filter
$filter->disableIdFilter();
// Add a column filter
$filter->like('name', 'name');
...
});
```
## Filter type
Currently supported filter types are the following:
### Equal
`sql: ... WHERE `column` = ""$input""`
```php
$filter->equal('column', $label);
```
### Not equal
`sql: ... WHERE `column` != ""$input""`
```php
$filter->notEqual('column', $label);
```
### Like
`sql: ... WHERE `column` LIKE "%"$input"%"`
```php
$filter->like('column', $label);
```
### Ilike
`sql: ... WHERE `column` ILIKE "%"$input"%"`
```php
$filter->ilike('column', $label);
```
### Greater then
`sql: ... WHERE `column` > "$input"`
```php
$filter->gt('column', $label);
```
### Less than
`sql: ... WHERE `column` < "$input"`
```php
$filter->lt('column', $label);
```
### Between
`sql: ... WHERE `column` BETWEEN "$start" AND "$end"`
```php
$filter->between('column', $label);
// set datetime field type
$filter->between('column', $label)->datetime();
// set time field type
$filter->between('column', $label)->time();
```
### In
`sql: ... WHERE `column` in (...$inputs)`
```php
$filter->in('column', $label)->multipleSelect(['key' => 'value']);
```
### NotIn
`sql: ... WHERE `column` not in (...$inputs)`
```php
$filter->notIn('column', $label)->multipleSelect(['key' => 'value']);
```
### Date
`sql: ... WHERE DATE(`column`) = "$input"`
```php
$filter->date('column', $label);
```
### Day
`sql: ... WHERE DAY(`column`) = "$input"`
```php
$filter->day('column', $label);
```
### Month
`sql: ... WHERE MONTH(`column`) = "$input"`
```php
$filter->month('column', $label);
```
### year
`sql: ... WHERE YEAR(`column`) = "$input"`
```php
$filter->year('column', $label);
```
### Where
You can use `where` to build more complex query filtering
`sql: ... WHERE `title` LIKE "%$input" OR `content` LIKE "%$input"`
```php
$filter->where(function ($query) {
$query->where('title', 'like', "%{$this->input}%")
->orWhere('content', 'like', "%{$this->input}%");
}, 'Text');
```
`sql: ... WHERE `rate` >= 6 AND `created_at` = {$input}`:
```php
$filter->where(function ($query) {
$query->whereRaw("`rate` >= 6 AND `created_at` = {$this->input}");
}, 'Text');
```
Relationship query, query the corresponding relationship `profile` field:
```php
$filter->where(function ($query) {
$query->whereHas('profile', function ($query) {
$query->where('address', 'like', "%{$this->input}%")->orWhere('email', 'like', "%{$this->input}%");
});
}, 'Address or mobile');
```
## Field type
The default field type is text input, set placeholder for text input:
```php
$filter->equal('column')->placeholder('Please input...');
```
You can also restrict the user input format by using some of the following methods:
```php
$filter->equal('column')->url();
$filter->equal('column')->email();
$filter->equal('column')->integer();
$filter->equal('column')->ip();
$filter->equal('column')->mac();
$filter->equal('column')->mobile();
// $options refer to https://github.com/RobinHerbots/Inputmask/blob/4.x/README_numeric.md
$filter->equal('column')->decimal($options = []);
// $options refer to https://github.com/RobinHerbots/Inputmask/blob/4.x/README_numeric.md
$filter->equal('column')->currency($options = []);
// $options refer to https://github.com/RobinHerbots/Inputmask/blob/4.x/README_numeric.md
$filter->equal('column')->percentage($options = []);
// $options refer to https://github.com/RobinHerbots/Inputmask
$filter->equal('column')->inputmask($options = [], $icon = 'pencil');
```
### Select
```php
$filter->equal('column')->select(['key' => 'value'...]);
// Or from the api to obtain data, api format reference model-form `select` component
$filter->equal('column')->select('api/users');
```
### multipleSelect
Generally used in conjunction with `in` and` notIn` need to query the array of two types of inquiries can also be used in the `type` type of query:
```php
$filter->in('column')->multipleSelect(['key' => 'value'...]);
// // Or from the api to obtain data, api format reference model-form `multipleSelect` component
$filter->in('column')->multipleSelect('api/users');
```
### radio
The more common scenario is the selection of categories
```php
$filter->equal('released')->radio([
'' => 'All',
0 => 'Unreleased',
1 => 'Released',
]);
```
### checkbox
The more common scene is do the scope query with `whereIn`:
```php
$filter->in('gender')->checkbox([
'm' => 'Male',
'f' => 'Female',
]);
```
### datetime
Use date and time components,`$options` parameter and value reference [bootstrap-datetimepicker](http://eonasdan.github.io/bootstrap-datetimepicker/Options/)
```php
$filter->equal('column')->datetime($options);
// `date()` equals to `datetime(['format' => 'YYYY-MM-DD'])`
$filter->equal('column')->date();
// `time()` equals to `datetime(['format' => 'HH:mm:ss'])`
$filter->equal('column')->time();
// `day()` equals to `datetime(['format' => 'DD'])`
$filter->equal('column')->day();
// `month()` equals to `datetime(['format' => 'MM'])`
$filter->equal('column')->month();
// `year()` equals to `datetime(['format' => 'YYYY'])`
$filter->equal('column')->year();
```
## Complex query filter
You can use the `$this->input` to trigger complex custom queries:
```php
$filter->where(function ($query) {
switch ($this->input) {
case 'yes':
// custom complex query if the 'yes' option is selected
$query->has('somerelationship');
break;
case 'no':
$query->doesntHave('somerelationship');
break;
}
}, 'Label of the field', 'name_for_url_shortcut')->radio([
'' => 'All',
'yes' => 'Only with relationship',
'no' => 'Only without relationship',
]);
```

View File

@@ -0,0 +1,410 @@
# Model-grid
Class `Encore\Admin\Grid` is used to generate tables based on the data model,for example,we have a table `movies` in database:
```sql
CREATE TABLE `movies` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`director` int(10) unsigned NOT NULL,
`describe` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`rate` tinyint unsigned NOT NULL,
`released` enum(0, 1),
`release_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
```
And the model of this table is `App\Models\Movie`,The following code can generate the data grid for table `movies`:
```php
use App\Models\Movie;
use Encore\Admin\Grid;
use Encore\Admin\Facades\Admin;
$grid = Admin::grid(Movie::class, function(Grid $grid){
// The first column displays the id field and sets the column as a sortable column
$grid->id('ID')->sortable();
// The second column shows the title field, because the title field name and the Grid object's title method conflict, so use Grid's column () method instead
$grid->column('title');
// The third column shows the director field, which is set by the display($callback) method to display the corresponding user name in the users table
$grid->director()->display(function($userId) {
return User::find($userId)->name;
});
// The fourth column appears as the describe field
$grid->describe();
// The fifth column is displayed as the rate field
$grid->rate();
// The sixth column shows the released field, formatting the display output through the display($callback) method
$grid->released('Release?')->display(function ($released) {
return $released ? 'yes' : 'no';
});
// The following shows the columns for the three time fields
$grid->release_at();
$grid->created_at();
$grid->updated_at();
// The filter($callback) method is used to set up a simple search box for the table
$grid->filter(function ($filter) {
// Sets the range query for the created_at field
$filter->between('created_at', 'Created Time')->datetime();
});
});
```
## Basic Usage
#### Add a column
```php
// Add the column directly through the field name `username`
$grid->username('Username');
// The effect is the same as above
$grid->column('username', 'Username');
// Add multiple columns
$grid->columns('email', 'username' ...);
```
#### Modify the source data
```php
$grid->model()->where('id', '>', 100);
$grid->model()->orderBy('id', 'desc');
$grid->model()->take(100);
```
#### Sets the number of lines displayed per page
```php
// The default is 15 per page
$grid->paginate(20);
```
#### Modify the display output of column
```php
use Illuminate\Support\Str;
$grid->text()->display(function($text) {
return Str::limit($text, 30, '...');
});
$grid->name()->display(function ($name) {
return "<span class='label'>$name</span>";
});
$grid->email()->display(function ($email) {
return "mailto:$email";
});
// column not in table
$grid->column('column_not_in_table')->display(function () {
return 'blablabla....';
});
```
The closure passed to method `display()` is bind to row data object, you can use other column data in current row.
```php
$grid->first_name();
$grid->last_name();
// column not in table
$grid->column('full_name')->display(function () {
return $this->first_name.' '.$this->last_name;
});
```
#### Disable the create button
```php
$grid->disableCreateButton();
```
#### Disable Pagination
```php
$grid->disablePagination();
```
#### Disable all tools on header of grid. Filter, refresh, export, batch actions
```php
$grid->disableTools();
```
#### Disable data filter
```php
$grid->disableFilter();
```
#### Disable the export button
```php
$grid->disableExport();
```
#### Disable row selector
```php
$grid->disableRowSelector();
```
#### Disable row actions
```php
$grid->disableActions();
```
#### Enable orderable grid
```php
$grid->orderable();
```
#### Set options for perPage selector
```php
$grid->perPages([10, 20, 30, 40, 50]);
```
## Relation
### One to one
The `users` table and the `profiles` table are generated one-to-one relation through the `profiles.user_id` field.
```sql
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`age` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
```
The corresponding data model are:
```php
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class);
}
}
class Profile extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
```
You can associate them in a grid with the following code:
```php
Admin::grid(User::class, function (Grid $grid) {
$grid->id('ID')->sortable();
$grid->name();
$grid->email();
$grid->column('profile.age');
$grid->column('profile.gender');
//or
$grid->profile()->age();
$grid->profile()->gender();
$grid->created_at();
$grid->updated_at();
});
```
### One to many
The `posts` and `comments` tables generate a one-to-many association via the `comments.post_id` field
```sql
CREATE TABLE `posts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`content` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `comments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`post_id` int(10) unsigned NOT NULL,
`content` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
```
The corresponding data model are:
```php
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Comment extends Model
{
public function post()
{
return $this->belongsTo(Post::class);
}
}
```
You can associate them in a grid with the following code:
```php
return Admin::grid(Post::class, function (Grid $grid) {
$grid->id('id')->sortable();
$grid->title();
$grid->content();
$grid->comments('Comments count')->display(function ($comments) {
$count = count($comments);
return "<span class='label label-warning'>{$count}</span>";
});
$grid->created_at();
$grid->updated_at();
});
return Admin::grid(Comment::class, function (Grid $grid) {
$grid->id('id');
$grid->post()->title();
$grid->content();
$grid->created_at()->sortable();
$grid->updated_at();
});
```
### Many to many
The `users` and` roles` tables produce a many-to-many relationship through the pivot table `role_user`
```sql
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(190) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_username_unique` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `roles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`slug` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `roles_name_unique` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `role_users` (
`role_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
KEY `role_users_role_id_user_id_index` (`role_id`,`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
```
The corresponding data model are:
```php
class User extends Model
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
```
You can associate them in a grid with the following code:
```php
return Admin::grid(User::class, function (Grid $grid) {
$grid->id('ID')->sortable();
$grid->username();
$grid->name();
$grid->roles()->display(function ($roles) {
$roles = array_map(function ($role) {
return "<span class='label label-success'>{$role['name']}</span>";
}, $roles);
return join('&nbsp;', $roles);
});
$grid->created_at();
$grid->updated_at();
});
```

View File

@@ -0,0 +1,124 @@
# Model-tree
Can be achieved through a `model-tree` to a tree-like components, you can drag the way to achieve the level of data, sorting and other operations, the following is the basic usage.
## Table structure and model
To use `model-tree`, you have to follow the convention of the table structure:
```sql
CREATE TABLE `demo_categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL DEFAULT '0',
`order` int(11) NOT NULL DEFAULT '0',
`title` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
```
The above table structure has three necessary fields `parent_id`, `order`, `title`, and the other fields are not required.
The corresponding model is `app/Models/Category.php`:
```php
<?php
namespace App\Models\Demo;
use Encore\Admin\Traits\AdminBuilder;
use Encore\Admin\Traits\ModelTree;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use ModelTree, AdminBuilder;
protected $table = 'demo_categories';
}
```
Table structure in the three fields `parent_id`,` order`, `title` field name can be amended:
```php
<?php
namespace App\Models\Demo;
use Encore\Admin\Traits\AdminBuilder;
use Encore\Admin\Traits\ModelTree;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use ModelTree, AdminBuilder;
protected $table = 'demo_categories';
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->setParentColumn('pid');
$this->setOrderColumn('sort');
$this->setTitleColumn('name');
}
}
```
## Usage
然后就是在页面中使用`model-tree`了:
Then use `model-tree` in your page
```php
<?php
namespace App\Admin\Controllers\Demo;
use App\Http\Controllers\Controller;
use App\Models\Category;
use Encore\Admin\Form;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Layout\Content;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Tree;
class CategoryController extends Controller
{
use ModelForm;
public function index()
{
return Admin::content(function (Content $content) {
$content->header('Categories');
$content->body(Category::tree());
});
}
}
```
You can modify the display of branch in the following ways:
```php
Category::tree(function ($tree) {
$tree->branch(function ($branch) {
$src = config('admin.upload.host') . '/' . $branch['logo'] ;
$logo = "<img src='$src' style='max-width:30px;max-height:30px' class='img'/>";
return "{$branch['id']} - {$branch['title']} $logo";
});
})
```
The `$branch` parameter is array of current row data.
If you want to modify the query of the model, use the following way:
```php
Category::tree(function ($tree) {
$tree->query(function ($model) {
return $model->where('type', 1);
});
})
```

View File

@@ -0,0 +1,141 @@
# Access Control
`laravel-admin` has built-in` RBAC` permissions control module, expand the left sidebar `Auth`, you can see user, permissions and roles management panel, the use of permissions control as follows:
## Route permission
In the `laravel-admin 1.5`, the permissions and routes are bound together, in the edit permission page which set the current permissions can access the routing, in the `HTTP method` select box to select the method of access to the path, in the `HTTP path` textarea fill in the path to access.
For example, to add a permission, the permission can access the path `/admin/users` in GET method, then `HTTP method` select `GET`, `HTTP path` fill in `/users`.
If you want to access all paths with the prefix `/admin/users`, then the `HTTP path` fill in `/users*`, if the permissions include multiple access paths, wrap the line for each path.
## Page permission
If you want to control the user's permissions in the page, you can refer to the following example
### example1
For example, there is now a scene, here is a article module, we use create articles as an example
At first open `http://localhost/admi/auth/permissions`, fill up slug field with text `create-post`, and `Create post` in name field, then assign this permission to some roles.
In your controller action:
```php
use Encore\Admin\Auth\Permission;
class PostController extends Controller
{
public function create()
{
// check permission, only the roles with permission `create-post` can visit this action
Permission::check('create-post');
}
}
```
### example2
If you want to control the page elements of the user's display, then you need to first define permissions, such as `delete-image` and `view-title-column`, respectively, to control the permissions to delete pictures and display a column in grid, then assign these two permissions to roles, add following code to the grid
```php
$grid->actions(function ($actions) {
// The roles with this permission will not able to see the delete button in actions column.
if (!Admin::user()->can('delete-image')) {
$actions->disableDelete();
}
});
// Only roles with permission `view-title-column` can view this column in grid
if (Admin::user()->can('view-title-column')) {
$grid->column('title');
}
```
## Other methods
Get current user object.
```php
Admin::user();
```
Get current user id.
```php
Admin::user()->id;
```
Get user's roles.
```php
Admin::user()->roles;
```
Get user's permissions.
```php
Admin::user()->permissions;
```
User is role.
```php
Admin::user()->isRole('developer');
```
User has permission.
```php
Admin::user()->can('create-post');
```
User don't has permission.
```php
Admin::user()->cannot('delete-post');
```
Is user super administrator.
```php
Admin::user()->isAdministrator();
```
Is user in one of roles.
```php
Admin::user()->inRoles(['editor', 'developer']);
```
## Permission middleware
You can use permission middleware in the routes to control the routing permission
```php
// Allow roles `administrator` and `editor` access the routes under group.
Route::group([
'middleware' => 'admin.permission:allow,administrator,editor',
], function ($router) {
$router->resource('users', UserController::class);
...
});
// Deny roles `developer` and `operator` access the routes under group.
Route::group([
'middleware' => 'admin.permission:deny,developer,operator',
], function ($router) {
$router->resource('users', UserController::class);
...
});
// User has permission `edit-post`、`create-post` and `delete-post` can access routes under group.
Route::group([
'middleware' => 'admin.permission:check,edit-post,create-post,delete-post',
], function ($router) {
$router->resource('posts', PostController::class);
...
});
```
The usage of permission middleware is just as same as other middleware.

View File

@@ -0,0 +1,62 @@
# Quick start
We use `users` table come with `Laravel` for example,the structure of table is:
```sql
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
```
And the model for this table is `App\User.php`
You can follow these steps to setup `CRUD` interfaces of table `users`:
## Add controller
Use the following command to create a controller for `App\User` model
```php
php artisan admin:make UserController --model=App\\User
// under windows use:
php artisan admin:make UserController --model=App\User
```
The above command will create the controller in `app/Admin/Controllers/UserController.php`.
## Add route
Add a route in `app/Admin/routes.php`
```
$router->resource('demo/users', UserController::class);
```
## Add left menu item
Open `http://localhost:8000/admin/auth/menu`, add menu link and refresh the page, then you can find a link item in left menu bar.
> Where `uri` fills in the path part that does not contain the prefix of the route, such as the full path `http://localhost:8000/admin/demo/users`, just input `demo/users`, If you want to add an external link, just fill in the full url, such as `http://laravel-admin.org/`.
### Menu translations
append menu titles in menu_titles index at your language files.
For example 'Work Units' title:
in resources/lang/es/admin.php
```php
...
// lowercase and replace spaces with _
'menu_titles' => [
'work_units' => 'Unidades de trabajo'
],
```
## Build grid and form
The rest needs to be done is open `app/Admin/Contollers/UserController.php`, find `form()` and `grid()` method and write few lines of code with `model-grid` and `model-form`,for more detail, please read [model-grid](/en/model-grid.md) and [model-form](/en/model-form.md).

View File

@@ -0,0 +1,10 @@
# Upgrade precautions
Because `laravel-admin 1.5` built-in table structure has been modified, it is recommended that you re-install `laravel 5.5` and `laravel-admin 1.5`, and then migrate the code over
Code migration needs attention
- Please refer to the table structure changes [tables.php](https://github.com/z-song/laravel-admin/blob/master/database/migrations/2016_01_04_173148_create_admin_tables.php)
- Routing file structure is modified please refer to [routes.stub](https://github.com/z-song/laravel-admin/blob/master/src/Console/stubs/routes.stub)
- Please refer to the configuration file structure changes [admin.php](https://github.com/z-song/laravel-admin/blob/master/config/admin.php)
- The chart component has been removed and can no longer be used, please refer to [Custom chart](/en/custom-chart.md)

View File

@@ -0,0 +1,156 @@
# Web widgets
## Box
`Encore\Admin\Widgets\Box` used to generate box components:
```php
use Encore\Admin\Widgets\Box;
$box = new Box('Box Title', 'Box content');
$box->removable();
$box->collapsable();
$box->style('info');
$box->solid();
echo $box;
```
The `$content` parameter is the content element of the Box, which can be either an implementation of the `Illuminate\Contracts\Support\Renderable` interface, or other printable variables.
`Box::title($title)` method is used to set the Box component title.
`Box::content($content)` method is used to set the content element of a Box component.
`Box::removable()` method sets the Box component as removable.
`Box::collapsable()` method sets the Box component as collapsable.
`Box::style($style)` method sets the style of the Box component to fill in `primary`, `info`, `danger`, `warning`, `success`, `default`.
`Box::solid()` method adds a border to the Box component.
## Collapse
`Encore\Admin\Widgets\Collapse` class used to generate folding components:
```php
use Encore\Admin\Widgets\Collapse;
$collapse = new Collapse();
$collapse->add('Bar', 'xxxxx');
$collapse->add('Orders', new Table());
echo $collapse->render();
```
`Collapse::add($title, $content)` method is used to add a collapsed item to the collapsing component. The `$title` parameter sets the title of the item. The`$content` parameter is used to .
## Form
`Encore\Admin\Widgets\Form` class is used to quickly build a form:
```php
$form = new Form();
$form->action('example');
$form->email('email')->default('qwe@aweq.com');
$form->password('password');
$form->text('name');
$form->url('url');
$form->color('color');
$form->map('lat', 'lng');
$form->date('date');
$form->json('val');
$form->dateRange('created_at', 'updated_at');
echo $form->render();
```
`Form::__construct($data = [])` generates a form object. If the `$data` parameter is passed, the elements in the `$data` array will be filled into the form.
`Form::action($uri)` method is used to set the form submission address.
`Form::method($method)` method is used to set the submit method of the form, the default is `POST` method.
`Form::disablePjax()` disable pjax for form submit.
## Infobox
`Encore\Admin\Widgets\InfoBox` class is used to generate the information presentation block:
```php
use Encore\Admin\Widgets\InfoBox;
$infoBox = new InfoBox('New Users', 'users', 'aqua', '/admin/users', '1024');
echo $infoBox->render();
```
Refer to the section on the `InfoBox` in the `index()` method of the home page layout file [HomeController.php](https://github.com/z-song/laravel-admin/blob/master/src/Console/stubs/HomeController.stub).
## Tab component
`Encore\Admin\Widgets\Tab` class is used to generate the tab components:
```php
use Encore\Admin\Widgets\Tab;
$tab = new Tab();
$tab->add('Pie', $pie);
$tab->add('Table', new Table());
$tab->add('Text', 'blablablabla....');
echo $tab->render();
```
`Tab::add($title, $content)` method is used to add new tab, `$title` is tab title, `$content` is tab content.
## Table
`Encore\Admin\Widgets\Table` class is used to generate tables:
```php
use Encore\Admin\Widgets\Table;
// table 1
$headers = ['Id', 'Email', 'Name', 'Company'];
$rows = [
[1, 'labore21@yahoo.com', 'Ms. Clotilde Gibson', 'Goodwin-Watsica'],
[2, 'omnis.in@hotmail.com', 'Allie Kuhic', 'Murphy, Koepp and Morar'],
[3, 'quia65@hotmail.com', 'Prof. Drew Heller', 'Kihn LLC'],
[4, 'xet@yahoo.com', 'William Koss', 'Becker-Raynor'],
[5, 'ipsa.aut@gmail.com', 'Ms. Antonietta Kozey Jr.'],
];
$table = new Table($headers, $rows);
echo $table->render();
// table 2
$headers = ['Keys', 'Values'];
$rows = [
'name' => 'Joe',
'age' => 25,
'gender' => 'Male',
'birth' => '1989-12-05',
];
$table = new Table($headers, $rows);
echo $table->render();
```