網站程式設計-PHP
一、結構規劃
- 資料表:creative_nav
- 關鍵字:icon_home
- 後台程式名稱:admin/icon.php
- 後台樣板:templates/admin/tpl/admin_icon.html
二、後台樣板
- templates/admin/theme.html
<{if $WEB.file_name =="index.php"}>
<{include file="tpl/admin_index.html"}>
<{elseif $WEB.file_name =="icon.php"}>
<{include file="tpl/admin_icon.html"}>
<{/if}>
三、後台選單
- templates/admin/tpl/admin_nav.html
<ul class="dropdown-menu dropdown-user">
<li><a href="index.php"><i class="fa fa-user fa-fw"></i> 選單管理</a>
</li>
<li><a href="icon.php"><i class="fa fa-gear fa-fw"></i> 圖示管理</a>
</li>
<li class="divider"></li>
<li><a href="../admin.php?op=op_logout"><i class="fa fa-sign-out fa-fw"></i> 登出</a>
</li>
</ul>
四、fontawwsome iconpicker
- 官網:https://itsjavi.com/fontawesome-iconpicker/
- 安裝:
參考網站:http://github.ugm.com.tw/soft/templates/op_form.html
引入「font-awesome.min.css」
引入「fontawesome-iconpicker.min.css」
引入「fontawesome-iconpicker.min.js」
調用插件
更換jquery <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
程式碼 templates/admin/tpl/admin_icon.html <div class="row"> <link href="<{$themeUrl}>/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="<{$smarty.const.WEB_URL}>/class/fontawesome-iconpicker/css/fontawesome-iconpicker.min.css"> <script type="text/javascript" src="<{$smarty.const.WEB_URL}>/class/fontawesome-iconpicker/js/fontawesome-iconpicker.min.js"></script> <script type='text/javascript'> $(document).ready(function(){ $('.icp').iconpicker(); }); </script> <div class="col-md-3"> <div class="form-group"> <label>圖示</label> <div class="input-group"> <input name="icon" id="icon" data-placement="bottomRight" class="form-control icp icp-auto" value="fa-archive" type="text" /> <span class="input-group-addon"></span> </div> </div> </div> </div>
五、多行表單
- 參考網站:http://github.ugm.com.tw/soft/templates/op_form.html <div class="row"> <div class="col-md-12"> <div class="form-group"> <label>摘要</label> <textarea name="summary" id="summary" class="form-control" rows="3" placeholder="摘要"></textarea> </div> </div> </div>
六、網頁編輯器 CKEDITOR
- 官網:http://ckeditor.com
- 下載Standard Package:http://ckeditor.com/download
- 將下載檔案解壓縮至 class/
- 引入js
- 調用插件
- 程式碼 templates/admin/tpl/admin_icon.html
<div class="row">
<script type="text/javascript" src="<{$smarty.const.WEB_URL}>/class/ckeditor/ckeditor.js"></script>
<script>
$(function() {
CKEDITOR.replace('content');
});
</script>
<div class="col-md-12">
<div class="form-group">
<label>內容</label>
<textarea name="content" id="content" class="form-control" rows="5" placeholder="內容"></textarea>
</div>
</div>
</div>
七、將elFinder整合至CKEDITOR
- 官網:https://studio-42.github.io/elFinder/
- 將下載檔案解壓縮至 class/elFinder
- 引入elFinder
<script>
$(function() {
CKEDITOR.replace('content', {
language : 'zh' ,
contentsCss : ['<{$themeUrl}>/vendor/bootstrap/css/bootstrap.min.css'],
filebrowserBrowseUrl : '<{$smarty.const.WEB_URL}>/class/elFinder/elfinder.html'
} );
});
</script>
- 修改 class/elFinder/elfinder.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>elFinder 2.1.x source version with PHP connector</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2" />
<!-- jQuery and jQuery UI (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<!-- elFinder CSS (REQUIRED) -->
<link rel="stylesheet" type="text/css" href="css/elfinder.min.css">
<link rel="stylesheet" type="text/css" href="css/theme.css">
<!-- elFinder JS (REQUIRED) -->
<script src="js/elfinder.min.js"></script>
<!-- GoogleDocs Quicklook plugin for GoogleDrive Volume (OPTIONAL) -->
<!--<script src="js/extras/quicklook.googledocs.js"></script>-->
<!-- elFinder translation (OPTIONAL) -->
<script src="js/i18n/elfinder.zh_TW.js"></script>
<!-- elFinder initialization (REQUIRED) -->
<script type="text/javascript" charset="utf-8">
// Helper function to get parameters from the query string.
function getUrlParam(paramName) {
var reParam = new RegExp('(?:[\?&]|&)' + paramName + '=([^&]+)', 'i') ;
var match = window.location.search.match(reParam) ;
return (match && match.length > 1) ? match[1] : '' ;
}
$().ready(function() {
var funcNum = getUrlParam('CKEditorFuncNum');
var elf = $('#elfinder').elfinder({
url : 'php/connector.minimal.php',
lang: 'zh_TW', // language (OPTIONAL)
getFileCallback : function(file) {
window.opener.CKEDITOR.tools.callFunction(funcNum, file.url);
window.close();
},
resizable: false
}).elfinder('instance');
});
</script>
</head>
<body>
<!-- Element where elFinder will be created (REQUIRED) -->
<div id="elfinder"></div>
</body>
</html>
- 修改 class/elFinder/php/connector.minimal.php
<?php
error_reporting(0); // Set E_ALL for debuging
include_once "../../../head.php";
include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'elFinderConnector.class.php';
include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'elFinder.class.php';
include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'elFinderVolumeDriver.class.php';
include_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'elFinderVolumeLocalFileSystem.class.php';
// Required for MySQL storage connector
// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeMySQL.class.php';
// Required for FTP connector support
// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeFTP.class.php';
// ===============================================
/**
* # Dropbox volume driver need `composer require dropbox-php/dropbox-php:dev-master@dev`
* OR "dropbox-php's Dropbox" and "PHP OAuth extension" or "PEAR's HTTP_OAUTH package"
* * dropbox-php: http://www.dropbox-php.com/
* * PHP OAuth extension: http://pecl.php.net/package/oauth
* * PEAR's HTTP_OAUTH package: http://pear.php.net/package/http_oauth
* * HTTP_OAUTH package require HTTP_Request2 and Net_URL2
*/
// // Required for Dropbox.com connector support
// // On composer
// require 'vendor/autoload.php';
// elFinder::$netDrivers['dropbox'] = 'Dropbox';
// // OR on pear
// include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'elFinderVolumeDropbox.class.php';
// // Dropbox driver need next two settings. You can get at https://www.dropbox.com/developers
// define('ELFINDER_DROPBOX_CONSUMERKEY', '');
// define('ELFINDER_DROPBOX_CONSUMERSECRET', '');
// define('ELFINDER_DROPBOX_META_CACHE_PATH',''); // optional for `options['metaCachePath']`
// ===============================================
// // Required for Google Drive network mount
// // Installation by composer
// // `composer require nao-pon/flysystem-google-drive:~1.1 google/apiclient:~2.0@rc nao-pon/elfinder-flysystem-driver-ext`
// // composer autoload
// require 'vendor/autoload.php';
// // Enable network mount
// elFinder::$netDrivers['googledrive'] = 'FlysystemGoogleDriveNetmount';
// // GoogleDrive Netmount driver need next two settings. You can get at https://console.developers.google.com
// // AND reuire regist redirect url to "YOUR_CONNECTOR_URL?cmd=netmount&protocol=googledrive&host=1"
// define('ELFINDER_GOOGLEDRIVE_CLIENTID', '');
// define('ELFINDER_GOOGLEDRIVE_CLIENTSECRET', '');
// ===============================================
/**
* Simple function to demonstrate how to control file access using "accessControl" callback.
* This method will disable accessing files/folders starting from '.' (dot)
*
* @param string $attr attribute name (read|write|locked|hidden)
* @param string $path file path relative to volume root directory started with directory separator
* @return bool|null
**/
function access($attr, $path, $data, $volume) {
return strpos(basename($path), '.') === 0// if file/folder begins with '.' (dot)
? !($attr == 'read' || $attr == 'write') // set read+write to false, other (locked+hidden) set to true
: null; // else elFinder decide it itself
}
// Documentation for connector options:
// https://github.com/Studio-42/elFinder/wiki/Connector-configuration-options
$opts = array(
// 'debug' => true,
'roots' => array(
array(
'driver' => 'LocalFileSystem', // driver for accessing file system (REQUIRED)
'path' => WEB_PATH . "/uploads/", // path to files (REQUIRED)
'URL' => WEB_URL . "/uploads/", // URL to files (REQUIRED)
'uploadDeny' => array('all'), // All Mimetypes not allowed to upload
'uploadAllow' => array('image', 'text/plain'), // Mimetype `image` and `text/plain` allowed to upload
'uploadOrder' => array('deny', 'allow'), // allowed Mimetype `image` and `text/plain` only
'accessControl' => 'access', // disable and hide dot starting files (OPTIONAL)
),
),
);
// run elFinder
$connector = new elFinderConnector(new elFinder($opts));
$connector->run();
八、op_insert
參考:http://php.net/manual/en/function.json-encode.php
################################# # 新增資料 # ################################# function op_insert() { global $mysqli; //print_r($_POST);die(); #資料過濾 #http://php.net/manual/en/mysqli.real-escape-string.php $_POST['title'] = $mysqli->real_escape_string($_POST['title']); $_POST['target'] = intval($_POST['target']); $_POST['enable'] = intval($_POST['enable']); $_POST['sort'] = intval($_POST['sort']); $_POST['url'] = $mysqli->real_escape_string($_POST['url']); $_POST['kind'] = $mysqli->real_escape_string($_POST['kind']); #圖示、摘要與內容存成json $content['icon'] = $mysqli->real_escape_string($_POST['icon']); $content['summary'] = $mysqli->real_escape_string($_POST['summary']); $content['content'] = $mysqli->real_escape_string($_POST['content']); $_POST['content'] = json_encode($content, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE); $sql = "insert into `creative_nav` (`title`, `target`, `enable`, `sort`,`url`,`kind`,`content`) VALUES ('{$_POST['title']}', '{$_POST['target']}', '{$_POST['enable']}', '{$_POST['sort']}', '{$_POST['url']}', '{$_POST['kind']}', '{$_POST['content']}')"; //die($sql); $mysqli->query($sql) or die(printf("Error: %s <br>" . $sql, $mysqli->sqlstate)); $sn = $mysqli->insert_id; //傳回insert 指令所產生之流水號 return $sn; }
九、op_update
十、撈出單筆資料
- get_creative_nav
########################################
#取得單筆記錄
########################################
function get_creative_nav($sn = "") {
global $mysqli;
if (!$sn) {
redirect_header("index.php", 3000, "查詢選單資料錯誤!!");
}
$sql = "select *
from `creative_nav`
where `sn`='{$sn}' and `kind`= 'icon_home'";
$result = $mysqli->query($sql) or die(printf("Error: %s <br>" . $sql, $mysqli->sqlstate));
$row = $result->fetch_assoc();
#過濾撈出資料
$row['sn'] = intval($row['sn']);
//http://www.w3school.com.cn/php/func_string_htmlspecialchars.asp
$row['title'] = htmlspecialchars($row['title'], ENT_QUOTES); // 轉換雙引號和單引號
$row['url'] = htmlspecialchars($row['url'], ENT_QUOTES); // 轉換雙引號和單引號
$row['sort'] = intval($row['sort']);
$row['enable'] = intval($row['enable']);
$row['target'] = intval($row['target']);
$content = json_decode($row['content'], true); //(PHP 5 >= 5.2.0 true=>array
$row['icon'] = htmlspecialchars($content['icon'], ENT_QUOTES); // 轉換雙引號和單引號
$row['summary'] = htmlspecialchars($content['summary'], ENT_QUOTES); // 轉換雙引號和單引號
$row['content'] = htmlspecialchars($content['content'], ENT_QUOTES); // 轉換雙引號和單引號
return $row;
}
十一、op_form
參考:http://php.net/manual/en/function.json-decode.php
################################# # 表單 # 選單關鍵字 icon_home ################################# function op_form($sn = "") { global $mysqli, $smarty; #取得預設值 if ($sn) { #編輯 $row = get_creative_nav($sn); //取得單筆記錄 $row['op'] = "op_update"; $row['form_title'] = "編輯選單"; } else { #新增 $row = array(); $row['op'] = "op_insert"; $row['form_title'] = "新增選單"; } #預設值設定 $row['sn'] = (isset($row['sn'])) ? $row['sn'] : ""; $row['title'] = (isset($row['title'])) ? $row['title'] : ""; $row['enable'] = (isset($row['enable'])) ? $row['enable'] : 1; $row['target'] = (isset($row['target'])) ? $row['target'] : 0; $row['url'] = (isset($row['url'])) ? $row['url'] : ""; $row['sort'] = (isset($row['sort'])) ? $row['sort'] : 0; $row['kind'] = (isset($row['kind'])) ? $row['kind'] : "icon_home"; $row['icon'] = (isset($row['icon'])) ? $row['icon'] : "fa-android"; $row['content'] = (isset($row['content'])) ? $row['content'] : ""; $row['summary'] = (isset($row['summary'])) ? $row['summary'] : ""; #把變數送至樣板 $smarty->assign("row", $row); }十二、修改樣板
- 用「新聞」取代「選單」在 icon.php 與 templates/admin/tpl/admin_icon.html
- 「textarea」預設值
<div class="col-md-12">
<div class="form-group">
<label>內容</label>
<textarea name="content" id="content" class="form-control" rows="5" placeholder="內容"><{$row.content}></textarea>
</div>
</div>