sisjosex / phpadmin
PHP/Mysql 管理员生成器
This package is not auto-updated.
Last update: 2024-09-24 01:58:28 UTC
README
简洁易用的管理员,可以生成后端,也可以实现前端。
需求
- 启用Rewrite模块,例如在ubuntu和apache2上
$sudo a2enmod rewrite
$sudo service apache2 restart
- Grunt用于在
assets/admin/内部构建.js/css的.min文件
$npm install -g grunt-cli
$npm install
$grunt uglify
$grunt cssmin
更多信息请访问https://grunt.node.org.cn/
安装
-
将某些目录(例如"project1")内的文件和文件夹复制到。
-
编辑
config/constants.php#8
define('BASE_URL', $protocol . ':' . '//' . $_SERVER['SERVER_NAME'] . $port . 'project1');
-
编辑数据库配置
config/database.php -
根据您的环境在浏览器中加载
https:///project1https:///project1/admin -
管理员凭据
admin@gmail.comadmin
** 建议表的基本概念和结构 **
-
数据库表名。必须是单数小写,例如
city, company, gym.
-
表列名,必须是单数小写。如果您可能不希望永久删除,则需要状态类型ENUM,以下有示例。
-
引用表名必须是以下格式:tablename_id,在表名小写后以"_id"结尾。
示例
- ** 为名为gym的表构建一个简单的管理员,该表引用两个表:city/company **
CREATE TABLE IF NOT EXISTS `city` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`status` enum('active','deleted') DEFAULT 'active',
PRIMARY KEY (`id`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `company` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`style` enum('pfc','mfc','psf','nn') DEFAULT 'nn',
`name` varchar(250) NOT NULL,
`logo` varchar(500) NOT NULL,
`logo_small` varchar(500) NOT NULL,
`logo_big` varchar(500) NOT NULL,
`marker` varchar(500) NOT NULL,
`permalink` varchar(500) NOT NULL,
`status` enum('active','deleted') DEFAULT 'active',
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE IF NOT EXISTS `gym` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`city_id` int(11) NOT NULL,
`company_id` int(11) NOT NULL,
`name` varchar(250) NOT NULL,
`short_name` varchar(100) NOT NULL,
`latitude` varchar(20) NOT NULL,
`longitude` varchar(20) NOT NULL,
`phone` varchar(20) NOT NULL,
`email` varchar(200) NOT NULL,
`address` varchar(500) NOT NULL,
`permalink` varchar(500) NOT NULL,
`status` enum('active','incoming','deleted') DEFAULT 'active',
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `company_id` (`company_id`),
KEY `city_id` (`city_id`),
KEY `status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
** 将这些表导入数据库并在models文件夹中构建三个模型 ** city_model.php
<?php
require_once(BASE_PATH . 'system/module.php');
require_once(BASE_PATH . 'system/auth.php');
class CityModel extends Module
{
function __construct()
{
// Calls to parent constructor with table name and table_id column name
parent::__construct('city', 'id');
// You can comment this line if no prefix are used
$this->phisical_table = DB_PREFIX . 'city';
// key is exactly column name, lang function uses laguage/en.php by default you can make change the logic
$this->addField(
array(
"key" => "id",
"comparator" => 'IN',
"name" => lang("ID"),
"type" => "hidden"
)
);
// Validation format is like jqyer validation but in php format
$this->addField(
array(
"key" => "name",
// Default comparator when making background search yout can specify, see filters line
"comparator" => "LIKE",
"name" => lang("Name"),
"type" => "text", // supported types are:
/*
text
textarea
password
upload
editor
date
daterange
hidden
email
dropdown -> for ENUM types or external table
composite -> composite table(C) starting from (A) like: A -> C <- B (You cannot add more C rows)
inline -> simple composite table A, B then A -> C <- B (You can only add or edit C rows)
*/
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Name is required')
)
),
// You can customize attributtes for each here
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Name') )
)
)
);
// Added status column for persist data after deleting (deleted row = deleted value for this column)
$this->addField(
array(
"key" => "status",
"comparator" => '!='
)
);
// This compares with != like described above in comparator field parameter
$this->filters = array(
'status' => 'deleted'
);
// You can access to current user authenticated as below, roles are specified in user table, you can add more roles there also in user_model.php
if(Auth::$user['role'] != 'sadmin') {
$this->filters = array(
'status' => 'deleted'
);
}
// Defines what be showed in form and grid alt is set the order
$this->addGroup('form', array('id', 'name'));
$this->addGroup('grid', array('id', 'name'));
}
}
company_model.php
<?php
require_once(BASE_PATH . 'system/module.php');
require_once(BASE_PATH . 'system/auth.php');
class CompanyModel extends Module
{
function __construct()
{
parent::__construct('company', 'id');
$this->phisical_table = DB_PREFIX . 'company';
$this->addField(
array(
"key" => "id",
"name" => lang("ID"),
"type" => "hidden"
)
);
$this->addField(
array(
"key" => "name",
"comparator" => "=",
"name" => lang("Name"),
"type" => "text",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Name is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Name') )
),
'group' => 'column1'
)
);
$this->addField(
array(
"key" => "style",
"comparator" => "LIKE",
"name" => lang("Style"),
"type" => "dropdown",
// Setting up values for each enum type supported un table structure
"values" => array(
array('id' => '', 'name' => lang('Select Style')),
array('id' => 'pfc', 'name' => lang('PFC')),
array('id' => 'mfc', 'name' => lang('MFC')),
array('id' => 'psf', 'name' => lang('PSF'))
),
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Style is required')
)
),
// You can organize fields in columns put any name here or leave empty for no columns
'group' => 'column1'
)
);
$this->addField(
array(
"key" => "logo",
"name" => lang("Logo"),
"type" => "upload",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Logo is required')
)
),
// settings are required for upload/editor type field
'settings' => array(
// url for uploader admin/[controller_name]/upload
'url' => BASE_URL . 'admin/company/upload',
// absolute path for upload dir
'path' => BASE_PATH . 'uploads' . DIRECTORY_SEPARATOR . 'logos' . DIRECTORY_SEPARATOR,
// Download path by default are using timthumb for thumbnails in framework.js
'download' => BASE_URL . 'uploads/logos/'
),
'group' => 'column2'
)
);
$this->addField(
array(
"key" => "logo_small",
"name" => lang("Logo Small"),
"type" => "upload",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Logo Small is required')
)
),
'settings' => array(
'url' => BASE_URL . 'admin/company/upload',
'path' => BASE_PATH . 'uploads' . DIRECTORY_SEPARATOR . 'logos' . DIRECTORY_SEPARATOR,
'download' => BASE_URL . 'uploads/logos/'
),
'group' => 'column1'
)
);
/* Inline example, you can add/edit referenced external table and external columns specified en model parameter
$this->addField(
array(
"key" => "images",
"type" => "inline",
"model" => new Company_imagesModel(),
'field_group' => lang('Add Image'),
"group" => "column1",
)
);
*/
$this->addField(
array(
"key" => "logo_big",
"name" => lang("Logo Big"),
"type" => "upload",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Logo Big is required')
)
),
'settings' => array(
'url' => BASE_URL . 'admin/company/upload',
'path' => BASE_PATH . 'uploads' . DIRECTORY_SEPARATOR . 'logos' . DIRECTORY_SEPARATOR,
'download' => BASE_URL . 'uploads/logos/'
),
'group' => 'column2'
)
);
$this->addField(
array(
"key" => "marker",
"name" => lang("Marker for map"),
"type" => "upload",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Marker is required')
)
),
'settings' => array(
'url' => BASE_URL . 'admin/company/upload',
'path' => BASE_PATH . 'uploads' . DIRECTORY_SEPARATOR . 'markers' . DIRECTORY_SEPARATOR,
'download' => BASE_URL . 'uploads/markers/'
),
'group' => 'column2'
)
);
$this->addField(
array(
"key" => "status"
)
);
$this->filters = array(
DB_PREFIX . 'company.status!=' => 'deleted'
);
$this->pagination = array(
'start' => 0,
'per_page' => 10
);
$this->addGroup('form', array('id', 'style', 'name', 'logo_small', 'images', 'logo', 'logo_big', 'marker'));
$this->addGroup('grid', array('id', 'style', 'name', 'logo_small', 'logo', 'marker'));
}
/* Callback before saving data (add/edit), for example sets permalink */
function callback_before_save($id, $data) {
$data['permalink'] = toAscii($data['name']);
return $data;
}
}
<?php
require_once(BASE_PATH . 'system/module.php');
require_once(BASE_PATH . 'system/auth.php');
require_once(BASE_PATH . 'models/city_model.php');
require_once(BASE_PATH . 'models/company_model.php');
class GymModel extends Module
{
function __construct()
{
parent::__construct('gym', 'id');
$this->phisical_table = DB_PREFIX . 'gym';
/* customizing for dropdown when referencing this model on a dropdown field */
$this->field_custom_name_dropdown = "CONCAT(company.name, ' - ', gym.name)";
$this->addField(
array(
"key" => "id",
"name" => lang("ID"),
"type" => "hidden"
)
);
$this->addField(
array(
"key" => "name",
"comparator" => "=",
"name" => lang("Name"),
"type" => "text",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Name is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Name') )
),
'group' => 'column1',
'filtrable' => true,
)
);
$this->addField(
array(
"key" => "city_id",
"comparator" => "=",
"name" => lang("City"),
"type" => "dropdown",
// instead on ENUM here are using a external table for reference city_id column
"model" => new CityModel(),
"default" => array(
array('id' => '', 'name' => lang('Select City'))
),
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('City is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('City') )
),
'group' => 'column1',
// This paramter creates a searc bar and enable this column for make searches
'filtrable' => true,
// You cam agrupate by tabs, then tab bar appears on top of form
'tab' => lang('Main Settings')
)
);
$this->addField(
array(
"key" => "company_id",
"comparator" => "=",
"name" => lang("Company"),
"type" => "dropdown",
"model" => new CompanyModel(),
"default" => array(
array('id' => '', 'name' => lang('Select Company'))
),
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Company is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Company') )
),
'group' => 'column1',
'filtrable' => true
)
);
$this->addField(
array(
"key" => "short_name",
"comparator" => "=",
"name" => lang("Short name"),
"type" => "text",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Short name is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Short name') )
),
'group' => 'column1'
)
);
$this->addField(
array(
"key" => "phone",
"comparator" => "=",
"name" => lang("Phone"),
"type" => "text",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Phone is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Phone') )
),
'group' => 'column1'
)
);
$this->addField(
array(
"key" => "email",
"comparator" => "=",
"name" => lang("Email"),
"type" => "text",
'validation' => array(
'rules' => array(
'required' => true,
'email' => true
),
'messages' => array(
'required' => lang('Email is required'),
'email' => lang('Invalid email address')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Email') )
),
'group' => 'column1'
)
);
$this->addField(
array(
"key" => "address",
"comparator" => "=",
"name" => lang("Address"),
"type" => "textarea",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Address is required')
)
),
'attr' => array(
array('name' => 'placeholder', 'value' => lang('Address') ),
array('name' => 'class', 'value' => 'full-width' )
),
'group' => 'column1'
)
);
$this->addField(
array(
"key" => "location",
"comparator" => "=",
"name" => lang("Location"),
// This type will show a google map
"type" => "map",
'validation' => array(
'rules' => array(
'required' => true
),
'messages' => array(
'required' => lang('Location is required')
)
),
// Settings are required for map type in this format :
"settings" => array(
'type' => 'selector',
'lat_key' => 'latitude',
'lon_key' => 'longitude',
'center' => array(
'latitude' => -17.130948,
'longitude' => -64.753418
),
'zoom' => 18,
'map_type' => 'google.maps.MapTypeId.ROADMAP'
),
'group' => 'column2'
)
);
$this->addField(
array(
"key" => "status",
'name' => lang('Status'),
'type' => 'dropdown',
'values' => array(
array('id' => '', 'name' => lang('Select Status')),
array('id' => 'active', 'name' => lang('Active')),
array('id' => 'incoming', 'name' => lang('Incoming'))
),
'filtrable' => true,
"group" => "column1"
)
);
// this for show company name in grid
$this->addField(
array(
"grid_key" => "company",
"name" => lang('Company'),
"field" => 'company_id'
)
);
$this->filters = array(
DB_PREFIX . 'gym.status!=' => 'deleted'
);
// This setup pagination for grid
$this->pagination = array(
'start' => 0,
'per_page' => 10
);
$this->addGroup('form', array('id', 'city_id', 'company_id', 'name', 'short_name', 'email', 'phone', 'address', 'status', 'location'));
$this->addGroup('grid', array('id', 'company', 'name', 'short_name', 'status'));
}
function callback_before_save($id, $data) {
$data['permalink'] = toAscii($data['name']);
return $data;
}
// Example for custom methods for frontend
function getFor($company_id) {
$sql = "
SELECT gym.id, gym.permalink, gym.name, gym.short_name, gym.status, company.permalink as company_permalink, company.id as company_id, company.name as company, city.name as city
FROM gym
INNER JOIN company ON(company.id=gym.company_id)
INNER JOIN city ON(city.id=gym.city_id)
WHERE gym.company_id='$company_id' AND gym.status != 'deleted'
ORDER BY gym.short_name ASC";
return $this->fetch_result($sql);
}
}
** 现在在admin文件夹中创建三个控制器 ** 控制器必须每个都在一个单独的文件中,名称必须是"table name"的小写
<?php
require_once(BASE_PATH . 'controllers/admin/backend.php');
require_once(BASE_PATH . 'models/city_model.php');
class City extends Backend {
function __construct() {
parent::__construct();
$this->model = new CityModel();
}
}
<?php
require_once(BASE_PATH . 'controllers/admin/backend.php');
require_once(BASE_PATH . 'models/company_model.php');
class Company extends Backend {
function __construct() {
parent::__construct();
$this->model = new CompanyModel();
}
}
<?php
require_once(BASE_PATH . 'controllers/admin/backend.php');
require_once(BASE_PATH . 'models/gym_model.php');
class Gym extends Backend {
function __construct() {
parent::__construct();
$this->model = new GymModel();
}
}
是的,这非常简单,扩展了Backend,您有会话控制,如果没有登录,则重定向到登录,查看home控制器以了解无会话控制
** 现在您可以为管理面板添加模块 **
- 打开仪表板控制器,添加以下代码类似的内容
<?php
require_once(BASE_PATH . 'controllers/admin/backend.php');
//require_once(BASE_PATH . 'models/dashboard.php');
require_once(BASE_PATH . 'models/user_model.php');
require_once(BASE_PATH . 'models/gym_model.php');
require_once(BASE_PATH . 'models/city_model.php');
require_once(BASE_PATH . 'models/company_model.php');
class Dashboard extends Backend
{
function __construct()
{
parent::__construct();
//$this->model = new DashboardModel();
}
function index()
{
global $lang;
$userModule = new UserModel();
$cityModule = new CityModel();
$gymModule = new GymModel();
$companyModel = new CompanyModel();
$data['title'] = lang("Admin Panel");
if (Auth::$user['role'] == 'sadmin')
$data['modules']['user'] = array(
'model' => $userModule->purgeModel(),
'settings' => array(
'container' => '#page',
'class' => 'page'
),
'containers' => array(
'modal' => array(
'settings' => array()
),
'form' => array(
'settings' => array()
),
'grid' => array(
'settings' => array(
'actions' => array(
array('type' => 'edit', 'text' => lang('Edit'), 'icon' => ''),
array('type' => 'delete', 'text' => lang('Delete'), 'icon' => '')
)
)
),
'toolbar' => array(
'settings' => array(
'actions' => array(
array(
'type' => 'text',
'title' => lang('Users Manager'),
'template' => 'h2'
),
array(
'type' => 'text',
'title' => lang('Manage users and manage roles'),
'template' => 'h5'
),
array(
'type' => 'break'
),
array(
'type' => 'button',
'title' => lang('New User'),
'action' => 'new'
)
)
)
)
)
);
if (Auth::$user['role'] == 'sadmin')
$data['modules']['city'] = array(
'model' => $cityModule->purgeModel(),
'settings' => array(
'container' => '#page',
'class' => 'page'
),
'containers' => array(
'modal' => array(
'settings' => array()
),
'form' => array(
'settings' => array()
),
'grid' => array(
'settings' => array(
'actions' => array(
array('type' => 'edit', 'text' => lang('Edit'), 'icon' => ''),
array('type' => 'delete', 'text' => lang('Delete'), 'icon' => '')
)
)
),
'toolbar' => array(
'settings' => array(
'actions' => array(
array(
'type' => 'text',
'title' => lang('City Manager'),
'template' => 'h2'
),
array(
'type' => 'text',
'title' => lang('Manage cities'),
'template' => 'h5'
),
array(
'type' => 'break'
),
array(
'type' => 'button',
'title' => lang('New City'),
'action' => 'new'
)
)
)
)
)
);
);
if (Auth::$user['role'] == 'sadmin')
$data['modules']['gym'] = array(
'model' => $gymModule->purgeModel(),
'settings' => array(
'container' => '#page',
'class' => 'page'
),
'containers' => array(
'modal' => array(
'settings' => array()
),
'form' => array(
'settings' => array()
),
'grid' => array(
'settings' => array(
'actions' => array(
array('type' => 'edit', 'text' => lang('Edit'), 'icon' => ''),
array('type' => 'delete', 'text' => lang('Delete'), 'icon' => '')
)
)
),
'toolbar' => array(
'settings' => array(
'actions' => array(
array(
'type' => 'text',
'title' => lang('Gym manager'),
'template' => 'h2'
),
array(
'type' => 'text',
'title' => lang('Manage gym'),
'template' => 'h5'
),
array(
'type' => 'break'
),
array(
'type' => 'button',
'title' => lang('New Gym'),
'action' => 'new'
)
)
)
)
)
);
if (Auth::$user['role'] == 'sadmin')
$data['modules']['company'] = array(
'model' => $companyModel->purgeModel(),
'settings' => array(
'container' => '#page',
'class' => 'page'
),
'containers' => array(
'modal' => array(
'settings' => array()
),
'form' => array(
'settings' => array()
),
'grid' => array(
'settings' => array(
'actions' => array(
array('type' => 'edit', 'text' => lang('Edit'), 'icon' => ''),
array('type' => 'delete', 'text' => lang('Delete'), 'icon' => '')
)
)
),
'toolbar' => array(
'settings' => array(
'actions' => array(
array(
'type' => 'text',
'title' => lang('Company manager'),
'template' => 'h2'
),
array(
'type' => 'text',
'title' => lang('Manage companies'),
'template' => 'h5'
),
array(
'type' => 'break'
),
array(
'type' => 'button',
'title' => lang('New Company'),
'action' => 'new'
)
)
)
)
)
);
// View obect for render content
$this->view = new View();
$data['modules'] = $this->view->putDefaults($data['modules']);
$data['sidebar'] = array();
// Adds user module to sidebar
if (isset($data['modules']['user']))
$data['sidebar'][] = array(
'title' => lang('Manage Users'),
'attr' => array(
'onclick' => 'javascript: ;'
),
'icon' => '',
// this must be table name
'module' => 'user'
);
if (isset($data['modules']['company']))
$data['sidebar'][] = array(
'title' => lang('Manage Companies'),
'attr' => array(
'onclick' => 'javascript: ;'
),
'icon' => '',
'module' => 'company'
);
$data['language'] = $lang;
// Sets layout for page inside views folder, check depending css/js
$this->view->add('admin/layouts/backend', $data);
$this->view->render();
}
}
** 现在享受刷新管理员,您可以根据以下屏幕设置几个界面: **