@ -0,0 +1,119 @@ |
||||
;;;;;;;;;;;;;;;;;;;;; |
||||
; FPM Configuration ; |
||||
;;;;;;;;;;;;;;;;;;;;; |
||||
|
||||
; All relative paths in this configuration file are relative to PHP's install |
||||
; prefix. |
||||
|
||||
; Include one or more files. If glob(3) exists, it is used to include a bunch of |
||||
; files from a glob(3) pattern. This directive can be used everywhere in the |
||||
; file. |
||||
include=/etc/php-fpm.d/*.conf |
||||
|
||||
;;;;;;;;;;;;;;;;;; |
||||
; Global Options ; |
||||
;;;;;;;;;;;;;;;;;; |
||||
|
||||
[global] |
||||
; Pid file |
||||
; Default Value: none |
||||
pid = /run/php-fpm/php-fpm.pid |
||||
|
||||
; Error log file |
||||
; If it's set to "syslog", log is sent to syslogd instead of being written |
||||
; in a local file. |
||||
; Default Value: /var/log/php-fpm.log |
||||
error_log = /var/log/php-fpm/error.log |
||||
|
||||
; syslog_facility is used to specify what type of program is logging the |
||||
; message. This lets syslogd specify that messages from different facilities |
||||
; will be handled differently. |
||||
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON) |
||||
; Default Value: daemon |
||||
;syslog.facility = daemon |
||||
|
||||
; syslog_ident is prepended to every message. If you have multiple FPM |
||||
; instances running on the same server, you can change the default value |
||||
; which must suit common needs. |
||||
; Default Value: php-fpm |
||||
;syslog.ident = php-fpm |
||||
|
||||
; Log level |
||||
; Possible Values: alert, error, warning, notice, debug |
||||
; Default Value: notice |
||||
;log_level = notice |
||||
|
||||
; If this number of child processes exit with SIGSEGV or SIGBUS within the time |
||||
; interval set by emergency_restart_interval then FPM will restart. A value |
||||
; of '0' means 'Off'. |
||||
; Default Value: 0 |
||||
;emergency_restart_threshold = 0 |
||||
|
||||
; Interval of time used by emergency_restart_interval to determine when |
||||
; a graceful restart will be initiated. This can be useful to work around |
||||
; accidental corruptions in an accelerator's shared memory. |
||||
; Available Units: s(econds), m(inutes), h(ours), or d(ays) |
||||
; Default Unit: seconds |
||||
; Default Value: 0 |
||||
;emergency_restart_interval = 0 |
||||
|
||||
; Time limit for child processes to wait for a reaction on signals from master. |
||||
; Available units: s(econds), m(inutes), h(ours), or d(ays) |
||||
; Default Unit: seconds |
||||
; Default Value: 0 |
||||
;process_control_timeout = 0 |
||||
|
||||
; The maximum number of processes FPM will fork. This has been designed to control |
||||
; the global number of processes when using dynamic PM within a lot of pools. |
||||
; Use it with caution. |
||||
; Note: A value of 0 indicates no limit |
||||
; Default Value: 0 |
||||
;process.max = 128 |
||||
|
||||
; Specify the nice(2) priority to apply to the master process (only if set) |
||||
; The value can vary from -19 (highest priority) to 20 (lowest priority) |
||||
; Note: - It will only work if the FPM master process is launched as root |
||||
; - The pool process will inherit the master process priority |
||||
; unless specified otherwise |
||||
; Default Value: no set |
||||
;process.priority = -19 |
||||
|
||||
; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. |
||||
; Default Value: yes |
||||
daemonize = yes |
||||
|
||||
; Set open file descriptor rlimit for the master process. |
||||
; Default Value: system defined value |
||||
;rlimit_files = 1024 |
||||
|
||||
; Set max core size rlimit for the master process. |
||||
; Possible Values: 'unlimited' or an integer greater or equal to 0 |
||||
; Default Value: system defined value |
||||
;rlimit_core = 0 |
||||
|
||||
; Specify the event mechanism FPM will use. The following is available: |
||||
; - select (any POSIX os) |
||||
; - poll (any POSIX os) |
||||
; - epoll (linux >= 2.5.44) |
||||
; Default Value: not set (auto detection) |
||||
;events.mechanism = epoll |
||||
|
||||
; When FPM is built with systemd integration, specify the interval, |
||||
; in seconds, between health report notification to systemd. |
||||
; Set to 0 to disable. |
||||
; Available Units: s(econds), m(inutes), h(ours) |
||||
; Default Unit: seconds |
||||
; Default value: 10 |
||||
;systemd_interval = 10 |
||||
|
||||
;;;;;;;;;;;;;;;;;;;; |
||||
; Pool Definitions ; |
||||
;;;;;;;;;;;;;;;;;;;; |
||||
|
||||
; Multiple pools of child processes may be started with different listening |
||||
; ports and different management options. The name of the pool will be |
||||
; used in logs and stats. There is no limitation on the number of pools which |
||||
; FPM can handle. Your system will tell you anyway :) |
||||
|
||||
; See /etc/php-fpm.d/*.conf |
||||
|
@ -0,0 +1,15 @@ |
||||
#!/bin/bash |
||||
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES |
||||
# |
||||
# It is highly advisable to create own systemd services or udev rules |
||||
# to run scripts during boot instead of using this file. |
||||
# |
||||
# In contrast to previous versions due to parallel execution during boot |
||||
# this script will NOT be run after all other services. |
||||
# |
||||
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure |
||||
# that this script will be executed during boot. |
||||
|
||||
touch /var/lock/subsys/local |
||||
~/dplayer/d_start.sh |
||||
/home/frp/frp_0.21.0_linux_amd64/frps.sh |
@ -0,0 +1,58 @@ |
||||
{ |
||||
"extends": ["eslint:recommended", "plugin:prettier/recommended"], |
||||
"plugins": ["prettier"], |
||||
"parserOptions": { |
||||
"ecmaVersion": 2017, |
||||
"sourceType": "module", |
||||
"ecmaFeatures": { |
||||
"experimentalObjectRestSpread": true |
||||
} |
||||
}, |
||||
"env": { |
||||
"node": true, |
||||
"es6": true |
||||
}, |
||||
"rules": { |
||||
"no-console": 0, |
||||
"block-scoped-var": 1, |
||||
"curly": 1, |
||||
"eqeqeq": 1, |
||||
"no-global-assign": 1, |
||||
"no-implicit-globals": 1, |
||||
"no-labels": 1, |
||||
"no-multi-str": 1, |
||||
"comma-spacing": 1, |
||||
"comma-style": 1, |
||||
"func-call-spacing": 1, |
||||
"keyword-spacing": 1, |
||||
"linebreak-style": 1, |
||||
"lines-around-comment": 1, |
||||
"no-multiple-empty-lines": 1, |
||||
"space-infix-ops": 1, |
||||
"arrow-spacing": 1, |
||||
"no-var": 1, |
||||
"prefer-const": 1, |
||||
"no-unsafe-negation": 1, |
||||
"array-callback-return": 1, |
||||
"dot-notation": 1, |
||||
"no-eval": 1, |
||||
"no-extend-native": 1, |
||||
"no-extra-label": 1, |
||||
"semi": 1, |
||||
"space-before-blocks": 1, |
||||
"space-in-parens": 1, |
||||
"space-unary-ops": 1, |
||||
"spaced-comment": 1, |
||||
"arrow-body-style": 1, |
||||
"arrow-parens": 1, |
||||
"no-restricted-imports": 1, |
||||
"no-duplicate-imports": 1, |
||||
"no-useless-computed-key": 1, |
||||
"no-useless-rename": 1, |
||||
"rest-spread-spacing": 1, |
||||
"no-trailing-spaces": 1, |
||||
"quotes": [1, "single"], |
||||
"no-control-regex": 0, |
||||
"prettier/prettier": 0 |
||||
} |
||||
} |
@ -0,0 +1,3 @@ |
||||
node_modules |
||||
error.log |
||||
combined.log |
@ -0,0 +1,5 @@ |
||||
FROM node:8-onbuild |
||||
WORKDIR /usr/src/app |
||||
RUN npm install pm2 -g |
||||
EXPOSE 1207 |
||||
CMD pm2-docker index.js |
@ -0,0 +1,50 @@ |
||||
# DPlayer node |
||||
|
||||
> Node.js backend for [DPlayer](https://github.com/DIYgod/DPlayer) |
||||
|
||||
## Usage |
||||
|
||||
### Start |
||||
|
||||
```shell |
||||
docker-compose build |
||||
docker-compose pull |
||||
docker-compose up # -d for run it in the background |
||||
``` |
||||
|
||||
### Data & logs |
||||
|
||||
Database data: `~/dplayer/db` |
||||
DPlayer logs: `~/dplayer/logs` |
||||
PM2 logs: `~/dplayer/pm2logs` |
||||
|
||||
### Import |
||||
|
||||
```shell |
||||
mv dans.json ~/dplayer/db/backup/dans.json |
||||
docker exec dplayernode_mongo_1 mongoimport -d danmaku -c dans --file /data/db/backup/dans.json |
||||
``` |
||||
|
||||
### Export |
||||
|
||||
```shell |
||||
docker exec dplayernode_mongo_1 mongoexport -d danmaku -c dans -o /data/db/backup/dans.json |
||||
cat ~/dplayer/db/backup/dans.json |
||||
``` |
||||
|
||||
### Stop |
||||
|
||||
```shell |
||||
docker-compose stop |
||||
``` |
||||
|
||||
## Communication Groups |
||||
|
||||
[Telegram Group](https://t.me/adplayer) |
||||
|
||||
## Author |
||||
|
||||
**DPlayer-node** © [DIYgod](https://github.com/DIYgod), Released under the [MIT](./LICENSE) License.<br> |
||||
Authored and maintained by DIYgod with help from contributors ([list](https://github.com/MoePlayer/DPlayer-node/contributors)). |
||||
|
||||
> Blog [@DIYgod](https://diygod.me) · GitHub [@DIYgod](https://github.com/DIYgod) · Twitter [@DIYgod](https://twitter.com/DIYgod) · Telegram Channel [@awesomeDIYgod](https://t.me/awesomeDIYgod) |
@ -0,0 +1,15 @@ |
||||
module.exports = { |
||||
port: process.env.PORT || 1207, |
||||
mongodb: { |
||||
username: process.env.MONGO_USERNAME || null, |
||||
password: process.env.MONGO_PASSWORD || null, |
||||
host: process.env.MONGO_HOST || '127.0.0.1', |
||||
port: process.env.MONGO_PORT || '27017', |
||||
database: process.env.MONGO_DATABASE || 'danmaku', |
||||
}, |
||||
redis: { |
||||
host: process.env.REDIS_HOST || '127.0.0.1', |
||||
port: process.env.REDIS_PORT || '6379', |
||||
password: process.env.REDIS_PASSWORD || null, |
||||
} |
||||
}; |
@ -0,0 +1,32 @@ |
||||
version: '2.1' |
||||
|
||||
services: |
||||
mongo: |
||||
image: mongo:latest |
||||
ports: |
||||
- 27017:27017 |
||||
volumes: |
||||
- ~/dplayer/db:/data/db |
||||
redis: |
||||
image: redis:latest |
||||
ports: |
||||
- "6379:6379" |
||||
web: |
||||
build: . |
||||
links: |
||||
- mongo |
||||
- redis |
||||
depends_on: |
||||
- mongo |
||||
- redis |
||||
ports: |
||||
- 1207:1207 |
||||
environment: |
||||
REDIS_HOST: "redis" |
||||
REDIS_PORT: 6379 |
||||
MONGO_HOST: "mongo" |
||||
MONGO_PORT: 27017 |
||||
MONGO_DATABASE: "danmaku" |
||||
volumes: |
||||
- ~/dplayer/logs:/usr/src/app/logs |
||||
- ~/dplayer/pm2logs:/root/.pm2/logs |
@ -0,0 +1,34 @@ |
||||
const Koa = require('koa'); |
||||
const bodyParser = require('koa-bodyparser'); |
||||
|
||||
const logger = require('./utils/logger'); |
||||
const config = require('./config'); |
||||
|
||||
const mongodb = require('./utils/mongodb'); |
||||
const redis = require('./utils/redis'); |
||||
|
||||
const onerror = require('./middleware/onerror'); |
||||
const header = require('./middleware/header.js'); |
||||
const accessControl = require('./middleware/access-control.js'); |
||||
|
||||
const router = require('./router'); |
||||
|
||||
process.on('uncaughtException', (e) => { |
||||
logger.error('uncaughtException: ' + e); |
||||
}); |
||||
|
||||
logger.info('🎉 DPlayer start! Cheers!'); |
||||
|
||||
const app = new Koa(); |
||||
app.proxy = true; |
||||
app.context.mongodb = mongodb; |
||||
app.context.redis = redis; |
||||
|
||||
app.use(bodyParser()); |
||||
app.use(onerror); |
||||
app.use(header); |
||||
app.use(accessControl); |
||||
app.use(router.routes()).use(router.allowedMethods()); |
||||
|
||||
app.listen(config.port); |
||||
logger.info('Listening Port ' + config.port); |
@ -0,0 +1,21 @@ |
||||
const blacklist = (process.env.BLACKLIST && process.env.BLACKLIST.split(',')) || []; |
||||
const whitelist = process.env.WHITELIST && process.env.WHITELIST.split(','); |
||||
|
||||
module.exports = async (ctx, next) => { |
||||
const ip = ctx.ips[0] || ctx.ip; |
||||
const referer = ctx.request.headers.referer; |
||||
|
||||
const refererAllowed = (whitelist && whitelist.indexOf(referer) !== -1) || blacklist.indexOf(referer) === -1; |
||||
const ipAllowed = (whitelist && whitelist.indexOf(ip) !== -1) || blacklist.indexOf(ip) === -1; |
||||
|
||||
if (refererAllowed && ipAllowed) { |
||||
await next(); |
||||
} else { |
||||
ctx.response.status = 403; |
||||
|
||||
ctx.body = JSON.stringify({ |
||||
code: 1, |
||||
msg: `${!refererAllowed ? '该站点' : '你的 IP '}没有访问权限`, |
||||
}); |
||||
} |
||||
}; |
@ -0,0 +1,14 @@ |
||||
const logger = require('../utils/logger'); |
||||
const headers = { |
||||
'Access-Control-Allow-Origin': '*', |
||||
'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild', |
||||
'Access-Control-Allow-Methods': 'PUT, POST, GET, DELETE, OPTIONS', |
||||
'Content-Type': 'application/json; charset=UTF-8', |
||||
'Cache-Control': 'no-cache', |
||||
}; |
||||
|
||||
module.exports = async (ctx, next) => { |
||||
logger.info(`${ctx.url}, user IP: ${ctx.ips[0] || ctx.ip}`); |
||||
ctx.set(headers); |
||||
await next(); |
||||
}; |
@ -0,0 +1,14 @@ |
||||
const logger = require('../utils/logger'); |
||||
|
||||
module.exports = async (ctx, next) => { |
||||
try { |
||||
await next(); |
||||
} catch (err) { |
||||
logger.error('Promise error: ' + (err instanceof Error ? err.stack : err)); |
||||
ctx.set({ |
||||
'Content-Type': 'text/html; charset=UTF-8', |
||||
}); |
||||
ctx.body = `DPlayer-node 发生了一些意外: <pre>${err instanceof Error ? err.stack : err}</pre>`; |
||||
ctx.status = 500; |
||||
} |
||||
}; |
@ -0,0 +1,24 @@ |
||||
{ |
||||
"name": "DPlayer_nodejs", |
||||
"version": "0.0.1", |
||||
"description": "", |
||||
"main": "index.js", |
||||
"author": "DIYgod", |
||||
"license": "MIT", |
||||
"devDependencies": { |
||||
"eslint": "5.0.1", |
||||
"eslint-config-prettier": "2.9.0", |
||||
"eslint-plugin-prettier": "2.6.1" |
||||
}, |
||||
"dependencies": { |
||||
"cheerio": "1.0.0-rc.2", |
||||
"koa": "2.5.1", |
||||
"koa-bodyparser": "4.2.1", |
||||
"koa-router": "7.4.0", |
||||
"mongoose": "5.1.7", |
||||
"node-fetch": "2.1.2", |
||||
"redis": "2.8.0", |
||||
"winston": "3.0.0", |
||||
"xml2js": "0.4.19" |
||||
} |
||||
} |
@ -0,0 +1,8 @@ |
||||
const Router = require('koa-router'); |
||||
const router = new Router(); |
||||
|
||||
router.get('/v3', require('./routes/get')); |
||||
router.post('/v3', require('./routes/post')); |
||||
router.get('/v3/bilibili', require('./routes/bilibili')); |
||||
|
||||
module.exports = router; |
@ -0,0 +1,46 @@ |
||||
const fetch = require('node-fetch'); |
||||
const cheerio = require('cheerio'); |
||||
|
||||
module.exports = async (ctx) => { |
||||
const aid = ctx.request.query.aid; |
||||
let cid = ctx.request.query.cid; |
||||
|
||||
if (!cid && aid) { |
||||
cid = await ctx.redis.get(`v3bilibiliaid2cid${aid}`); |
||||
if (!cid) { |
||||
const res = await fetch(`http://www.bilibili.com/widget/getPageList?aid=${aid}`); |
||||
const result = await res.json(); |
||||
cid = result[0].cid; |
||||
ctx.redis.set(`v3bilibiliaid2cid${aid}`, cid); |
||||
} |
||||
} |
||||
let data = await ctx.redis.get(`v3bilibilicid2dan${cid}`); |
||||
if (data) { |
||||
ctx.response.set('X-Koa-Redis', 'true'); |
||||
data = JSON.parse(data); |
||||
} else { |
||||
const res = await fetch(`https://api.bilibili.com/x/v1/dm/list.so?oid=${cid}`); |
||||
const result = await res.text(); |
||||
const $ = cheerio.load(result.replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]/g, ''), { |
||||
xmlMode: true |
||||
}); |
||||
data = $('d').map((i, el) => { |
||||
const item = $(el); |
||||
const p = item.attr('p').split(','); |
||||
let type = 0; |
||||
if (p[1] === '4') { |
||||
type = 2; |
||||
} |
||||
else if (p[1] === '5') { |
||||
type = 1; |
||||
} |
||||
return [[parseFloat(p[0]), type, parseInt(p[3]), p[6], item.text()]]; |
||||
}).get(); |
||||
ctx.redis.set(`v3bilibilicid2dan${cid}`, JSON.stringify(data), 10 * 60); |
||||
ctx.response.set('X-Koa-Origin', 'true'); |
||||
} |
||||
ctx.body = JSON.stringify({ |
||||
code: 0, |
||||
data: data, |
||||
}); |
||||
}; |
@ -0,0 +1,32 @@ |
||||
function htmlEncode (str) { |
||||
return str ? str.replace(/&/g, '&') |
||||
.replace(/</g, '<') |
||||
.replace(/>/g, '>') |
||||
.replace(/"/g, '"') |
||||
.replace(/'/g, ''') |
||||
.replace(/\//g, '/') : ''; |
||||
} |
||||
|
||||
module.exports = async (ctx) => { |
||||
const { id, limit } = ctx.request.query; |
||||
|
||||
let data = await ctx.redis.get(`danmaku${id}`); |
||||
if (data) { |
||||
data = JSON.parse(data); |
||||
if (limit) { |
||||
data = data.slice(-1 * parseInt(limit)); |
||||
} |
||||
ctx.response.set('X-Koa-Redis', 'true'); |
||||
} else { |
||||
data = await ctx.mongodb.find({ player: id }) || []; |
||||
ctx.redis.set(`danmaku${id}`, JSON.stringify(data)); |
||||
if (limit) { |
||||
data = data.slice(-1 * parseInt(limit)); |
||||
} |
||||
ctx.response.set('X-Koa-Mongodb', 'true'); |
||||
} |
||||
ctx.body = JSON.stringify({ |
||||
code: 0, |
||||
data: data.map((item) => [item.time || 0, item.type || 0, item.color || 16777215, htmlEncode(item.author) || 'DPlayer', htmlEncode(item.text) || '']), |
||||
}); |
||||
}; |
@ -0,0 +1,32 @@ |
||||
const logger = require('../utils/logger'); |
||||
|
||||
module.exports = async (ctx) => { |
||||
const body = ctx.request.body; |
||||
|
||||
const dan = new ctx.mongodb({ |
||||
player: body.id, |
||||
author: body.author, |
||||
time: body.time, |
||||
text: body.text, |
||||
color: body.color, |
||||
type: body.type, |
||||
ip: ctx.ips[0] || ctx.ip, |
||||
referer: ctx.headers.referer, |
||||
date: +new Date(), |
||||
}); |
||||
try { |
||||
const data = await dan.save(); |
||||
ctx.body = JSON.stringify({ |
||||
code: 0, |
||||
data, |
||||
}); |
||||
ctx.redis.del(`danmaku${data.player}`); |
||||
} |
||||
catch (err) { |
||||
logger.error(err); |
||||
ctx.body = JSON.stringify({ |
||||
code: 1, |
||||
msg: `Database error: ${err}`, |
||||
}); |
||||
} |
||||
}; |
@ -0,0 +1,29 @@ |
||||
const winston = require('winston'); |
||||
|
||||
const logger = winston.createLogger({ |
||||
level: 'info', |
||||
format: winston.format.json(), |
||||
transports: [ |
||||
//
|
||||
// - Write to all logs with level `info` and below to `combined.log`
|
||||
// - Write all logs error (and below) to `error.log`.
|
||||
//
|
||||
new winston.transports.File({ |
||||
filename: 'logs/error.log', |
||||
level: 'error', |
||||
}), |
||||
new winston.transports.File({ filename: 'logs/combined.log' }), |
||||
], |
||||
}); |
||||
|
||||
//
|
||||
// If we're not in production then log to the `console` with the format:
|
||||
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
|
||||
//
|
||||
logger.add( |
||||
new winston.transports.Console({ |
||||
format: winston.format.combine(winston.format.colorize(), winston.format.simple()), |
||||
}) |
||||
); |
||||
|
||||
module.exports = logger; |
@ -0,0 +1,31 @@ |
||||
const mongoose = require('mongoose'); |
||||
const config = require('../config'); |
||||
const logger = require('./logger'); |
||||
|
||||
mongoose.connect(`mongodb://${(config.mongodb.username && config.mongodb.password) ? `${config.mongodb.username}:${config.mongodb.password}@` : ''}${config.mongodb.host}:${config.mongodb.port}/${config.mongodb.database}`); |
||||
|
||||
const db = mongoose.connection; |
||||
db.on('error', (e) => { |
||||
logger.error('Mongodb error: ', e); |
||||
}); |
||||
db.once('open', () => { |
||||
logger.info('Mongodb connected'); |
||||
}); |
||||
|
||||
const danmakuSchema = new mongoose.Schema({ |
||||
player: { |
||||
type: String, |
||||
index: true, |
||||
}, |
||||
author: String, |
||||
time: Number, |
||||
text: String, |
||||
color: Number, |
||||
type: Number, |
||||
ip: String, |
||||
referer: String, |
||||
date: Number, |
||||
}); |
||||
const danmaku = mongoose.model('dan', danmakuSchema); |
||||
|
||||
module.exports = danmaku; |
@ -0,0 +1,35 @@ |
||||
const logger = require('./logger'); |
||||
const config = require('../config'); |
||||
const redis = require('redis'); |
||||
const { promisify } = require('util'); |
||||
|
||||
const options = { |
||||
host: config.redis.host, |
||||
port: config.redis.port, |
||||
password: config.redis.password, |
||||
}; |
||||
if (!options.password) { |
||||
delete options.password; |
||||
} |
||||
const client = redis.createClient(options); |
||||
|
||||
client.on('error', (e) => { |
||||
logger.error('Redis error: ', e); |
||||
}); |
||||
|
||||
client.on('connect', () => { |
||||
logger.info('Redis connected'); |
||||
}); |
||||
|
||||
const getAsync = promisify(client.get).bind(client); |
||||
|
||||
module.exports = { |
||||
set: (key, value, maxAge = 30 * 24 * 60 * 60) => { |
||||
logger.info('Set redis: ' + key); |
||||
client.setex(key, maxAge, value); |
||||
}, |
||||
get: async (key) => await getAsync(key), |
||||
del: (key) => { |
||||
client.del(key); |
||||
}, |
||||
}; |
@ -0,0 +1,202 @@ |
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
APPENDIX: How to apply the Apache License to your work. |
||||
|
||||
To apply the Apache License to your work, attach the following |
||||
boilerplate notice, with the fields enclosed by brackets "{}" |
||||
replaced with your own identifying information. (Don't include |
||||
the brackets!) The text should be enclosed in the appropriate |
||||
comment syntax for the file format. We also recommend that a |
||||
file or class name and description of purpose be included on the |
||||
same "printed page" as the copyright notice for easier |
||||
identification within third-party archives. |
||||
|
||||
Copyright {yyyy} {name of copyright owner} |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
|
@ -0,0 +1,9 @@ |
||||
[common] |
||||
server_addr = 127.0.0.1 |
||||
server_port = 7000 |
||||
|
||||
[ssh] |
||||
type = tcp |
||||
local_ip = 127.0.0.1 |
||||
local_port = 22 |
||||
remote_port = 6000 |
@ -0,0 +1,212 @@ |
||||
# [common] is integral section |
||||
[common] |
||||
# A literal address or host name for IPv6 must be enclosed |
||||
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" |
||||
server_addr = 0.0.0.0 |
||||
server_port = 7000 |
||||
|
||||
# if you want to connect frps by http proxy or socks5 proxy, you can set http_proxy here or in global environment variables |
||||
# it only works when protocol is tcp |
||||
# http_proxy = http://user:passwd@192.168.1.128:8080 |
||||
# http_proxy = socks5://user:passwd@192.168.1.128:1080 |
||||
|
||||
# console or real logFile path like ./frpc.log |
||||
log_file = ./frpc.log |
||||
|
||||
# trace, debug, info, warn, error |
||||
log_level = info |
||||
|
||||
log_max_days = 3 |
||||
|
||||
# for authentication |
||||
token = 12345678 |
||||
|
||||
# set admin address for control frpc's action by http api such as reload |
||||
admin_addr = 127.0.0.1 |
||||
admin_port = 7400 |
||||
admin_user = admin |
||||
admin_passwd = admin |
||||
|
||||
# connections will be established in advance, default value is zero |
||||
pool_count = 5 |
||||
|
||||
# if tcp stream multiplexing is used, default is true, it must be same with frps |
||||
tcp_mux = true |
||||
|
||||
# your proxy name will be changed to {user}.{proxy} |
||||
user = your_name |
||||
|
||||
# decide if exit program when first login failed, otherwise continuous relogin to frps |
||||
# default is true |
||||
login_fail_exit = true |
||||
|
||||
# communication protocol used to connect to server |
||||
# now it supports tcp and kcp and websocket, default is tcp |
||||
protocol = tcp |
||||
|
||||
# specify a dns server, so frpc will use this instead of default one |
||||
# dns_server = 8.8.8.8 |
||||
|
||||
# proxy names you want to start divided by ',' |
||||
# default is empty, means all proxies |
||||
# start = ssh,dns |
||||
|
||||
# heartbeat configure, it's not recommended to modify the default value |
||||
# the default value of heartbeat_interval is 10 and heartbeat_timeout is 90 |
||||
# heartbeat_interval = 30 |
||||
# heartbeat_timeout = 90 |
||||
|
||||
# 'ssh' is the unique proxy name |
||||
# if user in [common] section is not empty, it will be changed to {user}.{proxy} such as 'your_name.ssh' |
||||
[ssh] |
||||
# tcp | udp | http | https | stcp | xtcp, default is tcp |
||||
type = tcp |
||||
local_ip = 127.0.0.1 |
||||
local_port = 22 |
||||
# true or false, if true, messages between frps and frpc will be encrypted, default is false |
||||
use_encryption = false |
||||
# if true, message will be compressed |
||||
use_compression = false |
||||
# remote port listen by frps |
||||
remote_port = 6001 |
||||
# frps will load balancing connections for proxies in same group |
||||
group = test_group |
||||
# group should have same group key |
||||
group_key = 123456 |
||||
|
||||
[ssh_random] |
||||
type = tcp |
||||
local_ip = 127.0.0.1 |
||||
local_port = 22 |
||||
# if remote_port is 0, frps will assign a random port for you |
||||
remote_port = 0 |
||||
|
||||
# if you want to expose multiple ports, add 'range:' prefix to the section name |
||||
# frpc will generate multiple proxies such as 'tcp_port_6010', 'tcp_port_6011' and so on. |
||||
[range:tcp_port] |
||||
type = tcp |
||||
local_ip = 127.0.0.1 |
||||
local_port = 6010-6020,6022,6024-6028 |
||||
remote_port = 6010-6020,6022,6024-6028 |
||||
use_encryption = false |
||||
use_compression = false |
||||
|
||||
[dns] |
||||
type = udp |
||||
local_ip = 114.114.114.114 |
||||
local_port = 53 |
||||
remote_port = 6002 |
||||
use_encryption = false |
||||
use_compression = false |
||||
|
||||
[range:udp_port] |
||||
type = udp |
||||
local_ip = 127.0.0.1 |
||||
local_port = 6010-6020 |
||||
remote_port = 6010-6020 |
||||
use_encryption = false |
||||
use_compression = false |
||||
|
||||
# Resolve your domain names to [server_addr] so you can use http://web01.yourdomain.com to browse web01 and http://web02.yourdomain.com to browse web02 |
||||
[web01] |
||||
type = http |
||||
local_ip = 127.0.0.1 |
||||
local_port = 80 |
||||
use_encryption = false |
||||
use_compression = true |
||||
# http username and password are safety certification for http protocol |
||||
# if not set, you can access this custom_domains without certification |
||||
http_user = admin |
||||
http_pwd = admin |
||||
# if domain for frps is frps.com, then you can access [web01] proxy by URL http://test.frps.com |
||||
subdomain = web01 |
||||
custom_domains = web02.yourdomain.com |
||||
# locations is only available for http type |
||||
locations = /,/pic |
||||
host_header_rewrite = example.com |
||||
# params with prefix "header_" will be used to update http request headers |
||||
header_X-From-Where = frp |
||||
|
||||
[web02] |
||||
type = https |
||||
local_ip = 127.0.0.1 |
||||
local_port = 8000 |
||||
use_encryption = false |
||||
use_compression = false |
||||
subdomain = web01 |
||||
custom_domains = web02.yourdomain.com |
||||
|
||||
[plugin_unix_domain_socket] |
||||
type = tcp |
||||
remote_port = 6003 |
||||
# if plugin is defined, local_ip and local_port is useless |
||||
# plugin will handle connections got from frps |
||||
plugin = unix_domain_socket |
||||
# params with prefix "plugin_" that plugin needed |
||||
plugin_unix_path = /var/run/docker.sock |
||||
|
||||
[plugin_http_proxy] |
||||
type = tcp |
||||
remote_port = 6004 |
||||
plugin = http_proxy |
||||
plugin_http_user = abc |
||||
plugin_http_passwd = abc |
||||
|
||||
[plugin_socks5] |
||||
type = tcp |
||||
remote_port = 6005 |
||||
plugin = socks5 |
||||
plugin_user = abc |
||||
plugin_passwd = abc |
||||
|
||||
[plugin_static_file] |
||||
type = tcp |
||||
remote_port = 6006 |
||||
plugin = static_file |
||||
plugin_local_path = /var/www/blog |
||||
plugin_strip_prefix = static |
||||
plugin_http_user = abc |
||||
plugin_http_passwd = abc |
||||
|
||||
[secret_tcp] |
||||
# If the type is secret tcp, remote_port is useless |
||||
# Who want to connect local port should deploy another frpc with stcp proxy and role is visitor |
||||
type = stcp |
||||
# sk used for authentication for visitors |
||||
sk = abcdefg |
||||
local_ip = 127.0.0.1 |
||||
local_port = 22 |
||||
use_encryption = false |
||||
use_compression = false |
||||
|
||||
# user of frpc should be same in both stcp server and stcp visitor |
||||
[secret_tcp_visitor] |
||||
# frpc role visitor -> frps -> frpc role server |
||||
role = visitor |
||||
type = stcp |
||||
# the server name you want to visitor |
||||
server_name = secret_tcp |
||||
sk = abcdefg |
||||
# connect this address to visitor stcp server |
||||
bind_addr = 127.0.0.1 |
||||
bind_port = 9000 |
||||
use_encryption = false |
||||
use_compression = false |
||||
|
||||
[p2p_tcp] |
||||
type = xtcp |
||||
sk = abcdefg |
||||
local_ip = 127.0.0.1 |
||||
local_port = 22 |
||||
use_encryption = false |
||||
use_compression = false |
||||
|
||||
[p2p_tcp_visitor] |
||||
role = visitor |
||||
type = xtcp |
||||
server_name = p2p_tcp |
||||
sk = abcdefg |
||||
bind_addr = 127.0.0.1 |
||||
bind_port = 9001 |
||||
use_encryption = false |
||||
use_compression = false |
@ -0,0 +1,4 @@ |
||||
[common] |
||||
bind_port = 7777 |
||||
vhost_https_port = 4443 |
||||
vhost_http_port = 8080 |
@ -0,0 +1,3 @@ |
||||
#!/bin/bash |
||||
cd /home/frp/frp_0.21.0_linux_amd64 |
||||
nohup ./frps -c ./frps.ini & |
@ -0,0 +1,71 @@ |
||||
# [common] is integral section |
||||
[common] |
||||
# A literal address or host name for IPv6 must be enclosed |
||||
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" |
||||
bind_addr = 0.0.0.0 |
||||
bind_port = 7000 |
||||
|
||||
# udp port to help make udp hole to penetrate nat |
||||
bind_udp_port = 7001 |
||||
|
||||
# udp port used for kcp protocol, it can be same with 'bind_port' |
||||
# if not set, kcp is disabled in frps |
||||
kcp_bind_port = 7000 |
||||
|
||||
# specify which address proxy will listen for, default value is same with bind_addr |
||||
# proxy_bind_addr = 127.0.0.1 |
||||
|
||||
# if you want to support virtual host, you must set the http port for listening (optional) |
||||
# Note: http port and https port can be same with bind_port |
||||
vhost_http_port = 80 |
||||
vhost_https_port = 443 |
||||
|
||||
# response header timeout(seconds) for vhost http server, default is 60s |
||||
# vhost_http_timeout = 60 |
||||
|
||||
# set dashboard_addr and dashboard_port to view dashboard of frps |
||||
# dashboard_addr's default value is same with bind_addr |
||||
# dashboard is available only if dashboard_port is set |
||||
dashboard_addr = 0.0.0.0 |
||||
dashboard_port = 7500 |
||||
|
||||
# dashboard user and passwd for basic auth protect, if not set, both default value is admin |
||||
dashboard_user = admin |
||||
dashboard_pwd = admin |
||||
|
||||
# dashboard assets directory(only for debug mode) |
||||
# assets_dir = ./static |
||||
# console or real logFile path like ./frps.log |
||||
log_file = ./frps.log |
||||
|
||||
# trace, debug, info, warn, error |
||||
log_level = info |
||||
|
||||
log_max_days = 3 |
||||
|
||||
# auth token |
||||
token = 12345678 |
||||
|
||||
# heartbeat configure, it's not recommended to modify the default value |
||||
# the default value of heartbeat_timeout is 90 |
||||
# heartbeat_timeout = 90 |
||||
|
||||
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit |
||||
allow_ports = 2000-3000,3001,3003,4000-50000 |
||||
|
||||
# pool_count in each proxy will change to max_pool_count if they exceed the maximum value |
||||
max_pool_count = 5 |
||||
|
||||
# max ports can be used for each client, default value is 0 means no limit |
||||
max_ports_per_client = 0 |
||||
|
||||
# authentication_timeout means the timeout interval (seconds) when the frpc connects frps |
||||
# if authentication_timeout is zero, the time is not verified, default is 900s |
||||
authentication_timeout = 900 |
||||
|
||||
# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file |
||||
# when subdomain is test, the host used by routing is test.frps.com |
||||
subdomain_host = frps.com |
||||
|
||||
# if tcp stream multiplexing is used, default is true |
||||
tcp_mux = true |
@ -0,0 +1,2 @@ |
||||
[common] |
||||
bind_port = 7778 |
@ -0,0 +1 @@ |
||||
config.inc.php |
@ -0,0 +1,102 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$actionUrl = $security->getTokenUrl( |
||||
Typecho_Router::url('do', array('action' => 'backup', 'widget' => 'Backup'), |
||||
Typecho_Common::url('index.php', $options->rootUrl))); |
||||
|
||||
$backupFiles = Typecho_Widget::widget('Widget_Backup')->listFiles(); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12 col-tb-8"> |
||||
<div id="typecho-welcome"> |
||||
<form action="<?php echo $actionUrl; ?>" method="post">
|
||||
<h3><?php _e('备份您的数据'); ?></h3>
|
||||
<ul> |
||||
<li><?php _e('此备份操作仅包含<strong>内容数据</strong>, 并不会涉及任何<strong>设置信息</strong>'); ?></li>
|
||||
<li><?php _e('如果您的数据量过大, 为了避免操作超时, 建议您直接使用数据库提供的备份工具备份数据'); ?></li>
|
||||
<li><strong class="warning"><?php _e('为了缩小备份文件体积, 建议您在备份前删除不必要的数据'); ?></strong></li>
|
||||
</ul> |
||||
<p><button class="btn primary" type="submit"><?php _e('开始备份 »'); ?></button></p>
|
||||
<input tabindex="1" type="hidden" name="do" value="export"> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
|
||||
<div id="backup-secondary" class="col-mb-12 col-tb-4" role="form"> |
||||
<h3><?php _e('恢复数据'); ?></h3>
|
||||
<ul class="typecho-option-tabs clearfix"> |
||||
<li class="active w-50"><a href="#from-upload">上传</a></li> |
||||
<li class="w-50"><a href="#from-server">从服务器</a></li> |
||||
</ul> |
||||
|
||||
<form action="<?php echo $actionUrl; ?>" id="from-upload" class="tab-content" method="post" enctype="multipart/form-data">
|
||||
<ul class="typecho-option"> |
||||
<li> |
||||
<input tabindex="2" id="backup-upload-file" name="file" type="file" class="file"> |
||||
</li> |
||||
</ul> |
||||
<ul class="typecho-option typecho-option-submit"> |
||||
<li> |
||||
<button tabindex="3" type="submit" class="btn primary"><?php _e('上传并恢复 »'); ?></button>
|
||||
<input type="hidden" name="do" value="import"> |
||||
</li> |
||||
</ul> |
||||
</form> |
||||
|
||||
<form action="<?php echo $actionUrl; ?>" id="from-server" class="tab-content hidden" method="post">
|
||||
<ul class="typecho-option"> |
||||
<li> |
||||
<?php if (empty($backupFiles)): ?> |
||||
<p class="description"><?php _e('将备份文件手动上传至服务器的 %s 目录下后, 这里会出现文件选项', __TYPECHO_BACKUP_DIR__); ?></p>
|
||||
<?php else: ?> |
||||
<label class="typecho-label" for="backup-select-file"><?php _e('选择一个备份文件恢复数据'); ?></label>
|
||||
<select name="file" id="backup-select-file"> |
||||
<?php foreach ($backupFiles as $file): ?> |
||||
<option value="<?php echo $file; ?>"><?php echo $file; ?></option>
|
||||
<?php endforeach; ?> |
||||
</select> |
||||
<?php endif; ?> |
||||
</li> |
||||
</ul> |
||||
<ul class="typecho-option typecho-option-submit"> |
||||
<li> |
||||
<button tabindex="5" type="submit" class="btn primary"><?php _e('选择并恢复 »'); ?></button>
|
||||
<input type="hidden" name="do" value="import"> |
||||
</li> |
||||
</ul> |
||||
</form> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
?> |
||||
<script> |
||||
$('#backup-secondary .typecho-option-tabs li').click(function() { |
||||
$('#backup-secondary .typecho-option-tabs li').removeClass('active'); |
||||
$(this).addClass('active'); |
||||
$(this).parents('#backup-secondary').find('.tab-content').addClass('hidden'); |
||||
|
||||
var selected_tab = $(this).find('a').attr('href'); |
||||
$(selected_tab).removeClass('hidden'); |
||||
|
||||
return false; |
||||
}); |
||||
|
||||
$('#backup-secondary form').submit(function (e) { |
||||
if (!confirm('<?php _e('恢复操作将清除所有现有数据, 是否继续?'); ?>')) {
|
||||
return false; |
||||
} |
||||
}); |
||||
</script> |
||||
<?php include 'footer.php'; ?> |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-6 col-tb-offset-3"> |
||||
<?php Typecho_Widget::widget('Widget_Metas_Category_Edit')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,105 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<script src="<?php $options->adminStaticUrl('js', 'jquery.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'jquery-ui.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'typecho.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script> |
||||
(function () { |
||||
$(document).ready(function() { |
||||
// 处理消息机制 |
||||
(function () { |
||||
var prefix = '<?php echo Typecho_Cookie::getPrefix(); ?>',
|
||||
cookies = { |
||||
notice : $.cookie(prefix + '__typecho_notice'), |
||||
noticeType : $.cookie(prefix + '__typecho_notice_type'), |
||||
highlight : $.cookie(prefix + '__typecho_notice_highlight') |
||||
}, |
||||
path = '<?php echo Typecho_Cookie::getPath(); ?>';
|
||||
|
||||
if (!!cookies.notice && 'success|notice|error'.indexOf(cookies.noticeType) >= 0) { |
||||
var head = $('.typecho-head-nav'), |
||||
p = $('<div class="message popup ' + cookies.noticeType + '">' |
||||
+ '<ul><li>' + $.parseJSON(cookies.notice).join('</li><li>') |
||||
+ '</li></ul></div>'), offset = 0; |
||||
|
||||
if (head.length > 0) { |
||||
p.insertAfter(head); |
||||
offset = head.outerHeight(); |
||||
} else { |
||||
p.prependTo(document.body); |
||||
} |
||||
|
||||
function checkScroll () { |
||||
if ($(window).scrollTop() >= offset) { |
||||
p.css({ |
||||
'position' : 'fixed', |
||||
'top' : 0 |
||||
}); |
||||
} else { |
||||
p.css({ |
||||
'position' : 'absolute', |
||||
'top' : offset |
||||
}); |
||||
} |
||||
} |
||||
|
||||
$(window).scroll(function () { |
||||
checkScroll(); |
||||
}); |
||||
|
||||
checkScroll(); |
||||
|
||||
p.slideDown(function () { |
||||
var t = $(this), color = '#C6D880'; |
||||
|
||||
if (t.hasClass('error')) { |
||||
color = '#FBC2C4'; |
||||
} else if (t.hasClass('notice')) { |
||||
color = '#FFD324'; |
||||
} |
||||
|
||||
t.effect('highlight', {color : color}) |
||||
.delay(5000).fadeOut(function () { |
||||
$(this).remove(); |
||||
}); |
||||
}); |
||||
|
||||
|
||||
$.cookie(prefix + '__typecho_notice', null, {path : path}); |
||||
$.cookie(prefix + '__typecho_notice_type', null, {path : path}); |
||||
} |
||||
|
||||
if (cookies.highlight) { |
||||
$('#' + cookies.highlight).effect('highlight', 1000); |
||||
$.cookie(prefix + '__typecho_notice_highlight', null, {path : path}); |
||||
} |
||||
})(); |
||||
|
||||
|
||||
// 导航菜单 tab 聚焦时展开下拉菜单 |
||||
(function () { |
||||
$('#typecho-nav-list').find('.parent a').focus(function() { |
||||
$('#typecho-nav-list').find('.child').hide(); |
||||
$(this).parents('.root').find('.child').show(); |
||||
}); |
||||
$('.operate').find('a').focus(function() { |
||||
$('#typecho-nav-list').find('.child').hide(); |
||||
}); |
||||
})(); |
||||
|
||||
|
||||
if ($('.typecho-login').length == 0) { |
||||
$('a').each(function () { |
||||
var t = $(this), href = t.attr('href'); |
||||
|
||||
if ((href && href[0] == '#') |
||||
|| /^<?php echo preg_quote($options->adminUrl, '/'); ?>.*$/.exec(href)
|
||||
|| /^<?php echo substr(preg_quote(Typecho_Common::url('s', $options->index), '/'), 0, -1); ?>action\/[_a-zA-Z0-9\/]+.*$/.exec(href)) {
|
||||
return; |
||||
} |
||||
|
||||
t.attr('target', '_blank'); |
||||
}); |
||||
} |
||||
}); |
||||
})(); |
||||
</script> |
@ -0,0 +1,59 @@ |
||||
<?php |
||||
if (!defined('__DIR__')) { |
||||
define('__DIR__', dirname(__FILE__)); |
||||
} |
||||
|
||||
define('__TYPECHO_ADMIN__', true); |
||||
|
||||
/** 载入配置文件 */ |
||||
if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once __DIR__ . '/../config.inc.php') { |
||||
file_exists(__DIR__ . '/../install.php') ? header('Location: ../install.php') : print('Missing Config File'); |
||||
exit; |
||||
} |
||||
|
||||
/** 初始化组件 */ |
||||
Typecho_Widget::widget('Widget_Init'); |
||||
|
||||
/** 注册一个初始化插件 */ |
||||
Typecho_Plugin::factory('admin/common.php')->begin(); |
||||
|
||||
Typecho_Widget::widget('Widget_Options')->to($options); |
||||
Typecho_Widget::widget('Widget_User')->to($user); |
||||
Typecho_Widget::widget('Widget_Security')->to($security); |
||||
Typecho_Widget::widget('Widget_Menu')->to($menu); |
||||
|
||||
/** 初始化上下文 */ |
||||
$request = $options->request; |
||||
$response = $options->response; |
||||
|
||||
/** 检测是否是第一次登录 */ |
||||
$currentMenu = $menu->getCurrentMenu(); |
||||
list($prefixVersion, $suffixVersion) = explode('/', $options->version); |
||||
$params = parse_url($currentMenu[2]); |
||||
$adminFile = basename($params['path']); |
||||
|
||||
if (!$user->logged && !Typecho_Cookie::get('__typecho_first_run') && !empty($currentMenu)) { |
||||
|
||||
if ('welcome.php' != $adminFile) { |
||||
$response->redirect(Typecho_Common::url('welcome.php', $options->adminUrl)); |
||||
} else { |
||||
Typecho_Cookie::set('__typecho_first_run', 1); |
||||
} |
||||
|
||||
} else { |
||||
|
||||
/** 检测版本是否升级 */ |
||||
if ($user->pass('administrator', true) && !empty($currentMenu)) { |
||||
$mustUpgrade = (!defined('Typecho_Common::VERSION') || version_compare(str_replace('/', '.', Typecho_Common::VERSION), |
||||
str_replace('/', '.', $options->version), '>')); |
||||
|
||||
if ($mustUpgrade && 'upgrade.php' != $adminFile && 'backup.php' != $adminFile) { |
||||
$response->redirect(Typecho_Common::url('upgrade.php', $options->adminUrl)); |
||||
} else if (!$mustUpgrade && 'upgrade.php' == $adminFile) { |
||||
$response->redirect($options->adminUrl); |
||||
} else if (!$mustUpgrade && 'welcome.php' == $adminFile && $user->logged) { |
||||
$response->redirect($options->adminUrl); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,13 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<div class="typecho-foot" role="contentinfo"> |
||||
<div class="copyright"> |
||||
<a href="http://typecho.org" class="i-logo-s">Typecho</a> |
||||
<p><?php _e('由 <a href="http://typecho.org">%s</a> 强力驱动, 版本 %s (%s)', $options->software, $prefixVersion, $suffixVersion); ?></p>
|
||||
</div> |
||||
<nav class="resource"> |
||||
<a href="http://docs.typecho.org"><?php _e('帮助文档'); ?></a> •
|
||||
<a href="http://forum.typecho.org"><?php _e('支持论坛'); ?></a> •
|
||||
<a href="https://github.com/typecho/typecho/issues"><?php _e('报告错误'); ?></a> •
|
||||
<a href="http://extends.typecho.org"><?php _e('资源下载'); ?></a>
|
||||
</nav> |
||||
</div> |
@ -0,0 +1 @@ |
||||
/*!normalize.css v2.1.3 | MIT License | git.io/normalize */ article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden],template{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a{background:transparent;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;} |
@ -0,0 +1,44 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<script> |
||||
$(document).ready(function () { |
||||
// 自定义字段 |
||||
$('#custom-field-expand').click(function() { |
||||
var btn = $('i', this); |
||||
if (btn.hasClass('i-caret-right')) { |
||||
btn.removeClass('i-caret-right').addClass('i-caret-down'); |
||||
} else { |
||||
btn.removeClass('i-caret-down').addClass('i-caret-right'); |
||||
} |
||||
$(this).parent().toggleClass('fold'); |
||||
return false; |
||||
}); |
||||
|
||||
function attachDeleteEvent (el) { |
||||
$('button.btn-xs', el).click(function () { |
||||
if (confirm('<?php _e('确认要删除此字段吗?'); ?>')) {
|
||||
$(this).parents('tr').fadeOut(function () { |
||||
$(this).remove(); |
||||
}); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
$('#custom-field table tbody tr').each(function () { |
||||
attachDeleteEvent(this); |
||||
}); |
||||
|
||||
$('#custom-field button.operate-add').click(function () { |
||||
var html = '<tr><td><input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" class="text-s w-100"></td>'
|
||||
+ '<td><select name="fieldTypes[]" id="">' |
||||
+ '<option value="str"><?php _e('字符'); ?></option>'
|
||||
+ '<option value="int"><?php _e('整数'); ?></option>'
|
||||
+ '<option value="float"><?php _e('小数'); ?></option>'
|
||||
+ '</select></td>' |
||||
+ '<td><textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" class="text-s w-100" rows="2"></textarea></td>'
|
||||
+ '<td><button type="button" class="btn btn-xs"><?php _e('删除'); ?></button></td></tr>',
|
||||
el = $(html).hide().appendTo('#custom-field table tbody').fadeIn(); |
||||
|
||||
attachDeleteEvent(el); |
||||
}); |
||||
}); |
||||
</script> |
@ -0,0 +1,73 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<?php |
||||
$fields = isset($post) ? $post->getFieldItems() : $page->getFieldItems(); |
||||
$defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaultFieldItems(); |
||||
?> |
||||
<section id="custom-field" class="typecho-post-option<?php if (empty($defaultFields) && empty($fields)): ?> fold<?php endif; ?>">
|
||||
<label id="custom-field-expand" class="typecho-label"><a href="##"><i class="i-caret-right"></i> <?php _e('自定义字段'); ?></a></label>
|
||||
<table class="typecho-list-table mono"> |
||||
<colgroup> |
||||
<col width="25%"/> |
||||
<col width="10%"/> |
||||
<col width="55%"/> |
||||
<col width="10%"/> |
||||
</colgroup> |
||||
<?php foreach ($defaultFields as $field): ?> |
||||
<?php list ($label, $input) = $field; ?> |
||||
<tr> |
||||
<td><?php $label->render(); ?></td>
|
||||
<td colspan="3"><?php $input->render(); ?></td>
|
||||
</tr> |
||||
<?php endforeach; ?> |
||||
<?php foreach ($fields as $field): ?> |
||||
<tr> |
||||
<td> |
||||
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
|
||||
<input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>" id="fieldname" class="text-s w-100">
|
||||
</td> |
||||
<td> |
||||
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
|
||||
<select name="fieldTypes[]" id="fieldtype"> |
||||
<option value="str"<?php if ('str' == $field['type']): ?> selected<?php endif; ?>><?php _e('字符'); ?></option>
|
||||
<option value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
|
||||
<option value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
|
||||
</select> |
||||
</td> |
||||
<td> |
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100" rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea>
|
||||
</td> |
||||
<td> |
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
</td> |
||||
</tr> |
||||
<?php endforeach; ?> |
||||
<?php if (empty($defaultFields) && empty($fields)): ?> |
||||
<tr> |
||||
<td> |
||||
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
|
||||
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" id="fieldname" class="text-s w-100">
|
||||
</td> |
||||
<td> |
||||
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
|
||||
<select name="fieldTypes[]" id="fieldtype"> |
||||
<option value="str"><?php _e('字符'); ?></option>
|
||||
<option value="int"><?php _e('整数'); ?></option>
|
||||
<option value="float"><?php _e('小数'); ?></option>
|
||||
</select> |
||||
</td> |
||||
<td> |
||||
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
|
||||
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" id="fieldvalue" class="text-s w-100" rows="2"></textarea>
|
||||
</td> |
||||
<td> |
||||
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
|
||||
</td> |
||||
</tr> |
||||
<?php endif; ?> |
||||
</table> |
||||
<div class="description clearfix"> |
||||
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
|
||||
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?> |
||||
</div> |
||||
</section> |
@ -0,0 +1,336 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?> |
||||
<script src="<?php $options->adminStaticUrl('js', 'hyperdown.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'pagedown-extra.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'diff.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script> |
||||
$(document).ready(function () { |
||||
var textarea = $('#text'), |
||||
toolbar = $('<div class="editor" id="wmd-button-bar" />').insertBefore(textarea.parent()), |
||||
preview = $('<div id="wmd-preview" class="wmd-hidetab" />').insertAfter('.editor'); |
||||
|
||||
var options = {}, isMarkdown = <?php echo intval($content->isMarkdown || !$content->have()); ?>;
|
||||
|
||||
options.strings = { |
||||
bold: '<?php _e('加粗'); ?> <strong> Ctrl+B',
|
||||
boldexample: '<?php _e('加粗文字'); ?>',
|
||||
|
||||
italic: '<?php _e('斜体'); ?> <em> Ctrl+I',
|
||||
italicexample: '<?php _e('斜体文字'); ?>',
|
||||
|
||||
link: '<?php _e('链接'); ?> <a> Ctrl+L',
|
||||
linkdescription: '<?php _e('请输入链接描述'); ?>',
|
||||
|
||||
quote: '<?php _e('引用'); ?> <blockquote> Ctrl+Q',
|
||||
quoteexample: '<?php _e('引用文字'); ?>',
|
||||
|
||||
code: '<?php _e('代码'); ?> <pre><code> Ctrl+K',
|
||||
codeexample: '<?php _e('请输入代码'); ?>',
|
||||
|
||||
image: '<?php _e('图片'); ?> <img> Ctrl+G',
|
||||
imagedescription: '<?php _e('请输入图片描述'); ?>',
|
||||
|
||||
olist: '<?php _e('数字列表'); ?> <ol> Ctrl+O',
|
||||
ulist: '<?php _e('普通列表'); ?> <ul> Ctrl+U',
|
||||
litem: '<?php _e('列表项目'); ?>',
|
||||
|
||||
heading: '<?php _e('标题'); ?> <h1>/<h2> Ctrl+H',
|
||||
headingexample: '<?php _e('标题文字'); ?>',
|
||||
|
||||
hr: '<?php _e('分割线'); ?> <hr> Ctrl+R',
|
||||
more: '<?php _e('摘要分割线'); ?> <!--more--> Ctrl+M',
|
||||
|
||||
undo: '<?php _e('撤销'); ?> - Ctrl+Z',
|
||||
redo: '<?php _e('重做'); ?> - Ctrl+Y',
|
||||
redomac: '<?php _e('重做'); ?> - Ctrl+Shift+Z',
|
||||
|
||||
fullscreen: '<?php _e('全屏'); ?> - Ctrl+J',
|
||||
exitFullscreen: '<?php _e('退出全屏'); ?> - Ctrl+E',
|
||||
fullscreenUnsupport: '<?php _e('此浏览器不支持全屏操作'); ?>',
|
||||
|
||||
imagedialog: '<p><b><?php _e('插入图片'); ?></b></p><p><?php _e('请在下方的输入框内输入要插入的远程图片地址'); ?></p><p><?php _e('您也可以使用附件功能插入上传的本地图片'); ?></p>',
|
||||
linkdialog: '<p><b><?php _e('插入链接'); ?></b></p><p><?php _e('请在下方的输入框内输入要插入的链接地址'); ?></p>',
|
||||
|
||||
ok: '<?php _e('确定'); ?>',
|
||||
cancel: '<?php _e('取消'); ?>',
|
||||
|
||||
help: '<?php _e('Markdown语法帮助'); ?>'
|
||||
}; |
||||
|
||||
var converter = new HyperDown(), |
||||
editor = new Markdown.Editor(converter, '', options), |
||||
diffMatch = new diff_match_patch(), last = '', preview = $('#wmd-preview'), |
||||
mark = '@mark' + Math.ceil(Math.random() * 100000000) + '@', |
||||
span = '<span class="diff" />', |
||||
cache = {}; |
||||
|
||||
// 修正白名单 |
||||
converter.enableHtml(true); |
||||
converter.commonWhiteList += '|img|cite|embed|iframe'; |
||||
converter.specialWhiteList = $.extend(converter.specialWhiteList, { |
||||
'ol' : 'ol|li', |
||||
'ul' : 'ul|li', |
||||
'blockquote' : 'blockquote', |
||||
'pre' : 'pre|code' |
||||
}); |
||||
|
||||
converter.hook('beforeParseInline', function (html) { |
||||
return html.replace(/^\s*<!\-\-\s*more\s*\-\->\s*$/, function () { |
||||
return converter.makeHolder('<!--more-->'); |
||||
}); |
||||
}); |
||||
|
||||
// 自动跟随 |
||||
converter.hook('makeHtml', function (html) { |
||||
html = html.replace('<p><!--more--></p>', '<!--more-->'); |
||||
|
||||
if (html.indexOf('<!--more-->') > 0) { |
||||
var parts = html.split(/\s*<\!\-\-more\-\->\s*/), |
||||
summary = parts.shift(), |
||||
details = parts.join(''); |
||||
|
||||
html = '<div class="summary">' + summary + '</div>' |
||||
+ '<div class="details">' + details + '</div>'; |
||||
} |
||||
|
||||
|
||||
var diffs = diffMatch.diff_main(last, html); |
||||
last = html; |
||||
|
||||
if (diffs.length > 0) { |
||||
var stack = [], markStr = mark; |
||||
|
||||
for (var i = 0; i < diffs.length; i ++) { |
||||
var diff = diffs[i], op = diff[0], str = diff[1] |
||||
sp = str.lastIndexOf('<'), ep = str.lastIndexOf('>'); |
||||
|
||||
if (op != 0) { |
||||
if (sp >=0 && sp > ep) { |
||||
if (op > 0) { |
||||
stack.push(str.substring(0, sp) + markStr + str.substring(sp)); |
||||
} else { |
||||
var lastStr = stack[stack.length - 1], lastSp = lastStr.lastIndexOf('<'); |
||||
stack[stack.length - 1] = lastStr.substring(0, lastSp) + markStr + lastStr.substring(lastSp); |
||||
} |
||||
} else { |
||||
if (op > 0) { |
||||
stack.push(str + markStr); |
||||
} else { |
||||
stack.push(markStr); |
||||
} |
||||
} |
||||
|
||||
markStr = ''; |
||||
} else { |
||||
stack.push(str); |
||||
} |
||||
} |
||||
|
||||
html = stack.join(''); |
||||
|
||||
if (!markStr) { |
||||
var pos = html.indexOf(mark), prev = html.substring(0, pos), |
||||
next = html.substr(pos + mark.length), |
||||
sp = prev.lastIndexOf('<'), ep = prev.lastIndexOf('>'); |
||||
|
||||
if (sp >= 0 && sp > ep) { |
||||
html = prev.substring(0, sp) + span + prev.substring(sp) + next; |
||||
} else { |
||||
html = prev + span + next; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 替换img |
||||
html = html.replace(/<(img)\s+([^>]*)\s*src="([^"]+)"([^>]*)>/ig, function (all, tag, prefix, src, suffix) { |
||||
if (!cache[src]) { |
||||
cache[src] = false; |
||||
} else { |
||||
return '<span class="cache" data-width="' + cache[src][0] + '" data-height="' + cache[src][1] + '" ' |
||||
+ 'style="background:url(' + src + ') no-repeat left top; width:' |
||||
+ cache[src][0] + 'px; height:' + cache[src][1] + 'px; display: inline-block; max-width: 100%;' |
||||
+ '-webkit-background-size: contain;-moz-background-size: contain;-o-background-size: contain;background-size: contain;" />'; |
||||
} |
||||
|
||||
return all; |
||||
}); |
||||
|
||||
// 替换block |
||||
html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function (all, tag, src) { |
||||
if (src[src.length - 1] == '/') { |
||||
src = src.substring(0, src.length - 1); |
||||
} |
||||
|
||||
return '<div style="background: #ddd; height: 40px; overflow: hidden; line-height: 40px; text-align: center; font-size: 12px; color: #777">' |
||||
+ tag + ' : ' + $.trim(src) + '</div>'; |
||||
}); |
||||
|
||||
return html; |
||||
}); |
||||
|
||||
function cacheResize() { |
||||
var t = $(this), w = parseInt(t.data('width')), h = parseInt(t.data('height')), |
||||
ow = t.width(); |
||||
|
||||
t.height(h * ow / w); |
||||
} |
||||
|
||||
var to; |
||||
editor.hooks.chain('onPreviewRefresh', function () { |
||||
var diff = $('.diff', preview), scrolled = false; |
||||
|
||||
if (to) { |
||||
clearTimeout(to); |
||||
} |
||||
|
||||
$('img', preview).load(function () { |
||||
var t = $(this), src = t.attr('src'); |
||||
|
||||
if (scrolled) { |
||||
preview.scrollTo(diff, { |
||||
offset : - 50 |
||||
}); |
||||
} |
||||
|
||||
if (!!src && !cache[src]) { |
||||
cache[src] = [this.width, this.height]; |
||||
} |
||||
}); |
||||
|
||||
$('.cache', preview).resize(cacheResize).each(cacheResize); |
||||
|
||||
var changed = $('.diff', preview).parent(); |
||||
if (!changed.is(preview)) { |
||||
changed.css('background-color', 'rgba(255,230,0,0.5)'); |
||||
to = setTimeout(function () { |
||||
changed.css('background-color', 'transparent'); |
||||
}, 4500); |
||||
} |
||||
|
||||
if (diff.length > 0) { |
||||
var p = diff.position(), lh = diff.parent().css('line-height'); |
||||
lh = !!lh ? parseInt(lh) : 0; |
||||
|
||||
if (p.top < 0 || p.top > preview.height() - lh) { |
||||
preview.scrollTo(diff, { |
||||
offset : - 50 |
||||
}); |
||||
scrolled = true; |
||||
} |
||||
} |
||||
}); |
||||
|
||||
<?php Typecho_Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?> |
||||
|
||||
var input = $('#text'), th = textarea.height(), ph = preview.height(), |
||||
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">' |
||||
+ '<i class="i-upload"><?php _e('附件'); ?></i></button>')
|
||||
.prependTo('.submit .right') |
||||
.click(function() { |
||||
$('a', $('.typecho-option-tabs li').not('.active')).trigger('click'); |
||||
return false; |
||||
}); |
||||
|
||||
$('.typecho-option-tabs li').click(function () { |
||||
uploadBtn.find('i').toggleClass('i-upload-active', |
||||
$('#tab-files-btn', this).length > 0); |
||||
}); |
||||
|
||||
editor.hooks.chain('enterFakeFullScreen', function () { |
||||
th = textarea.height(); |
||||
ph = preview.height(); |
||||
$(document.body).addClass('fullscreen'); |
||||
var h = $(window).height() - toolbar.outerHeight(); |
||||
|
||||
textarea.css('height', h); |
||||
preview.css('height', h); |
||||
}); |
||||
|
||||
editor.hooks.chain('enterFullScreen', function () { |
||||
$(document.body).addClass('fullscreen'); |
||||
|
||||
var h = window.screen.height - toolbar.outerHeight(); |
||||
textarea.css('height', h); |
||||
preview.css('height', h); |
||||
}); |
||||
|
||||
editor.hooks.chain('exitFullScreen', function () { |
||||
$(document.body).removeClass('fullscreen'); |
||||
textarea.height(th); |
||||
preview.height(ph); |
||||
}); |
||||
|
||||
function initMarkdown() { |
||||
editor.run(); |
||||
|
||||
var imageButton = $('#wmd-image-button'), |
||||
linkButton = $('#wmd-link-button'); |
||||
|
||||
Typecho.insertFileToEditor = function (file, url, isImage) { |
||||
var button = isImage ? imageButton : linkButton; |
||||
|
||||
options.strings[isImage ? 'imagename' : 'linkname'] = file; |
||||
button.trigger('click'); |
||||
|
||||
var checkDialog = setInterval(function () { |
||||
if ($('.wmd-prompt-dialog').length > 0) { |
||||
$('.wmd-prompt-dialog input').val(url).select(); |
||||
clearInterval(checkDialog); |
||||
checkDialog = null; |
||||
} |
||||
}, 10); |
||||
}; |
||||
|
||||
Typecho.uploadComplete = function (file) { |
||||
Typecho.insertFileToEditor(file.title, file.url, file.isImage); |
||||
}; |
||||
|
||||
// 编辑预览切换 |
||||
var edittab = $('.editor').prepend('<div class="wmd-edittab"><a href="#wmd-editarea" class="active"><?php _e('撰写'); ?></a><a href="#wmd-preview"><?php _e('预览'); ?></a></div>'),
|
||||
editarea = $(textarea.parent()).attr("id", "wmd-editarea"); |
||||
|
||||
$(".wmd-edittab a").click(function() { |
||||
$(".wmd-edittab a").removeClass('active'); |
||||
$(this).addClass("active"); |
||||
$("#wmd-editarea, #wmd-preview").addClass("wmd-hidetab"); |
||||
|
||||
var selected_tab = $(this).attr("href"), |
||||
selected_el = $(selected_tab).removeClass("wmd-hidetab"); |
||||
|
||||
// 预览时隐藏编辑器按钮 |
||||
if (selected_tab == "#wmd-preview") { |
||||
$("#wmd-button-row").addClass("wmd-visualhide"); |
||||
} else { |
||||
$("#wmd-button-row").removeClass("wmd-visualhide"); |
||||
} |
||||
|
||||
// 预览和编辑窗口高度一致 |
||||
$("#wmd-preview").outerHeight($("#wmd-editarea").innerHeight()); |
||||
|
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
if (isMarkdown) { |
||||
initMarkdown(); |
||||
} else { |
||||
var notice = $('<div class="message notice"><?php _e('这篇文章不是由Markdown语法创建的, 继续使用Markdown编辑它吗?'); ?> '
|
||||
+ '<button class="btn btn-xs primary yes"><?php _e('是'); ?></button> '
|
||||
+ '<button class="btn btn-xs no"><?php _e('否'); ?></button></div>')
|
||||
.hide().insertBefore(textarea).slideDown(); |
||||
|
||||
$('.yes', notice).click(function () { |
||||
notice.remove(); |
||||
$('<input type="hidden" name="markdown" value="1" />').appendTo('.submit'); |
||||
initMarkdown(); |
||||
}); |
||||
|
||||
$('.no', notice).click(function () { |
||||
notice.remove(); |
||||
}); |
||||
} |
||||
}); |
||||
</script> |
||||
<?php endif; ?> |
||||
|
@ -0,0 +1,13 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
|
||||
$panel = $request->get('panel'); |
||||
$panelTable = unserialize($options->panelTable); |
||||
|
||||
if (!isset($panelTable['file']) || !in_array(urlencode($panel), $panelTable['file'])) { |
||||
throw new Typecho_Plugin_Exception(_t('页面不存在'), 404); |
||||
} |
||||
|
||||
list ($pluginName, $file) = explode('/', trim($panel, '/'), 2); |
||||
|
||||
require_once $options->pluginDir($pluginName) . '/' . $panel; |
@ -0,0 +1,212 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<?php |
||||
if (isset($post) && $post instanceof Typecho_Widget && $post->have()) { |
||||
$fileParentContent = $post; |
||||
} else if (isset($page) && $page instanceof Typecho_Widget && $page->have()) { |
||||
$fileParentContent = $page; |
||||
} |
||||
|
||||
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : 0; |
||||
|
||||
if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) { |
||||
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : '')); |
||||
} |
||||
?> |
||||
|
||||
<script src="<?php $options->adminStaticUrl('js', 'moxie.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'plupload.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script> |
||||
$(document).ready(function() { |
||||
function updateAttacmentNumber () { |
||||
var btn = $('#tab-files-btn'), |
||||
balloon = $('.balloon', btn), |
||||
count = $('#file-list li .insert').length; |
||||
|
||||
if (count > 0) { |
||||
if (!balloon.length) { |
||||
btn.html($.trim(btn.html()) + ' '); |
||||
balloon = $('<span class="balloon"></span>').appendTo(btn); |
||||
} |
||||
|
||||
balloon.html(count); |
||||
} else if (0 == count && balloon.length > 0) { |
||||
balloon.remove(); |
||||
} |
||||
} |
||||
|
||||
$('.upload-area').bind({ |
||||
dragenter : function () { |
||||
$(this).parent().addClass('drag'); |
||||
}, |
||||
|
||||
dragover : function (e) { |
||||
$(this).parent().addClass('drag'); |
||||
}, |
||||
|
||||
drop : function () { |
||||
$(this).parent().removeClass('drag'); |
||||
}, |
||||
|
||||
dragend : function () { |
||||
$(this).parent().removeClass('drag'); |
||||
}, |
||||
|
||||
dragleave : function () { |
||||
$(this).parent().removeClass('drag'); |
||||
} |
||||
}); |
||||
|
||||
updateAttacmentNumber(); |
||||
|
||||
function fileUploadStart (file) { |
||||
$('<li id="' + file.id + '" class="loading">' |
||||
+ file.name + '</li>').appendTo('#file-list'); |
||||
} |
||||
|
||||
function fileUploadError (error) { |
||||
var file = error.file, code = error.code, word; |
||||
|
||||
switch (code) { |
||||
case plupload.FILE_SIZE_ERROR: |
||||
word = '<?php _e('文件大小超过限制'); ?>';
|
||||
break; |
||||
case plupload.FILE_EXTENSION_ERROR: |
||||
word = '<?php _e('文件扩展名不被支持'); ?>';
|
||||
break; |
||||
case plupload.FILE_DUPLICATE_ERROR: |
||||
word = '<?php _e('文件已经上传过'); ?>';
|
||||
break; |
||||
case plupload.HTTP_ERROR: |
||||
default: |
||||
word = '<?php _e('上传出现错误'); ?>';
|
||||
break; |
||||
} |
||||
|
||||
var fileError = '<?php _e('%s 上传失败'); ?>'.replace('%s', file.name),
|
||||
li, exist = $('#' + file.id); |
||||
|
||||
if (exist.length > 0) { |
||||
li = exist.removeClass('loading').html(fileError); |
||||
} else { |
||||
li = $('<li>' + fileError + '<br />' + word + '</li>').appendTo('#file-list'); |
||||
} |
||||
|
||||
li.effect('highlight', {color : '#FBC2C4'}, 2000, function () { |
||||
$(this).remove(); |
||||
}); |
||||
|
||||
// fix issue #341 |
||||
this.removeFile(file); |
||||
} |
||||
|
||||
var completeFile = null; |
||||
function fileUploadComplete (id, url, data) { |
||||
var li = $('#' + id).removeClass('loading').data('cid', data.cid) |
||||
.data('url', data.url) |
||||
.data('image', data.isImage) |
||||
.html('<input type="hidden" name="attachment[]" value="' + data.cid + '" />' |
||||
+ '<a class="insert" target="_blank" href="###" title="<?php _e('点击插入文件'); ?>">' + data.title + '</a><div class="info">' + data.bytes
|
||||
+ ' <a class="file" target="_blank" href="<?php $options->adminUrl('media.php'); ?>?cid='
|
||||
+ data.cid + '" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>'
|
||||
+ ' <a class="delete" href="###" title="<?php _e('删除'); ?>"><i class="i-delete"></i></a></div>')
|
||||
.effect('highlight', 1000); |
||||
|
||||
attachInsertEvent(li); |
||||
attachDeleteEvent(li); |
||||
updateAttacmentNumber(); |
||||
|
||||
if (!completeFile) { |
||||
completeFile = data; |
||||
} |
||||
} |
||||
|
||||
$('#tab-files').bind('init', function () { |
||||
var uploader = new plupload.Uploader({ |
||||
browse_button : $('.upload-file').get(0), |
||||
url : '<?php $security->index('/action/upload' |
||||
. (isset($fileParentContent) ? '?cid=' . $fileParentContent->cid : '')); ?>', |
||||
runtimes : 'html5,flash,html4', |
||||
flash_swf_url : '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
|
||||
drop_element : $('.upload-area').get(0), |
||||
filters : { |
||||
max_file_size : '<?php echo $phpMaxFilesize ?>',
|
||||
mime_types : [{'title' : '<?php _e('允许上传的文件'); ?>', 'extensions' : '<?php echo implode(',', $options->allowedAttachmentTypes); ?>'}],
|
||||
prevent_duplicates : true |
||||
}, |
||||
|
||||
init : { |
||||
FilesAdded : function (up, files) { |
||||
for (var i = 0; i < files.length; i ++) { |
||||
fileUploadStart(files[i]); |
||||
} |
||||
|
||||
completeFile = null; |
||||
uploader.start(); |
||||
}, |
||||
|
||||
UploadComplete : function () { |
||||
if (completeFile) { |
||||
Typecho.uploadComplete(completeFile); |
||||
} |
||||
}, |
||||
|
||||
FileUploaded : function (up, file, result) { |
||||
if (200 == result.status) { |
||||
var data = $.parseJSON(result.response); |
||||
|
||||
if (data) { |
||||
fileUploadComplete(file.id, data[0], data[1]); |
||||
uploader.removeFile(file); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
fileUploadError.call(uploader, { |
||||
code : plupload.HTTP_ERROR, |
||||
file : file |
||||
}); |
||||
}, |
||||
|
||||
Error : function (up, error) { |
||||
fileUploadError.call(uploader, error); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
uploader.init(); |
||||
}); |
||||
|
||||
function attachInsertEvent (el) { |
||||
$('.insert', el).click(function () { |
||||
var t = $(this), p = t.parents('li'); |
||||
Typecho.insertFileToEditor(t.text(), p.data('url'), p.data('image')); |
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
function attachDeleteEvent (el) { |
||||
var file = $('a.insert', el).text(); |
||||
$('.delete', el).click(function () { |
||||
if (confirm('<?php _e('确认要删除文件 %s 吗?'); ?>'.replace('%s', file))) {
|
||||
var cid = $(this).parents('li').data('cid'); |
||||
$.post('<?php $security->index('/action/contents-attachment-edit'); ?>',
|
||||
{'do' : 'delete', 'cid' : cid}, |
||||
function () { |
||||
$(el).fadeOut(function () { |
||||
$(this).remove(); |
||||
updateAttacmentNumber(); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
$('#file-list li').each(function () { |
||||
attachInsertEvent(this); |
||||
attachDeleteEvent(this); |
||||
}); |
||||
}); |
||||
</script> |
||||
|
@ -0,0 +1,30 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
|
||||
<?php |
||||
if (isset($post) || isset($page)) { |
||||
$cid = isset($post) ? $post->cid : $page->cid; |
||||
|
||||
if ($cid) { |
||||
Typecho_Widget::widget('Widget_Contents_Attachment_Related', 'parentId=' . $cid)->to($attachment); |
||||
} else { |
||||
Typecho_Widget::widget('Widget_Contents_Attachment_Unattached')->to($attachment); |
||||
} |
||||
} |
||||
?> |
||||
|
||||
<div id="upload-panel" class="p"> |
||||
<div class="upload-area" draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
|
||||
<ul id="file-list"> |
||||
<?php while ($attachment->next()): ?> |
||||
<li data-cid="<?php $attachment->cid(); ?>" data-url="<?php echo $attachment->attachment->url; ?>" data-image="<?php echo $attachment->attachment->isImage ? 1 : 0; ?>"><input type="hidden" name="attachment[]" value="<?php $attachment->cid(); ?>" />
|
||||
<a class="insert" title="<?php _e('点击插入文件'); ?>" href="###"><?php $attachment->title(); ?></a>
|
||||
<div class="info"> |
||||
<?php echo number_format(ceil($attachment->attachment->size / 1024)); ?> Kb
|
||||
<a class="file" target="_blank" href="<?php $options->adminUrl('media.php?cid=' . $attachment->cid); ?>" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>
|
||||
<a href="###" class="delete" title="<?php _e('删除'); ?>"><i class="i-delete"></i></a>
|
||||
</div> |
||||
</li> |
||||
<?php endwhile; ?> |
||||
</ul> |
||||
</div> |
||||
|
@ -0,0 +1,6 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
</body> |
||||
</html> |
||||
<?php |
||||
/** 注册一个结束插件 */ |
||||
Typecho_Plugin::factory('admin/footer.php')->end(); |
@ -0,0 +1,26 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<script> |
||||
(function () { |
||||
$(document).ready(function () { |
||||
var error = $('.typecho-option .error:first'); |
||||
|
||||
if (error.length > 0) { |
||||
$('html,body').scrollTop(error.parents('.typecho-option').offset().top); |
||||
} |
||||
|
||||
$('form').submit(function () { |
||||
if (this.submitted) { |
||||
return false; |
||||
} else { |
||||
this.submitted = true; |
||||
} |
||||
}); |
||||
|
||||
$('label input[type=text]').click(function (e) { |
||||
var check = $('#' + $(this).parents('label').attr('for')); |
||||
check.prop('checked', true); |
||||
return false; |
||||
}); |
||||
}); |
||||
})(); |
||||
</script> |
@ -0,0 +1,31 @@ |
||||
<?php |
||||
if (!defined('__TYPECHO_ADMIN__')) { |
||||
exit; |
||||
} |
||||
|
||||
$header = '<link rel="stylesheet" href="' . Typecho_Common::url('normalize.css?v=' . $suffixVersion, $options->adminStaticUrl('css')) . '"> |
||||
<link rel="stylesheet" href="' . Typecho_Common::url('grid.css?v=' . $suffixVersion, $options->adminStaticUrl('css')) . '"> |
||||
<link rel="stylesheet" href="' . Typecho_Common::url('style.css?v=' . $suffixVersion, $options->adminStaticUrl('css')) . '"> |
||||
<!--[if lt IE 9]> |
||||
<script src="' . Typecho_Common::url('html5shiv.js?v=' . $suffixVersion, $options->adminStaticUrl('js')) . '"></script> |
||||
<script src="' . Typecho_Common::url('respond.js?v=' . $suffixVersion, $options->adminStaticUrl('js')) . '"></script> |
||||
<![endif]-->'; |
||||
|
||||
/** 注册一个初始化插件 */ |
||||
$header = Typecho_Plugin::factory('admin/header.php')->header($header); |
||||
|
||||
?><!DOCTYPE HTML> |
||||
<html class="no-js"> |
||||
<head> |
||||
<meta charset="<?php $options->charset(); ?>">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||
<meta name="renderer" content="webkit"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
<title><?php _e('%s - %s - Powered by Typecho', $menu->title, $options->title); ?></title>
|
||||
<meta name="robots" content="noindex, nofollow"> |
||||
<?php echo $header; ?> |
||||
</head> |
||||
<body<?php if (isset($bodyClass)) {echo ' class="' . $bodyClass . '"';} ?>>
|
||||
<!--[if lt IE 9]> |
||||
<div class="message error browsehappy" role="dialog"><?php _e('当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>'); ?>.</div>
|
||||
<![endif]--> |
After Width: | Height: | Size: 847 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,158 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat'); |
||||
?> |
||||
<div class="main"> |
||||
<div class="container typecho-dashboard"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main"> |
||||
<div class="col-mb-12 welcome-board" role="main"> |
||||
<p><?php _e('目前有 <em>%s</em> 篇文章, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.', |
||||
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?> |
||||
<br><?php _e('点击下面的链接快速开始:'); ?></p>
|
||||
|
||||
<ul id="start-link" class="clearfix"> |
||||
<?php if($user->pass('contributor', true)): ?> |
||||
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
|
||||
<?php if($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?> |
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核的评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
|
||||
</li> |
||||
<?php elseif($stat->myWaitingCommentsNum > 0): ?> |
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'); ?>"><?php _e('待审核评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
|
||||
</li> |
||||
<?php endif; ?> |
||||
<?php if($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->spamCommentsNum > 0): ?> |
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
|
||||
</li> |
||||
<?php elseif($stat->mySpamCommentsNum > 0): ?> |
||||
<li><a href="<?php $options->adminUrl('manage-comments.php?status=spam'); ?>"><?php _e('垃圾评论'); ?></a>
|
||||
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
|
||||
</li> |
||||
<?php endif; ?> |
||||
<?php if($user->pass('administrator', true)): ?> |
||||
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('更换外观'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('plugins.php'); ?>"><?php _e('插件管理'); ?></a></li>
|
||||
<li><a href="<?php $options->adminUrl('options-general.php'); ?>"><?php _e('系统设置'); ?></a></li>
|
||||
<?php endif; ?> |
||||
<?php endif; ?> |
||||
<!--<li><a href="<?php $options->adminUrl('profile.php'); ?>"><?php _e('更新我的资料'); ?></a></li>-->
|
||||
</ul> |
||||
<?php $version = Typecho_Cookie::get('__typecho_check_version'); ?> |
||||
<?php if ($version && $version['available']): ?> |
||||
<div class="update-check"> |
||||
<p class="message notice"> |
||||
<?php _e('您当前使用的版本是'); ?> <?php echo $version['current']; ?> →
|
||||
<strong><a href="<?php echo $version['link']; ?>"><?php _e('官方最新版本是'); ?> <?php echo $version['latest']; ?></a></strong>
|
||||
</p> |
||||
</div> |
||||
<?php endif; ?> |
||||
</div> |
||||
|
||||
<div class="col-mb-12 col-tb-4" role="complementary"> |
||||
<section class="latest-link"> |
||||
<h3><?php _e('最近发布的文章'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize=10')->to($posts); ?> |
||||
<ul> |
||||
<?php if($posts->have()): ?> |
||||
<?php while($posts->next()): ?> |
||||
<li> |
||||
<span><?php $posts->date('n.j'); ?></span>
|
||||
<a href="<?php $posts->permalink(); ?>" class="title"><?php $posts->title(); ?></a>
|
||||
</li> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<li><em><?php _e('暂时没有文章'); ?></em></li>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
</section> |
||||
</div> |
||||
|
||||
<div class="col-mb-12 col-tb-4" role="complementary"> |
||||
<section class="latest-link"> |
||||
<h3><?php _e('最近得到的回复'); ?></h3>
|
||||
<ul> |
||||
<?php Typecho_Widget::widget('Widget_Comments_Recent', 'pageSize=10')->to($comments); ?> |
||||
<?php if($comments->have()): ?> |
||||
<?php while($comments->next()): ?> |
||||
<li> |
||||
<span><?php $comments->date('n.j'); ?></span>
|
||||
<a href="<?php $comments->permalink(); ?>" class="title"><?php $comments->author(true); ?></a>:
|
||||
<?php $comments->excerpt(35, '...'); ?> |
||||
</li> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<li><?php _e('暂时没有回复'); ?></li>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
</section> |
||||
</div> |
||||
|
||||
<div class="col-mb-12 col-tb-4" role="complementary"> |
||||
<section class="latest-link"> |
||||
<h3><?php _e('官方最新日志'); ?></h3>
|
||||
<div id="typecho-message"> |
||||
<ul> |
||||
<li><?php _e('读取中...'); ?></li>
|
||||
</ul> |
||||
</div> |
||||
</section> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
?> |
||||
|
||||
<script> |
||||
$(document).ready(function () { |
||||
var ul = $('#typecho-message ul'), cache = window.sessionStorage, |
||||
html = cache ? cache.getItem('feed') : '', |
||||
update = cache ? cache.getItem('update') : ''; |
||||
|
||||
if (!!html) { |
||||
ul.html(html); |
||||
} else { |
||||
html = ''; |
||||
$.get('<?php $options->index('/action/ajax?do=feed'); ?>', function (o) {
|
||||
for (var i = 0; i < o.length; i ++) { |
||||
var item = o[i]; |
||||
html += '<li><span>' + item.date + '</span> <a href="' + item.link + '" target="_blank">' + item.title |
||||
+ '</a></li>'; |
||||
} |
||||
|
||||
ul.html(html); |
||||
cache.setItem('feed', html); |
||||
}, 'json'); |
||||
} |
||||
|
||||
function applyUpdate(update) { |
||||
if (update.available) { |
||||
$('<div class="update-check message error"><p>' |
||||
+ '<?php _e('您当前使用的版本是 %s'); ?>'.replace('%s', update.current) + '<br />'
|
||||
+ '<strong><a href="' + update.link + '" target="_blank">' |
||||
+ '<?php _e('官方最新版本是 %s'); ?>'.replace('%s', update.latest) + '</a></strong></p></div>')
|
||||
.insertAfter('.typecho-page-title').effect('highlight'); |
||||
} |
||||
} |
||||
|
||||
if (!!update) { |
||||
applyUpdate($.parseJSON(update)); |
||||
} else { |
||||
$.get('<?php $options->index('/action/ajax?do=checkVersion'); ?>', function (o, status, resp) {
|
||||
applyUpdate(o); |
||||
cache.setItem('update', resp.responseText); |
||||
}, 'json'); |
||||
} |
||||
}); |
||||
|
||||
</script> |
||||
<?php include 'footer.php'; ?> |
@ -0,0 +1 @@ |
||||
(function(k,m){var g="3.7.0";var d=k.html5||{};var h=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;var c=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;var q;var i="_html5shiv";var a=0;var o={};var e;(function(){try{var t=m.createElement("a");t.innerHTML="<xyz></xyz>";q=("hidden" in t);e=t.childNodes.length==1||(function(){(m.createElement)("a");var v=m.createDocumentFragment();return(typeof v.cloneNode=="undefined"||typeof v.createDocumentFragment=="undefined"||typeof v.createElement=="undefined")}())}catch(u){q=true;e=true}}());function f(t,v){var w=t.createElement("p"),u=t.getElementsByTagName("head")[0]||t.documentElement;w.innerHTML="x<style>"+v+"</style>";return u.insertBefore(w.lastChild,u.firstChild)}function l(){var t=j.elements;return typeof t=="string"?t.split(" "):t}function p(t){var u=o[t[i]];if(!u){u={};a++;t[i]=a;o[a]=u}return u}function n(w,t,v){if(!t){t=m}if(e){return t.createElement(w)}if(!v){v=p(t)}var u;if(v.cache[w]){u=v.cache[w].cloneNode()}else{if(c.test(w)){u=(v.cache[w]=v.createElem(w)).cloneNode()}else{u=v.createElem(w)}}return u.canHaveChildren&&!h.test(w)?v.frag.appendChild(u):u}function r(v,x){if(!v){v=m}if(e){return v.createDocumentFragment()}x=x||p(v);var y=x.frag.cloneNode(),w=0,u=l(),t=u.length;for(;w<t;w++){y.createElement(u[w])}return y}function s(t,u){if(!u.cache){u.cache={};u.createElem=t.createElement;u.createFrag=t.createDocumentFragment;u.frag=u.createFrag()}t.createElement=function(v){if(!j.shivMethods){return u.createElem(v)}return n(v,t,u)};t.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/[\w\-]+/g,function(v){u.createElem(v);u.frag.createElement(v);return'c("'+v+'")'})+");return n}")(j,u.frag)}function b(t){if(!t){t=m}var u=p(t);if(j.shivCSS&&!q&&!u.hasCSS){u.hasCSS=!!f(t,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")}if(!e){s(t,u)}return t}var j={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:g,shivCSS:(d.shivCSS!==false),supportsUnknownElements:e,shivMethods:(d.shivMethods!==false),type:"default",shivDocument:b,createElement:n,createDocumentFragment:r};k.html5=j;b(m)}(this,document)); |
@ -0,0 +1,7 @@ |
||||
/* Respond.js v1.4.2: min/max-width media query polyfill |
||||
* Copyright 2013 Scott Jehl |
||||
* Licensed under MIT |
||||
* http://j.mp/respondjs */
|
||||
/* matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ |
||||
/* NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ |
||||
(function(a){a.matchMedia=a.matchMedia||function(f,g){var d,b=f.documentElement,c=b.firstElementChild||b.firstChild,e=f.createElement("body"),h=f.createElement("div");h.id="mq-test-1";h.style.cssText="position:absolute;top:-100em";e.style.background="none";e.appendChild(h);return function(i){h.innerHTML='­<style media="'+i+'"> #mq-test-1 { width: 42px; }</style>';b.insertBefore(e,c);d=h.offsetWidth===42;b.removeChild(e);return{matches:d,media:i}}}(a.document)})(this);(function(k){var u={};k.respond=u;u.update=function(){};var c=[],d=function(){var w=false;try{w=new k.XMLHttpRequest()}catch(A){w=new k.ActiveXObject("Microsoft.XMLHTTP")}return function(){return w}}(),n=function(w,B){var A=d();if(!A){return}A.open("GET",w,true);A.onreadystatechange=function(){if(A.readyState!==4||A.status!==200&&A.status!==304){return}B(A.responseText)};if(A.readyState===4){return}A.send(null)},r=function(w){return w.replace(u.regex.minmaxwh,"").match(u.regex.other)};u.ajax=n;u.queue=c;u.unsupportedmq=r;u.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g};u.mediaQueriesSupported=k.matchMedia&&k.matchMedia("only all")!==null&&k.matchMedia("only all").matches;if(u.mediaQueriesSupported){return}var z=k.document,t=z.documentElement,h=[],j=[],q=[],o={},g=30,e=z.getElementsByTagName("head")[0]||t,f=z.getElementsByTagName("base")[0],b=e.getElementsByTagName("link"),l,s,p,y=function(){var B,E=z.createElement("div"),w=z.body,D=t.style.fontSize,C=w&&w.style.fontSize,A=false;E.style.cssText="position:absolute;font-size:1em;width:1em";if(!w){w=A=z.createElement("body");w.style.background="none"}t.style.fontSize="100%";w.style.fontSize="100%";w.appendChild(E);if(A){t.insertBefore(w,t.firstChild)}B=E.offsetWidth;if(A){t.removeChild(w)}else{w.removeChild(E)}t.style.fontSize=D;if(C){w.style.fontSize=C}B=p=parseFloat(B);return B},i=function(L){var Q="clientWidth",C=t[Q],A=z.compatMode==="CSS1Compat"&&C||z.body[Q]||C,O={},P=b[b.length-1],B=new Date().getTime();if(L&&l&&B-l<g){k.clearTimeout(s);s=k.setTimeout(i,g);return}else{l=B}for(var J in h){if(h.hasOwnProperty(J)){var M=h[J],F=M.minw,I=M.maxw,K=F===null,N=I===null,w="em";if(!!F){F=parseFloat(F)*(F.indexOf(w)>-1?p||y():1)}if(!!I){I=parseFloat(I)*(I.indexOf(w)>-1?p||y():1)}if(!M.hasquery||(!K||!N)&&(K||A>=F)&&(N||A<=I)){if(!O[M.media]){O[M.media]=[]}O[M.media].push(j[M.rules])}}}for(var H in q){if(q.hasOwnProperty(H)){if(q[H]&&q[H].parentNode===e){e.removeChild(q[H])}}}q.length=0;for(var G in O){if(O.hasOwnProperty(G)){var E=z.createElement("style"),D=O[G].join("\n");E.type="text/css";E.media=G;e.insertBefore(E,P.nextSibling);if(E.styleSheet){E.styleSheet.cssText=D}else{E.appendChild(z.createTextNode(D))}q.push(E)}}},m=function(K,w,B){var I=K.replace(u.regex.comments,"").replace(u.regex.keyframes,"").match(u.regex.media),L=I&&I.length||0;w=w.substring(0,w.lastIndexOf("/"));var A=function(M){return M.replace(u.regex.urls,"$1"+w+"$2$3")},C=!L&&B;if(w.length){w+="/"}if(C){L=1}for(var F=0;F<L;F++){var G,H,D,J;if(C){G=B;j.push(A(K))}else{G=I[F].match(u.regex.findStyles)&&RegExp.$1;j.push(RegExp.$2&&A(RegExp.$2))}D=G.split(",");J=D.length;for(var E=0;E<J;E++){H=D[E];if(r(H)){continue}h.push({media:H.split("(")[0].match(u.regex.only)&&RegExp.$2||"all",rules:j.length-1,hasquery:H.indexOf("(")>-1,minw:H.match(u.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:H.match(u.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}i()},x=function(){if(c.length){var w=c.shift();n(w.href,function(A){m(A,w.href,w.media);o[w.href]=true;k.setTimeout(function(){x()},0)})}},a=function(){for(var C=0;C<b.length;C++){var B=b[C],A=B.href,D=B.media,w=B.rel&&B.rel.toLowerCase()==="stylesheet";if(!!A&&w&&!o[A]){if(B.styleSheet&&B.styleSheet.rawCssText){m(B.styleSheet.rawCssText,A,D);o[A]=true}else{if(!/^([a-zA-Z:]*\/\/)/.test(A)&&!f||A.replace(RegExp.$1,"").split("/")[0]===k.location.host){if(A.substring(0,2)==="//"){A=k.location.protocol+A}c.push({href:A,media:D})}}}}x()};a();u.update=a;u.getEmValue=y;function v(){i(true)}if(k.addEventListener){k.addEventListener("resize",v,false)}else{if(k.attachEvent){k.attachEvent("onresize",v)}}})(this); |
@ -0,0 +1,54 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
|
||||
if ($user->hasLogin()) { |
||||
$response->redirect($options->adminUrl); |
||||
} |
||||
$rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name')); |
||||
Typecho_Cookie::delete('__typecho_remember_name'); |
||||
|
||||
$bodyClass = 'body-100'; |
||||
|
||||
include 'header.php'; |
||||
?> |
||||
<div class="typecho-login-wrap"> |
||||
<div class="typecho-login"> |
||||
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1> |
||||
<form action="<?php $options->loginAction(); ?>" method="post" name="login" role="form">
|
||||
<p> |
||||
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>
|
||||
<input type="text" id="name" name="name" value="<?php echo $rememberName; ?>" placeholder="<?php _e('用户名'); ?>" class="text-l w-100" autofocus />
|
||||
</p> |
||||
<p> |
||||
<label for="password" class="sr-only"><?php _e('密码'); ?></label>
|
||||
<input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" />
|
||||
</p> |
||||
<p class="submit"> |
||||
<button type="submit" class="btn btn-l w-100 primary"><?php _e('登录'); ?></button>
|
||||
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
|
||||
</p> |
||||
<p> |
||||
<label for="remember"><input type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('下次自动登录'); ?></label>
|
||||
</p> |
||||
</form> |
||||
|
||||
<p class="more-link"> |
||||
<a href="<?php $options->siteUrl(); ?>"><?php _e('返回首页'); ?></a>
|
||||
<?php if($options->allowRegister): ?> |
||||
• |
||||
<a href="<?php $options->registerUrl(); ?>"><?php _e('用户注册'); ?></a>
|
||||
<?php endif; ?> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
<?php
|
||||
include 'common-js.php'; |
||||
?> |
||||
<script> |
||||
$(document).ready(function () { |
||||
$('#name').focus(); |
||||
}); |
||||
</script> |
||||
<?php |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,154 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
Typecho_Widget::widget('Widget_Metas_Category_Admin')->to($categories); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main manage-metas"> |
||||
|
||||
<div class="col-mb-12" role="main"> |
||||
|
||||
<form method="post" name="manage_categories" class="operate-form"> |
||||
<div class="typecho-list-operate clearfix"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('此分类下的所有内容将被删除, 你确认要删除这些分类吗?'); ?>" href="<?php $security->index('/action/metas-category-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('刷新分类可能需要等待较长时间, 你确认要刷新这些分类吗?'); ?>" href="<?php $security->index('/action/metas-category-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
|
||||
<li class="multiline"> |
||||
<button type="button" class="btn merge btn-s" rel="<?php $security->index('/action/metas-category-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
|
||||
<select name="merge"> |
||||
<?php $categories->parse('<option value="{mid}">{name}</option>'); ?> |
||||
</select> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="search" role="search"> |
||||
<?php $categories->backLink(); ?> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table"> |
||||
<colgroup> |
||||
<col width="20"/> |
||||
<col width="30%"/> |
||||
<col width="15%"/> |
||||
<col width="25%"/> |
||||
<col width=""/> |
||||
<col width="10%"/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr class="nodrag"> |
||||
<th> </th> |
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('子分类'); ?></th>
|
||||
<th><?php _e('缩略名'); ?></th>
|
||||
<th> </th> |
||||
<th><?php _e('文章数'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php if($categories->have()): ?> |
||||
<?php while ($categories->next()): ?> |
||||
<tr id="mid-<?php $categories->theId(); ?>">
|
||||
<td><input type="checkbox" value="<?php $categories->mid(); ?>" name="mid[]"/></td>
|
||||
<td><a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
|
||||
<a href="<?php $categories->permalink(); ?>" title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
|
||||
</td> |
||||
<td> |
||||
|
||||
<?php if (count($categories->children) > 0): ?> |
||||
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
|
||||
<?php else: ?> |
||||
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
|
||||
<?php endif; ?> |
||||
</td> |
||||
<td><?php $categories->slug(); ?></td>
|
||||
<td> |
||||
<?php if ($options->defaultCategory == $categories->mid): ?> |
||||
<?php _e('默认'); ?> |
||||
<?php else: ?> |
||||
<a class="hidden-by-mouse" href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>" title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
|
||||
<?php endif; ?> |
||||
</td> |
||||
<td><a class="balloon-button left size-<?php echo Typecho_Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>" href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a></td>
|
||||
</tr> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<tr> |
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何分类'); ?></h6></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
</form> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
?> |
||||
|
||||
<script type="text/javascript"> |
||||
(function () { |
||||
$(document).ready(function () { |
||||
var table = $('.typecho-list-table').tableDnD({ |
||||
onDrop : function () { |
||||
var ids = []; |
||||
|
||||
$('input[type=checkbox]', table).each(function () { |
||||
ids.push($(this).val()); |
||||
}); |
||||
|
||||
$.post('<?php $security->index('/action/metas-category-edit?do=sort'); ?>',
|
||||
$.param({mid : ids})); |
||||
|
||||
$('tr', table).each(function (i) { |
||||
if (i % 2) { |
||||
$(this).addClass('even'); |
||||
} else { |
||||
$(this).removeClass('even'); |
||||
} |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
table.tableSelectable({ |
||||
checkEl : 'input[type=checkbox]', |
||||
rowEl : 'tr', |
||||
selectAllEl : '.typecho-table-select-all', |
||||
actionEl : '.dropdown-menu a' |
||||
}); |
||||
|
||||
$('.btn-drop').dropdownMenu({ |
||||
btnEl : '.dropdown-toggle', |
||||
menuEl : '.dropdown-menu' |
||||
}); |
||||
|
||||
$('.dropdown-menu button.merge').click(function () { |
||||
var btn = $(this); |
||||
btn.parents('form').attr('action', btn.attr('rel')).submit(); |
||||
}); |
||||
|
||||
<?php if (isset($request->mid)): ?> |
||||
$('.typecho-mini-panel').effect('highlight', '#AACB36'); |
||||
<?php endif; ?> |
||||
}); |
||||
})(); |
||||
</script> |
||||
<?php include 'footer.php'; ?> |
||||
|
@ -0,0 +1,373 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat'); |
||||
$comments = Typecho_Widget::widget('Widget_Comments_Admin'); |
||||
$isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == Typecho_Cookie::get('__typecho_all_comments')); |
||||
?> |
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12 typecho-list"> |
||||
<div class="clearfix"> |
||||
<ul class="typecho-option-tabs right"> |
||||
<?php if($user->pass('editor', true) && !isset($request->cid)): ?> |
||||
<li class="<?php if($isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=on'); ?>"><?php _e('所有'); ?></a></li>
|
||||
<li class="<?php if(!$isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=off'); ?>"><?php _e('我的'); ?></a></li>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
<ul class="typecho-option-tabs"> |
||||
<li<?php if(!isset($request->status) || 'approved' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php' |
||||
. (isset($request->cid) ? '?cid=' . $request->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
|
||||
<li<?php if('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=waiting' |
||||
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('待审核'); ?> |
||||
<?php if(!$isAllComments && $stat->myWaitingCommentsNum > 0 && !isset($request->cid)): ?>
|
||||
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
|
||||
<?php elseif($isAllComments && $stat->waitingCommentsNum > 0 && !isset($request->cid)): ?> |
||||
<span class="balloon"><?php $stat->waitingCommentsNum(); ?></span>
|
||||
<?php elseif(isset($request->cid) && $stat->currentWaitingCommentsNum > 0): ?> |
||||
<span class="balloon"><?php $stat->currentWaitingCommentsNum(); ?></span>
|
||||
<?php endif; ?> |
||||
</a></li> |
||||
<li<?php if('spam' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=spam' |
||||
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('垃圾'); ?> |
||||
<?php if(!$isAllComments && $stat->mySpamCommentsNum > 0 && !isset($request->cid)): ?>
|
||||
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
|
||||
<?php elseif($isAllComments && $stat->spamCommentsNum > 0 && !isset($request->cid)): ?> |
||||
<span class="balloon"><?php $stat->spamCommentsNum(); ?></span>
|
||||
<?php elseif(isset($request->cid) && $stat->currentSpamCommentsNum > 0): ?> |
||||
<span class="balloon"><?php $stat->currentSpamCommentsNum(); ?></span>
|
||||
<?php endif; ?> |
||||
</a></li> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
|
||||
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
<?php if('spam' == $request->get('status')): ?> |
||||
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
|
||||
<?php endif; ?> |
||||
</div> |
||||
</div> |
||||
<div class="search" role="search"> |
||||
<?php if ('' != $request->keywords || '' != $request->category): ?> |
||||
<a href="<?php $options->adminUrl('manage-comments.php'
|
||||
. (isset($request->status) || isset($request->cid) ? '?' . |
||||
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') . |
||||
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . htmlspecialchars($request->get('cid')) : '') : '')); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?> |
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
|
||||
<?php if(isset($request->status)): ?> |
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
|
||||
<?php endif; ?> |
||||
<?php if(isset($request->cid)): ?> |
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
|
||||
<?php endif; ?> |
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
|
||||
<form method="post" name="manage_comments" class="operate-form"> |
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table"> |
||||
<colgroup> |
||||
<col width="3%"/> |
||||
<col width="6%" /> |
||||
<col width="20%"/> |
||||
<col width="71%"/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th> </th> |
||||
<th><?php _e('作者'); ?></th>
|
||||
<th> </th> |
||||
<th><?php _e('内容'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
|
||||
<?php if($comments->have()): ?> |
||||
<?php while($comments->next()): ?> |
||||
<tr id="<?php $comments->theId(); ?>" data-comment="<?php |
||||
$comment = array( |
||||
'author' => $comments->author, |
||||
'mail' => $comments->mail, |
||||
'url' => $comments->url, |
||||
'ip' => $comments->ip, |
||||
'type' => $comments->type, |
||||
'text' => $comments->text |
||||
); |
||||
|
||||
echo htmlspecialchars(Json::encode($comment)); |
||||
?>"> |
||||
<td valign="top"> |
||||
<input type="checkbox" value="<?php $comments->coid(); ?>" name="coid[]"/>
|
||||
</td> |
||||
<td valign="top"> |
||||
<div class="comment-avatar"> |
||||
<?php if ('comment' == $comments->type): ?> |
||||
<?php $comments->gravatar(40); ?> |
||||
<?php endif; ?> |
||||
<?php if ('comment' != $comments->type): ?> |
||||
<?php _e('引用'); ?> |
||||
<?php endif; ?> |
||||
</div> |
||||
</td> |
||||
<td valign="top" class="comment-head"> |
||||
<div class="comment-meta"> |
||||
<strong class="comment-author"><?php $comments->author(true); ?></strong>
|
||||
<?php if($comments->mail): ?> |
||||
<br /><span><a href="mailto:<?php $comments->mail(); ?>"><?php $comments->mail(); ?></a></span>
|
||||
<?php endif; ?> |
||||
<?php if($comments->ip): ?> |
||||
<br /><span><?php $comments->ip(); ?></span>
|
||||
<?php endif; ?> |
||||
</div> |
||||
</td> |
||||
<td valign="top" class="comment-body"> |
||||
<div class="comment-date"><?php $comments->dateWord(); ?> 于 <a href="<?php $comments->permalink(); ?>"><?php $comments->title(); ?></a></div>
|
||||
<div class="comment-content"> |
||||
<?php $comments->content(); ?> |
||||
</div> |
||||
<div class="comment-action hidden-by-mouse"> |
||||
<?php if('approved' == $comments->status): ?> |
||||
<span class="weak"><?php _e('通过'); ?></span>
|
||||
<?php else: ?> |
||||
<a href="<?php $security->index('/action/comments-edit?do=approved&coid=' . $comments->coid); ?>" class="operate-approved"><?php _e('通过'); ?></a>
|
||||
<?php endif; ?> |
||||
|
||||
<?php if('waiting' == $comments->status): ?> |
||||
<span class="weak"><?php _e('待审核'); ?></span>
|
||||
<?php else: ?> |
||||
<a href="<?php $security->index('/action/comments-edit?do=waiting&coid=' . $comments->coid); ?>" class="operate-waiting"><?php _e('待审核'); ?></a>
|
||||
<?php endif; ?> |
||||
|
||||
<?php if('spam' == $comments->status): ?> |
||||
<span class="weak"><?php _e('垃圾'); ?></span>
|
||||
<?php else: ?> |
||||
<a href="<?php $security->index('/action/comments-edit?do=spam&coid=' . $comments->coid); ?>" class="operate-spam"><?php _e('垃圾'); ?></a>
|
||||
<?php endif; ?> |
||||
|
||||
<a href="#<?php $comments->theId(); ?>" rel="<?php $security->index('/action/comments-edit?do=edit&coid=' . $comments->coid); ?>" class="operate-edit"><?php _e('编辑'); ?></a>
|
||||
|
||||
<?php if('approved' == $comments->status && 'comment' == $comments->type): ?> |
||||
<a href="#<?php $comments->theId(); ?>" rel="<?php $security->index('/action/comments-edit?do=reply&coid=' . $comments->coid); ?>" class="operate-reply"><?php _e('回复'); ?></a>
|
||||
<?php endif; ?> |
||||
|
||||
<a lang="<?php _e('你确认要删除%s的评论吗?', htmlspecialchars($comments->author)); ?>" href="<?php $security->index('/action/comments-edit?do=delete&coid=' . $comments->coid); ?>" class="operate-delete"><?php _e('删除'); ?></a>
|
||||
</div> |
||||
</td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<tr> |
||||
<td colspan="4"><h6 class="typecho-list-table-title"><?php _e('没有评论') ?></h6></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
</tbody> |
||||
</table><!-- end .typecho-list-table --> |
||||
</div><!-- end .typecho-table-wrap --> |
||||
|
||||
<?php if(isset($request->cid)): ?> |
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
|
||||
<?php endif; ?> |
||||
</form><!-- end .operate-form --> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
|
||||
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
|
||||
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
<?php if('spam' == $request->get('status')): ?> |
||||
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
|
||||
<?php endif; ?> |
||||
</div> |
||||
</div> |
||||
<?php if($comments->have()): ?> |
||||
<ul class="typecho-pager"> |
||||
<?php $comments->pageNav(); ?> |
||||
</ul> |
||||
<?php endif; ?> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
</div><!-- end .typecho-list --> |
||||
</div><!-- end .typecho-page-main --> |
||||
</div> |
||||
</div> |
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'table-js.php'; |
||||
?> |
||||
<script type="text/javascript"> |
||||
$(document).ready(function () { |
||||
// 记住滚动条 |
||||
function rememberScroll () { |
||||
$(window).bind('beforeunload', function () { |
||||
$.cookie('__typecho_comments_scroll', $('body').scrollTop()); |
||||
}); |
||||
} |
||||
|
||||
// 自动滚动 |
||||
(function () { |
||||
var scroll = $.cookie('__typecho_comments_scroll'); |
||||
|
||||
if (scroll) { |
||||
$.cookie('__typecho_comments_scroll', null); |
||||
$('html, body').scrollTop(scroll); |
||||
} |
||||
})(); |
||||
|
||||
$('.operate-delete').click(function () { |
||||
var t = $(this), href = t.attr('href'), tr = t.parents('tr'); |
||||
|
||||
if (confirm(t.attr('lang'))) { |
||||
tr.fadeOut(function () { |
||||
rememberScroll(); |
||||
window.location.href = href; |
||||
}); |
||||
} |
||||
|
||||
return false; |
||||
}); |
||||
|
||||
$('.operate-approved, .operate-waiting, .operate-spam').click(function () { |
||||
rememberScroll(); |
||||
window.location.href = $(this).attr('href'); |
||||
return false; |
||||
}); |
||||
|
||||
$('.operate-reply').click(function () { |
||||
var td = $(this).parents('td'), t = $(this); |
||||
|
||||
if ($('.comment-reply', td).length > 0) { |
||||
$('.comment-reply').remove(); |
||||
} else { |
||||
var form = $('<form method="post" action="' |
||||
+ t.attr('rel') + '" class="comment-reply">' |
||||
+ '<p><label for="text" class="sr-only"><?php _e('内容'); ?></label><textarea id="text" name="text" class="w-90 mono" rows="3"></textarea></p>'
|
||||
+ '<p><button type="submit" class="btn btn-s primary"><?php _e('回复'); ?></button> <button type="button" class="btn btn-s cancel"><?php _e('取消'); ?></button></p>'
|
||||
+ '</form>').insertBefore($('.comment-action', td)); |
||||
|
||||
$('.cancel', form).click(function () { |
||||
$(this).parents('.comment-reply').remove(); |
||||
}); |
||||
|
||||
var textarea = $('textarea', form).focus(); |
||||
|
||||
form.submit(function () { |
||||
var t = $(this), tr = t.parents('tr'), |
||||
reply = $('<div class="comment-reply-content"></div>').insertAfter($('.comment-content', tr)); |
||||
|
||||
reply.html('<p>' + textarea.val() + '</p>'); |
||||
$.post(t.attr('action'), t.serialize(), function (o) { |
||||
reply.html(o.comment.content) |
||||
.effect('highlight'); |
||||
}, 'json'); |
||||
|
||||
t.remove(); |
||||
return false; |
||||
}); |
||||
} |
||||
|
||||
return false; |
||||
}); |
||||
|
||||
$('.operate-edit').click(function () { |
||||
var tr = $(this).parents('tr'), t = $(this), id = tr.attr('id'), comment = tr.data('comment'); |
||||
tr.hide(); |
||||
|
||||
var edit = $('<tr class="comment-edit"><td> </td>' |
||||
+ '<td colspan="2" valign="top"><form method="post" action="' |
||||
+ t.attr('rel') + '" class="comment-edit-info">' |
||||
+ '<p><label for="' + id + '-author"><?php _e('用户名'); ?></label><input class="text-s w-100" id="'
|
||||
+ id + '-author" name="author" type="text"></p>' |
||||
+ '<p><label for="' + id + '-mail"><?php _e('电子邮箱'); ?></label>'
|
||||
+ '<input class="text-s w-100" type="email" name="mail" id="' + id + '-mail"></p>' |
||||
+ '<p><label for="' + id + '-url"><?php _e('个人主页'); ?></label>'
|
||||
+ '<input class="text-s w-100" type="text" name="url" id="' + id + '-url"></p></form></td>' |
||||
+ '<td valign="top"><form method="post" action="' |
||||
+ t.attr('rel') + '" class="comment-edit-content"><p><label for="' + id + '-text"><?php _e('内容'); ?></label>'
|
||||
+ '<textarea name="text" id="' + id + '-text" rows="6" class="w-90 mono"></textarea></p>' |
||||
+ '<p><button type="submit" class="btn btn-s primary"><?php _e('提交'); ?></button> '
|
||||
+ '<button type="button" class="btn btn-s cancel"><?php _e('取消'); ?></button></p></form></td></tr>')
|
||||
.data('id', id).data('comment', comment).insertAfter(tr); |
||||
|
||||
$('input[name=author]', edit).val(comment.author); |
||||
$('input[name=mail]', edit).val(comment.mail); |
||||
$('input[name=url]', edit).val(comment.url); |
||||
$('textarea[name=text]', edit).val(comment.text).focus(); |
||||
|
||||
$('.cancel', edit).click(function () { |
||||
var tr = $(this).parents('tr'); |
||||
|
||||
$('#' + tr.data('id')).show(); |
||||
tr.remove(); |
||||
}); |
||||
|
||||
$('form', edit).submit(function () { |
||||
var t = $(this), tr = t.parents('tr'), |
||||
oldTr = $('#' + tr.data('id')), |
||||
comment = oldTr.data('comment'); |
||||
|
||||
$('form', tr).each(function () { |
||||
var items = $(this).serializeArray(); |
||||
|
||||
for (var i = 0; i < items.length; i ++) { |
||||
var item = items[i]; |
||||
comment[item.name] = item.value; |
||||
} |
||||
}); |
||||
|
||||
var html = '<strong class="comment-author">' |
||||
+ (comment.url ? '<a target="_blank" href="' + comment.url + '">' |
||||
+ comment.author + '</a>' : comment.author) + '</strong>' |
||||
+ ('comment' != comment.type ? '<small><?php _e('引用'); ?></small>' : '')
|
||||
+ (comment.mail ? '<br /><span><a href="mailto:' + comment.mail + '">' |
||||
+ comment.mail + '</a></span>' : '') |
||||
+ (comment.ip ? '<br /><span>' + comment.ip + '</span>' : ''); |
||||
|
||||
$('.comment-meta', oldTr).html(html) |
||||
.effect('highlight'); |
||||
$('.comment-content', oldTr).html('<p>' + comment.text + '</p>'); |
||||
oldTr.data('comment', comment); |
||||
|
||||
$.post(t.attr('action'), comment, function (o) { |
||||
$('.comment-content', oldTr).html(o.comment.content) |
||||
.effect('highlight'); |
||||
}, 'json'); |
||||
|
||||
oldTr.show(); |
||||
tr.remove(); |
||||
|
||||
return false; |
||||
}); |
||||
|
||||
return false; |
||||
}); |
||||
}); |
||||
</script> |
||||
<?php |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,122 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat'); |
||||
?> |
||||
|
||||
<?php Typecho_Widget::widget('Widget_Contents_Attachment_Admin')->to($attachments); ?> |
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12"> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
<button class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>" lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
|
||||
</div> |
||||
</div> |
||||
<div class="search" role="search"> |
||||
<?php if ('' != $request->keywords): ?> |
||||
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?> |
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
|
||||
<form method="post" name="manage_medias" class="operate-form"> |
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table draggable"> |
||||
<colgroup> |
||||
<col width="20"/> |
||||
<col width="6%"/> |
||||
<col width="30%"/> |
||||
<col width=""/> |
||||
<col width="30%"/> |
||||
<col width="16%"/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th> </th> |
||||
<th> </th> |
||||
<th><?php _e('文件名'); ?></th>
|
||||
<th><?php _e('上传者'); ?></th>
|
||||
<th><?php _e('所属文章'); ?></th>
|
||||
<th><?php _e('发布日期'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php if($attachments->have()): ?> |
||||
<?php while($attachments->next()): ?> |
||||
<?php $mime = Typecho_Common::mimeIconType($attachments->attachment->mime); ?> |
||||
<tr id="<?php $attachments->theId(); ?>">
|
||||
<td><input type="checkbox" value="<?php $attachments->cid(); ?>" name="cid[]"/></td>
|
||||
<td><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a></td>
|
||||
<td> |
||||
<i class="mime-<?php echo $mime; ?>"></i>
|
||||
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
|
||||
<a href="<?php $attachments->permalink(); ?>" title="<?php _e('浏览 %s', $attachments->title); ?>"><i class="i-exlink"></i></a>
|
||||
</td> |
||||
<td><?php $attachments->author(); ?></td>
|
||||
<td> |
||||
<?php if ($attachments->parentPost->cid): ?> |
||||
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
|
||||
<?php else: ?> |
||||
<span class="description"><?php _e('未归档'); ?></span>
|
||||
<?php endif; ?> |
||||
</td> |
||||
<td><?php $attachments->dateWord(); ?></td>
|
||||
</tr> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<tr> |
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文件'); ?></h6></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
</tbody> |
||||
</table><!-- end .typecho-list-table --> |
||||
</div><!-- end .typecho-table-wrap --> |
||||
</form><!-- end .operate-form --> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>" href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
<button class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>" lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
|
||||
</div> |
||||
<?php if($attachments->have()): ?> |
||||
<ul class="typecho-pager"> |
||||
<?php $attachments->pageNav(); ?> |
||||
</ul> |
||||
<?php endif; ?>
|
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
|
||||
</div> |
||||
</div><!-- end .typecho-page-main --> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'table-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,132 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat'); |
||||
?> |
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12 typecho-list"> |
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>" href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="search" role="search"> |
||||
<?php if ('' != $request->keywords): ?> |
||||
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?> |
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
|
||||
<form method="post" name="manage_pages" class="operate-form"> |
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table"> |
||||
<colgroup> |
||||
<col width="20"/> |
||||
<col width="6%"/> |
||||
<col width="30%"/> |
||||
<col width="30%"/> |
||||
<col width=""/> |
||||
<col width="16%"/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr class="nodrag"> |
||||
<th> </th> |
||||
<th> </th> |
||||
<th><?php _e('标题'); ?></th>
|
||||
<th><?php _e('缩略名'); ?></th>
|
||||
<th><?php _e('作者'); ?></th>
|
||||
<th><?php _e('日期'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php Typecho_Widget::widget('Widget_Contents_Page_Admin')->to($pages); ?> |
||||
<?php if($pages->have()): ?> |
||||
<?php while($pages->next()): ?> |
||||
<tr id="<?php $pages->theId(); ?>">
|
||||
<td><input type="checkbox" value="<?php $pages->cid(); ?>" name="cid[]"/></td>
|
||||
<td><a href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>" title="<?php $pages->commentsNum(); ?> <?php _e('评论'); ?>"><?php $pages->commentsNum(); ?></a></td>
|
||||
<td> |
||||
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
|
||||
<?php
|
||||
if ($pages->hasSaved || 'page_draft' == $pages->type) { |
||||
echo '<em class="status">' . _t('草稿') . '</em>'; |
||||
} else if ('hidden' == $pages->status) { |
||||
echo '<em class="status">' . _t('隐藏') . '</em>'; |
||||
} |
||||
?> |
||||
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>" title="<?php _e('编辑 %s', htmlspecialchars($pages->title)); ?>"><i class="i-edit"></i></a>
|
||||
<?php if ('page_draft' != $pages->type): ?> |
||||
<a href="<?php $pages->permalink(); ?>" title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i class="i-exlink"></i></a>
|
||||
<?php endif; ?> |
||||
</td> |
||||
<td><?php $pages->slug(); ?></td>
|
||||
<td><?php $pages->author(); ?></td>
|
||||
<td> |
||||
<?php if ($pages->hasSaved): ?> |
||||
<span class="description"> |
||||
<?php $modifyDate = new Typecho_Date($pages->modified); ?> |
||||
<?php _e('保存于 %s', $modifyDate->word()); ?> |
||||
</span> |
||||
<?php else: ?> |
||||
<?php $pages->dateWord(); ?> |
||||
<?php endif; ?> |
||||
</td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<tr> |
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何页面'); ?></h6></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
</tbody> |
||||
</table> |
||||
</div><!-- end .typecho-table-wrap --> |
||||
</form><!-- end .operate-form --> |
||||
</div><!-- end .typecho-list --> |
||||
</div><!-- end .typecho-page-main --> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'table-js.php'; |
||||
?> |
||||
|
||||
<?php if(!isset($request->status) || 'publish' == $request->get('status')): ?> |
||||
<script type="text/javascript"> |
||||
(function () { |
||||
$(document).ready(function () { |
||||
var table = $('.typecho-list-table').tableDnD({ |
||||
onDrop : function () { |
||||
var ids = []; |
||||
|
||||
$('input[type=checkbox]', table).each(function () { |
||||
ids.push($(this).val()); |
||||
}); |
||||
|
||||
$.post('<?php $security->index('/action/contents-page-edit?do=sort'); ?>',
|
||||
$.param({cid : ids})); |
||||
} |
||||
}); |
||||
}); |
||||
})(); |
||||
</script> |
||||
<?php endif; ?> |
||||
|
||||
<?php include 'footer.php'; ?> |
@ -0,0 +1,193 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat'); |
||||
$posts = Typecho_Widget::widget('Widget_Contents_Post_Admin'); |
||||
$isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == Typecho_Cookie::get('__typecho_all_posts')); |
||||
?> |
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12 typecho-list"> |
||||
<div class="clearfix"> |
||||
<ul class="typecho-option-tabs right"> |
||||
<?php if($user->pass('editor', true) && !isset($request->uid)): ?> |
||||
<li class="<?php if($isAllPosts): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_posts=on'); ?>"><?php _e('所有'); ?></a></li>
|
||||
<li class="<?php if(!$isAllPosts): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_posts=off'); ?>"><?php _e('我的'); ?></a></li>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
<ul class="typecho-option-tabs"> |
||||
<li<?php if(!isset($request->status) || 'all' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-posts.php' |
||||
. (isset($request->uid) ? '?uid=' . $request->uid : '')); ?>"><?php _e('可用'); ?></a></li>
|
||||
<li<?php if('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-posts.php?status=waiting' |
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('待审核'); ?> |
||||
<?php if(!$isAllPosts && $stat->myWaitingPostsNum > 0 && !isset($request->uid)): ?> |
||||
<span class="balloon"><?php $stat->myWaitingPostsNum(); ?></span>
|
||||
<?php elseif($isAllPosts && $stat->waitingPostsNum > 0 && !isset($request->uid)): ?> |
||||
<span class="balloon"><?php $stat->waitingPostsNum(); ?></span>
|
||||
<?php elseif(isset($request->uid) && $stat->currentWaitingPostsNum > 0): ?> |
||||
<span class="balloon"><?php $stat->currentWaitingPostsNum(); ?></span>
|
||||
<?php endif; ?> |
||||
</a></li> |
||||
<li<?php if('draft' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-posts.php?status=draft' |
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('草稿'); ?> |
||||
<?php if(!$isAllPosts && $stat->myDraftPostsNum > 0 && !isset($request->uid)): ?> |
||||
<span class="balloon"><?php $stat->myDraftPostsNum(); ?></span>
|
||||
<?php elseif($isAllPosts && $stat->draftPostsNum > 0 && !isset($request->uid)): ?> |
||||
<span class="balloon"><?php $stat->draftPostsNum(); ?></span>
|
||||
<?php elseif(isset($request->uid) && $stat->currentDraftPostsNum > 0): ?> |
||||
<span class="balloon"><?php $stat->currentDraftPostsNum(); ?></span>
|
||||
<?php endif; ?> |
||||
</a></li> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="search" role="search"> |
||||
<?php if ('' != $request->keywords || '' != $request->category): ?> |
||||
<a href="<?php $options->adminUrl('manage-posts.php' |
||||
. (isset($request->status) || isset($request->uid) ? '?' . |
||||
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') . |
||||
(isset($request->uid) ? '?uid=' . htmlspecialchars($request->get('uid')) : '') : '')); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?> |
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
|
||||
<select name="category"> |
||||
<option value=""><?php _e('所有分类'); ?></option>
|
||||
<?php Typecho_Widget::widget('Widget_Metas_Category_List')->to($category); ?> |
||||
<?php while($category->next()): ?> |
||||
<option value="<?php $category->mid(); ?>"<?php if($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
|
||||
<?php endwhile; ?> |
||||
</select> |
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
<?php if(isset($request->uid)): ?> |
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>" name="uid" />
|
||||
<?php endif; ?> |
||||
<?php if(isset($request->status)): ?> |
||||
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
|
||||
<?php endif; ?> |
||||
</div> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
|
||||
<form method="post" name="manage_posts" class="operate-form"> |
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table"> |
||||
<colgroup> |
||||
<col width="20"/> |
||||
<col width="6%"/> |
||||
<col width="45%"/> |
||||
<col width=""/> |
||||
<col width="18%"/> |
||||
<col width="16%"/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th> </th> |
||||
<th> </th> |
||||
<th><?php _e('标题'); ?></th>
|
||||
<th><?php _e('作者'); ?></th>
|
||||
<th><?php _e('分类'); ?></th>
|
||||
<th><?php _e('日期'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php if($posts->have()): ?> |
||||
<?php while($posts->next()): ?> |
||||
<tr id="<?php $posts->theId(); ?>">
|
||||
<td><input type="checkbox" value="<?php $posts->cid(); ?>" name="cid[]"/></td>
|
||||
<td><a href="<?php $options->adminUrl('manage-comments.php?cid=' . ($posts->parentId ? $posts->parentId : $posts->cid)); ?>" class="balloon-button size-<?php echo Typecho_Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>" title="<?php $posts->commentsNum(); ?> <?php _e('评论'); ?>"><?php $posts->commentsNum(); ?></a></td>
|
||||
<td> |
||||
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
|
||||
<?php
|
||||
if ($posts->hasSaved || 'post_draft' == $posts->type) { |
||||
echo '<em class="status">' . _t('草稿') . '</em>'; |
||||
} else if ('hidden' == $posts->status) { |
||||
echo '<em class="status">' . _t('隐藏') . '</em>'; |
||||
} else if ('waiting' == $posts->status) { |
||||
echo '<em class="status">' . _t('待审核') . '</em>'; |
||||
} else if ('private' == $posts->status) { |
||||
echo '<em class="status">' . _t('私密') . '</em>'; |
||||
} else if ($posts->password) { |
||||
echo '<em class="status">' . _t('密码保护') . '</em>'; |
||||
} |
||||
?> |
||||
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>" title="<?php _e('编辑 %s', htmlspecialchars($posts->title)); ?>"><i class="i-edit"></i></a>
|
||||
<?php if ('post_draft' != $posts->type): ?> |
||||
<a href="<?php $posts->permalink(); ?>" title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i class="i-exlink"></i></a>
|
||||
<?php endif; ?> |
||||
</td> |
||||
<td><a href="<?php $options->adminUrl('manage-posts.php?uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a></td>
|
||||
<td><?php $categories = $posts->categories; $length = count($categories); ?> |
||||
<?php foreach ($categories as $key => $val): ?> |
||||
<?php echo '<a href="'; |
||||
$options->adminUrl('manage-posts.php?category=' . $val['mid'] |
||||
. (isset($request->uid) ? '&uid=' . $request->uid : '') |
||||
. (isset($request->status) ? '&status=' . $request->status : '')); |
||||
echo '">' . $val['name'] . '</a>' . ($key < $length - 1 ? ', ' : ''); ?> |
||||
<?php endforeach; ?> |
||||
</td> |
||||
<td> |
||||
<?php if ($posts->hasSaved): ?> |
||||
<span class="description"> |
||||
<?php $modifyDate = new Typecho_Date($posts->modified); ?> |
||||
<?php _e('保存于 %s', $modifyDate->word()); ?> |
||||
</span> |
||||
<?php else: ?> |
||||
<?php $posts->dateWord(); ?> |
||||
<?php endif; ?> |
||||
</td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<tr> |
||||
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文章'); ?></h6></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
</form><!-- end .operate-form --> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>" href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php if($posts->have()): ?> |
||||
<ul class="typecho-pager"> |
||||
<?php $posts->pageNav(); ?> |
||||
</ul> |
||||
<?php endif; ?> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
</div><!-- end .typecho-list --> |
||||
</div><!-- end .typecho-page-main --> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'table-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,91 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
Typecho_Widget::widget('Widget_Metas_Tag_Admin')->to($tags); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main manage-metas"> |
||||
|
||||
<div class="col-mb-12 col-tb-8" role="main"> |
||||
|
||||
<form method="post" name="manage_tags" class="operate-form"> |
||||
<div class="typecho-list-operate clearfix"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些标签吗?'); ?>" href="<?php $security->index('/action/metas-tag-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
<li><a lang="<?php _e('刷新标签可能需要等待较长时间, 你确认要刷新这些标签吗?'); ?>" href="<?php $security->index('/action/metas-tag-edit?do=refresh'); ?>"><?php _e('刷新'); ?></a></li>
|
||||
<li class="multiline"> |
||||
<button type="button" class="btn btn-s merge" rel="<?php $security->index('/action/metas-tag-edit?do=merge'); ?>"><?php _e('合并到'); ?></button>
|
||||
<input type="text" name="merge" class="text-s" /> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<ul class="typecho-list-notable tag-list clearfix"> |
||||
<?php if($tags->have()): ?> |
||||
<?php while ($tags->next()): ?> |
||||
<li class="size-<?php $tags->split(5, 10, 20, 30); ?>" id="<?php $tags->theId(); ?>">
|
||||
<input type="checkbox" value="<?php $tags->mid(); ?>" name="mid[]"/>
|
||||
<span rel="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><?php $tags->name(); ?></span>
|
||||
<a class="tag-edit-link" href="<?php echo $request->makeUriByRequest('mid=' . $tags->mid); ?>"><i class="i-edit"></i></a>
|
||||
</li> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<h6 class="typecho-list-table-title"><?php _e('没有任何标签'); ?></h6>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
<input type="hidden" name="do" value="delete" /> |
||||
</form> |
||||
|
||||
</div> |
||||
<div class="col-mb-12 col-tb-4" role="form"> |
||||
<?php Typecho_Widget::widget('Widget_Metas_Tag_Edit')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
?> |
||||
|
||||
<script type="text/javascript"> |
||||
(function () { |
||||
$(document).ready(function () { |
||||
|
||||
$('.typecho-list-notable').tableSelectable({ |
||||
checkEl : 'input[type=checkbox]', |
||||
rowEl : 'li', |
||||
selectAllEl : '.typecho-table-select-all', |
||||
actionEl : '.dropdown-menu a' |
||||
}); |
||||
|
||||
$('.btn-drop').dropdownMenu({ |
||||
btnEl : '.dropdown-toggle', |
||||
menuEl : '.dropdown-menu' |
||||
}); |
||||
|
||||
$('.dropdown-menu button.merge').click(function () { |
||||
var btn = $(this); |
||||
btn.parents('form').attr('action', btn.attr('rel')).submit(); |
||||
}); |
||||
|
||||
<?php if (isset($request->mid)): ?> |
||||
$('.typecho-mini-panel').effect('highlight', '#AACB36'); |
||||
<?php endif; ?> |
||||
}); |
||||
})(); |
||||
</script> |
||||
<?php include 'footer.php'; ?> |
||||
|
@ -0,0 +1,118 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12 typecho-list"> |
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="search" role="search"> |
||||
<?php if ('' != $request->keywords): ?> |
||||
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('« 取消筛选'); ?></a>
|
||||
<?php endif; ?> |
||||
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords" />
|
||||
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
|
||||
</div> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
|
||||
<form method="post" name="manage_users" class="operate-form"> |
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table"> |
||||
<colgroup> |
||||
<col width="20"/> |
||||
<col width="6%"/> |
||||
<col width="30%"/> |
||||
<col width=""/> |
||||
<col width="25%"/> |
||||
<col width="15%"/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th> </th> |
||||
<th> </th> |
||||
<th><?php _e('用户名'); ?></th>
|
||||
<th><?php _e('昵称'); ?></th>
|
||||
<th><?php _e('电子邮件'); ?></th>
|
||||
<th><?php _e('用户组'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php Typecho_Widget::widget('Widget_Users_Admin')->to($users); ?> |
||||
<?php while($users->next()): ?> |
||||
<tr id="user-<?php $users->uid(); ?>">
|
||||
<td><input type="checkbox" value="<?php $users->uid(); ?>" name="uid[]"/></td>
|
||||
<td><a href="<?php $options->adminUrl('manage-posts.php?uid=' . $users->uid); ?>" class="balloon-button left size-<?php echo Typecho_Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a></td>
|
||||
<td><a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
|
||||
<a href="<?php $users->permalink(); ?>" title="<?php _e('浏览 %s', $users->screenName); ?>"><i class="i-exlink"></i></a>
|
||||
</td> |
||||
<td><?php $users->screenName(); ?></td>
|
||||
<td><?php if($users->mail): ?><a href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?></td>
|
||||
<td><?php switch ($users->group) { |
||||
case 'administrator': |
||||
_e('管理员'); |
||||
break; |
||||
case 'editor': |
||||
_e('编辑'); |
||||
break; |
||||
case 'contributor': |
||||
_e('贡献者'); |
||||
break; |
||||
case 'subscriber': |
||||
_e('关注者'); |
||||
break; |
||||
case 'visitor': |
||||
_e('访问者'); |
||||
break; |
||||
default: |
||||
break; |
||||
} ?></td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
</tbody> |
||||
</table><!-- end .typecho-list-table --> |
||||
</div><!-- end .typecho-table-wrap --> |
||||
</form><!-- end .operate-form --> |
||||
|
||||
<div class="typecho-list-operate clearfix"> |
||||
<form method="get"> |
||||
<div class="operate"> |
||||
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
|
||||
<div class="btn-group btn-drop"> |
||||
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
|
||||
<ul class="dropdown-menu"> |
||||
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>" href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<?php if($users->have()): ?> |
||||
<ul class="typecho-pager"> |
||||
<?php $users->pageNav(); ?> |
||||
</ul> |
||||
<?php endif; ?> |
||||
</form> |
||||
</div><!-- end .typecho-list-operate --> |
||||
</div><!-- end .typecho-list --> |
||||
</div><!-- end .typecho-page-main --> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'table-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,194 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : 0; |
||||
|
||||
if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) { |
||||
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : '')); |
||||
} |
||||
|
||||
Typecho_Widget::widget('Widget_Contents_Attachment_Edit')->to($attachment); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main"> |
||||
<div class="col-mb-12 col-tb-8" role="main"> |
||||
<?php if ($attachment->attachment->isImage): ?> |
||||
<p><img src="<?php $attachment->attachment->url(); ?>" alt="<?php $attachment->attachment->name(); ?>" class="typecho-attachment-photo" /></p>
|
||||
<?php endif; ?> |
||||
|
||||
<p> |
||||
<?php $mime = Typecho_Common::mimeIconType($attachment->attachment->mime); ?> |
||||
<i class="mime-<?php echo $mime; ?>"></i>
|
||||
<a href=""><strong><?php $attachment->attachment->name(); ?></strong></a>
|
||||
<span><?php echo number_format(ceil($attachment->attachment->size / 1024)); ?> Kb</span>
|
||||
</p> |
||||
|
||||
<p> |
||||
<input id="attachment-url" type="text" class="mono w-100" value="<?php $attachment->attachment->url(); ?>" readonly />
|
||||
</p> |
||||
|
||||
<div id="upload-panel" class="p"> |
||||
<div class="upload-area" draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
|
||||
<ul id="file-list"></ul> |
||||
</div> |
||||
</div> |
||||
<div class="col-mb-12 col-tb-4 edit-media" role="form"> |
||||
<?php $attachment->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
?> |
||||
<script src="<?php $options->adminStaticUrl('js', 'moxie.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script src="<?php $options->adminStaticUrl('js', 'plupload.js?v=' . $suffixVersion); ?>"></script>
|
||||
<script type="text/javascript"> |
||||
$(document).ready(function() { |
||||
$('#attachment-url').click(function () { |
||||
$(this).select(); |
||||
}); |
||||
|
||||
$('.operate-delete').click(function () { |
||||
var t = $(this), href = t.attr('href'); |
||||
|
||||
if (confirm(t.attr('lang'))) { |
||||
window.location.href = href; |
||||
} |
||||
|
||||
return false; |
||||
}); |
||||
|
||||
$('.upload-area').bind({ |
||||
dragenter : function () { |
||||
$(this).parent().addClass('drag'); |
||||
}, |
||||
|
||||
dragover : function (e) { |
||||
$(this).parent().addClass('drag'); |
||||
}, |
||||
|
||||
drop : function () { |
||||
$(this).parent().removeClass('drag'); |
||||
}, |
||||
|
||||
dragend : function () { |
||||
$(this).parent().removeClass('drag'); |
||||
}, |
||||
|
||||
dragleave : function () { |
||||
$(this).parent().removeClass('drag'); |
||||
} |
||||
}); |
||||
|
||||
function fileUploadStart (file) { |
||||
$('<ul id="file-list"></ul>').appendTo('#upload-panel'); |
||||
$('<li id="' + file.id + '" class="loading">' |
||||
+ file.name + '</li>').prependTo('#file-list'); |
||||
} |
||||
|
||||
function fileUploadError (error) { |
||||
var file = error.file, code = error.code, word; |
||||
|
||||
switch (code) { |
||||
case plupload.FILE_SIZE_ERROR: |
||||
word = '<?php _e('文件大小超过限制'); ?>';
|
||||
break; |
||||
case plupload.FILE_EXTENSION_ERROR: |
||||
word = '<?php _e('文件扩展名不被支持'); ?>';
|
||||
break; |
||||
case plupload.FILE_DUPLICATE_ERROR: |
||||
word = '<?php _e('文件已经上传过'); ?>';
|
||||
break; |
||||
case plupload.HTTP_ERROR: |
||||
default: |
||||
word = '<?php _e('上传出现错误'); ?>';
|
||||
break; |
||||
} |
||||
|
||||
var fileError = '<?php _e('%s 上传失败'); ?>'.replace('%s', file.name),
|
||||
li, exist = $('#' + file.id); |
||||
|
||||
if (exist.length > 0) { |
||||
li = exist.removeClass('loading').html(fileError); |
||||
} else { |
||||
$('<ul id="file-list"></ul>').appendTo('#upload-panel'); |
||||
li = $('<li>' + fileError + '<br />' + word + '</li>').prependTo('#file-list'); |
||||
} |
||||
|
||||
li.effect('highlight', {color : '#FBC2C4'}, 2000, function () { |
||||
$(this).remove(); |
||||
}); |
||||
} |
||||
|
||||
function fileUploadComplete (id, url, data) { |
||||
var img = $('.typecho-attachment-photo'); |
||||
|
||||
if (img.length > 0) { |
||||
img.get(0).src = '<?php $attachment->attachment->url(); ?>?' + Math.random();
|
||||
} |
||||
|
||||
$('#' + id).html('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', data.title))
|
||||
.effect('highlight', 1000, function () { |
||||
$(this).remove(); |
||||
$('#file-list').remove(); |
||||
}); |
||||
} |
||||
|
||||
var uploader = new plupload.Uploader({ |
||||
browse_button : $('.upload-file').get(0), |
||||
url : '<?php $security->index('/action/upload?do=modify&cid=' . $attachment->cid); ?>',
|
||||
runtimes : 'html5,flash,html4', |
||||
flash_swf_url : '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
|
||||
drop_element : $('.upload-area').get(0), |
||||
filters : { |
||||
max_file_size : '<?php echo $phpMaxFilesize ?>',
|
||||
mime_types : [{'title' : '<?php _e('允许上传的文件'); ?>', 'extensions' : '<?php $attachment->attachment->type(); ?>'}],
|
||||
prevent_duplicates : true |
||||
}, |
||||
multi_selection : false, |
||||
|
||||
init : { |
||||
FilesAdded : function (up, files) { |
||||
plupload.each(files, function(file) { |
||||
fileUploadStart(file); |
||||
}); |
||||
|
||||
uploader.start(); |
||||
}, |
||||
|
||||
FileUploaded : function (up, file, result) { |
||||
if (200 == result.status) { |
||||
var data = $.parseJSON(result.response); |
||||
|
||||
if (data) { |
||||
fileUploadComplete(file.id, data[0], data[1]); |
||||
return; |
||||
} |
||||
} |
||||
|
||||
fileUploadError({ |
||||
code : plupload.HTTP_ERROR, |
||||
file : file |
||||
}); |
||||
}, |
||||
|
||||
Error : function (up, error) { |
||||
fileUploadError(error); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
uploader.init(); |
||||
}); |
||||
</script> |
||||
<?php |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,16 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<div class="typecho-head-nav clearfix" role="navigation"> |
||||
<nav id="typecho-nav-list"> |
||||
<?php $menu->output(); ?> |
||||
</nav> |
||||
<div class="operate"> |
||||
<?php Typecho_Plugin::factory('admin/menu.php')->navBar(); ?> |
||||
<a title="<?php |
||||
if ($user->logged > 0) { |
||||
$logged = new Typecho_Date($user->logged); |
||||
_e('最后登录: %s', $logged->word()); |
||||
} |
||||
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
|
||||
</div> |
||||
</div> |
||||
|
@ -0,0 +1,23 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2"> |
||||
<?php Typecho_Widget::widget('Widget_Options_Discussion')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2"> |
||||
<?php Typecho_Widget::widget('Widget_Options_General')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,24 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2"> |
||||
<?php Typecho_Widget::widget('Widget_Options_Permalink')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
?> |
||||
|
||||
<?php include 'footer.php'; ?> |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2"> |
||||
<?php Typecho_Widget::widget('Widget_Plugins_Config')->config()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,37 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2"> |
||||
<?php Typecho_Widget::widget('Widget_Options_Reading')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
?> |
||||
<script> |
||||
$('#frontPage-recent,#frontPage-page,#frontPage-file').change(function () { |
||||
var t = $(this); |
||||
if (t.prop('checked')) { |
||||
if ('frontPage-recent' == t.attr('id')) { |
||||
$('.front-archive').addClass('hidden'); |
||||
} else { |
||||
$('.front-archive').insertAfter(t.parent()).removeClass('hidden'); |
||||
} |
||||
} |
||||
}); |
||||
</script> |
||||
<?php |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,32 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12"> |
||||
<ul class="typecho-option-tabs fix-tabs clearfix"> |
||||
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
|
||||
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?> |
||||
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
|
||||
<?php endif; ?> |
||||
<li class="current"><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
</ul> |
||||
</div> |
||||
<div class="col-mb-12 col-tb-8 col-tb-offset-2" role="form"> |
||||
<?php Typecho_Widget::widget('Widget_Themes_Config')->config()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,8 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<div class="typecho-page-title"> |
||||
<h2><?php echo $menu->title; ?><?php
|
||||
if (!empty($menu->addLink)) { |
||||
echo "<a href=\"{$menu->addLink}\">" . _t("新增") . "</a>"; |
||||
} |
||||
?></h2> |
||||
</div> |
@ -0,0 +1,127 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12 typecho-list"> |
||||
<?php Typecho_Widget::widget('Widget_Plugins_List@activated', 'activated=1')->to($activatedPlugins); ?> |
||||
<?php if ($activatedPlugins->have() || !empty($activatedPlugins->activatedPlugins)): ?> |
||||
<h4 class="typecho-list-table-title"><?php _e('启用的插件'); ?></h4>
|
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table"> |
||||
<colgroup> |
||||
<col width="25%"/> |
||||
<col width="45%"/> |
||||
<col width="8%"/> |
||||
<col width="10%"/> |
||||
<col width=""/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('描述'); ?></th>
|
||||
<th><?php _e('版本'); ?></th>
|
||||
<th><?php _e('作者'); ?></th>
|
||||
<th><?php _e('操作'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php while ($activatedPlugins->next()): ?> |
||||
<tr id="plugin-<?php $activatedPlugins->name(); ?>">
|
||||
<td><?php $activatedPlugins->title(); ?> |
||||
<?php if (!$activatedPlugins->dependence): ?> |
||||
<img src="<?php $options->adminUrl('images/notice.gif'); ?>" title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>" alt="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>" class="tiny" />
|
||||
<?php endif; ?> |
||||
</td> |
||||
<td><?php $activatedPlugins->description(); ?></td>
|
||||
<td><?php $activatedPlugins->version(); ?></td>
|
||||
<td><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage |
||||
. '">' . $activatedPlugins->author . '</a>'; ?></td> |
||||
<td> |
||||
<?php if ($activatedPlugins->activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?> |
||||
<?php if ($activatedPlugins->config): ?> |
||||
<a href="<?php $options->adminUrl('options-plugin.php?config=' . $activatedPlugins->name); ?>"><?php _e('设置'); ?></a>
|
||||
• |
||||
<?php endif; ?> |
||||
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>" href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
|
||||
<?php else: ?> |
||||
<span class="important"><?php _e('即插即用'); ?></span>
|
||||
<?php endif; ?> |
||||
</td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
|
||||
<?php if (!empty($activatedPlugins->activatedPlugins)): ?> |
||||
<?php foreach ($activatedPlugins->activatedPlugins as $key => $val): ?> |
||||
<tr> |
||||
<td><?php echo $key; ?></td>
|
||||
<td colspan="3"><span class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用它'); ?></span></td>
|
||||
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>" href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a></td>
|
||||
</tr> |
||||
<?php endforeach; ?> |
||||
<?php endif; ?> |
||||
|
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
<?php Typecho_Widget::widget('Widget_Plugins_List@unactivated', 'activated=0')->to($deactivatedPlugins); ?> |
||||
<?php if ($deactivatedPlugins->have() || !$activatedPlugins->have()): ?> |
||||
<h4 class="typecho-list-table-title"><?php _e('禁用的插件'); ?></h4>
|
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table deactivate"> |
||||
<colgroup> |
||||
<col width="25%"/> |
||||
<col width="45%"/> |
||||
<col width="8%"/> |
||||
<col width="10%"/> |
||||
<col width=""/> |
||||
</colgroup> |
||||
<thead> |
||||
<tr> |
||||
<th><?php _e('名称'); ?></th>
|
||||
<th><?php _e('描述'); ?></th>
|
||||
<th><?php _e('版本'); ?></th>
|
||||
<th><?php _e('作者'); ?></th>
|
||||
<th class="typecho-radius-topright"><?php _e('操作'); ?></th>
|
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<?php if ($deactivatedPlugins->have()): ?> |
||||
<?php while ($deactivatedPlugins->next()): ?> |
||||
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
|
||||
<td><?php $deactivatedPlugins->title(); ?></td>
|
||||
<td><?php $deactivatedPlugins->description(); ?></td>
|
||||
<td><?php $deactivatedPlugins->version(); ?></td>
|
||||
<td><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage |
||||
. '">' . $deactivatedPlugins->author . '</a>'; ?></td> |
||||
<td> |
||||
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
|
||||
</td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
<?php else: ?> |
||||
<tr> |
||||
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6></td>
|
||||
</tr> |
||||
<?php endif; ?> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
<?php endif; ?> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,60 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$stat = Typecho_Widget::widget('Widget_Stat'); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main"> |
||||
<div class="col-mb-12 col-tb-3"> |
||||
<p><a href="http://gravatar.com/emails/" title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="' . Typecho_Common::gravatarUrl($user->mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?></a></p>
|
||||
<h2><?php $user->screenName(); ?></h2>
|
||||
<p><?php $user->name(); ?></p>
|
||||
<p><?php _e('目前有 <em>%s</em> 篇日志, 并有 <em>%s</em> 条关于你的评论在 <em>%s</em> 个分类中.',
|
||||
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?></p> |
||||
<p><?php |
||||
if ($user->logged > 0) { |
||||
$logged = new Typecho_Date($user->logged); |
||||
_e('最后登录: %s', $logged->word()); |
||||
} |
||||
?></p> |
||||
</div> |
||||
|
||||
<div class="col-mb-12 col-tb-6 col-tb-offset-1 typecho-content-panel" role="form"> |
||||
<section> |
||||
<h3><?php _e('个人资料'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->profileForm()->render(); ?> |
||||
</section> |
||||
|
||||
<?php if($user->pass('contributor', true)): ?> |
||||
<br> |
||||
<section id="writing-option"> |
||||
<h3><?php _e('撰写设置'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->optionsForm()->render(); ?> |
||||
</section> |
||||
<?php endif; ?> |
||||
|
||||
<br> |
||||
|
||||
<section id="change-password"> |
||||
<h3><?php _e('密码修改'); ?></h3>
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->passwordForm()->render(); ?> |
||||
</section> |
||||
|
||||
<?php Typecho_Widget::widget('Widget_Users_Profile')->personalFormList(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
Typecho_Plugin::factory('admin/profile.php')->bottom(); |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,50 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
|
||||
if ($user->hasLogin() || !$options->allowRegister) { |
||||
$response->redirect($options->siteUrl); |
||||
} |
||||
$rememberName = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_name')); |
||||
$rememberMail = htmlspecialchars(Typecho_Cookie::get('__typecho_remember_mail')); |
||||
Typecho_Cookie::delete('__typecho_remember_name'); |
||||
Typecho_Cookie::delete('__typecho_remember_mail'); |
||||
|
||||
$bodyClass = 'body-100'; |
||||
|
||||
include 'header.php'; |
||||
?> |
||||
<div class="typecho-login-wrap"> |
||||
<div class="typecho-login"> |
||||
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1> |
||||
<form action="<?php $options->registerAction(); ?>" method="post" name="register" role="form">
|
||||
<p> |
||||
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>
|
||||
<input type="text" id="name" name="name" placeholder="<?php _e('用户名'); ?>" value="<?php echo $rememberName; ?>" class="text-l w-100" autofocus />
|
||||
</p> |
||||
<p> |
||||
<label for="mail" class="sr-only"><?php _e('Email'); ?></label>
|
||||
<input type="email" id="mail" name="mail" placeholder="<?php _e('Email'); ?>" value="<?php echo $rememberMail; ?>" class="text-l w-100" />
|
||||
</p> |
||||
<p class="submit"> |
||||
<button type="submit" class="btn btn-l w-100 primary"><?php _e('注册'); ?></button>
|
||||
</p> |
||||
</form> |
||||
|
||||
<p class="more-link"> |
||||
<a href="<?php $options->siteUrl(); ?>"><?php _e('返回首页'); ?></a>
|
||||
• |
||||
<a href="<?php $options->adminUrl('login.php'); ?>"><?php _e('用户登录'); ?></a>
|
||||
</p> |
||||
</div> |
||||
</div> |
||||
<?php
|
||||
include 'common-js.php'; |
||||
?> |
||||
<script> |
||||
$(document).ready(function () { |
||||
$('#name').focus(); |
||||
}); |
||||
</script> |
||||
<?php |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,18 @@ |
||||
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?> |
||||
<script> |
||||
(function () { |
||||
$(document).ready(function () { |
||||
$('.typecho-list-table').tableSelectable({ |
||||
checkEl : 'input[type=checkbox]', |
||||
rowEl : 'tr', |
||||
selectAllEl : '.typecho-table-select-all', |
||||
actionEl : '.dropdown-menu a,button.btn-operate' |
||||
}); |
||||
|
||||
$('.btn-drop').dropdownMenu({ |
||||
btnEl : '.dropdown-toggle', |
||||
menuEl : '.dropdown-menu' |
||||
}); |
||||
}); |
||||
})(); |
||||
</script> |
@ -0,0 +1,62 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
Typecho_Widget::widget('Widget_Themes_Files')->to($files); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12"> |
||||
<ul class="typecho-option-tabs fix-tabs clearfix"> |
||||
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
|
||||
<li class="current"><a href="<?php $options->adminUrl('theme-editor.php'); ?>">
|
||||
<?php if ($options->theme == $files->theme): ?> |
||||
<?php _e('编辑当前外观'); ?> |
||||
<?php else: ?> |
||||
<?php _e('编辑%s外观', ' <cite>' . $files->theme . '</cite> '); ?> |
||||
<?php endif; ?> |
||||
</a></li> |
||||
<?php if (Widget_Themes_Config::isExists()): ?> |
||||
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div class="typecho-edit-theme"> |
||||
<div class="col-mb-12 col-tb-8 col-9 content"> |
||||
<form method="post" name="theme" id="theme" action="<?php $security->index('/action/themes-edit'); ?>">
|
||||
<label for="content" class="sr-only"><?php _e('编辑源码'); ?></label>
|
||||
<textarea name="content" id="content" class="w-100 mono" <?php if(!$files->currentIsWriteable()): ?>readonly<?php endif; ?>><?php echo $files->currentContent(); ?></textarea>
|
||||
<p class="submit"> |
||||
<?php if($files->currentIsWriteable()): ?> |
||||
<input type="hidden" name="theme" value="<?php echo $files->currentTheme(); ?>" />
|
||||
<input type="hidden" name="edit" value="<?php echo $files->currentFile(); ?>" />
|
||||
<button type="submit" class="btn primary"><?php _e('保存文件'); ?></button>
|
||||
<?php else: ?> |
||||
<em><?php _e('此文件无法写入'); ?></em>
|
||||
<?php endif; ?> |
||||
</p> |
||||
</form> |
||||
</div> |
||||
<ul class="col-mb-12 col-tb-4 col-3"> |
||||
<li><strong>模板文件</strong></li> |
||||
<?php while($files->next()): ?> |
||||
<li<?php if($files->current): ?> class="current"<?php endif; ?>>
|
||||
<a href="<?php $options->adminUrl('theme-editor.php?theme=' . $files->currentTheme() . '&file=' . $files->file); ?>"><?php $files->file(); ?></a></li>
|
||||
<?php endwhile; ?> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
Typecho_Plugin::factory('admin/theme-editor.php')->bottom($files); |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,69 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12"> |
||||
<ul class="typecho-option-tabs fix-tabs clearfix"> |
||||
<li class="current"><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
|
||||
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?> |
||||
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
|
||||
<?php endif; ?> |
||||
<?php if (Widget_Themes_Config::isExists()): ?> |
||||
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
|
||||
<?php endif; ?> |
||||
</ul> |
||||
|
||||
<div class="typecho-table-wrap"> |
||||
<table class="typecho-list-table typecho-theme-list"> |
||||
<colgroup> |
||||
<col width="35%" /> |
||||
<col /> |
||||
</colgroup> |
||||
|
||||
<thead> |
||||
<th><?php _e('截图'); ?></th>
|
||||
<th><?php _e('详情'); ?></th>
|
||||
</thead> |
||||
|
||||
<tbody> |
||||
<?php Typecho_Widget::widget('Widget_Themes_List')->to($themes); ?> |
||||
<?php while($themes->next()): ?> |
||||
<tr id="theme-<?php $themes->name(); ?>" class="<?php if($themes->activated): ?>current<?php endif; ?>">
|
||||
<td valign="top"><img src="<?php $themes->screen(); ?>" alt="<?php $themes->name(); ?>" /></td>
|
||||
<td valign="top"> |
||||
<h3><?php '' != $themes->title ? $themes->title() : $themes->name(); ?></h3>
|
||||
<cite> |
||||
<?php if($themes->author): ?><?php _e('作者'); ?>: <?php if($themes->homepage): ?><a href="<?php $themes->homepage() ?>"><?php endif; ?><?php $themes->author(); ?><?php if($themes->homepage): ?></a><?php endif; ?> <?php endif; ?> |
||||
<?php if($themes->version): ?><?php _e('版本'); ?>: <?php $themes->version() ?><?php endif; ?> |
||||
</cite> |
||||
<p><?php echo nl2br($themes->description); ?></p>
|
||||
<?php if($options->theme != $themes->name): ?> |
||||
<p> |
||||
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?> |
||||
<a class="edit" href="<?php $options->adminUrl('theme-editor.php?theme=' . $themes->name); ?>"><?php _e('编辑'); ?></a>
|
||||
<?php endif; ?> |
||||
<a class="activate" href="<?php $security->index('/action/themes-edit?change=' . $themes->name); ?>"><?php _e('启用'); ?></a>
|
||||
</p> |
||||
<?php endif; ?> |
||||
</td> |
||||
</tr> |
||||
<?php endwhile; ?> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'footer.php'; |
||||
?> |
@ -0,0 +1,55 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
|
||||
$errors = $security->systemCheck(); |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="main"> |
||||
<div class="col-mb-12"> |
||||
<div id="typecho-welcome"> |
||||
<?php if (!empty($errors)): ?> |
||||
<form action="<?php echo Typecho_Common::url('upgrade.php', $options->adminUrl); ?>" method="get">
|
||||
<h3><?php _e('发现安全问题'); ?></h3>
|
||||
<ul> |
||||
<?php foreach ($errors as $error): ?> |
||||
<li class="warning"><?php echo $error; ?></li>
|
||||
<?php endforeach; ?> |
||||
</ul> |
||||
<p><button class="btn primary" type="submit"><?php _e('解决完毕 »'); ?></button></p>
|
||||
</form> |
||||
<?php else: ?> |
||||
<form action="<?php echo $security->getTokenUrl( |
||||
Typecho_Router::url('do', array('action' => 'upgrade', 'widget' => 'Upgrade'), |
||||
Typecho_Common::url('index.php', $options->rootUrl))); ?>" method="post"> |
||||
<h3><?php _e('检测到新版本!'); ?></h3>
|
||||
<ul> |
||||
<li><?php _e('您已经更新了系统程序, 我们还需要执行一些后续步骤来完成升级'); ?></li>
|
||||
<li><?php _e('此程序将把您的系统从 <strong>%s</strong> 升级到 <strong>%s</strong>', $options->version, Typecho_Common::VERSION); ?></li>
|
||||
<li><strong class="warning"><?php _e('在升级之前强烈建议先<a href="%s">备份您的数据</a>', Typecho_Common::url('backup.php', $options->adminUrl)); ?></strong></li>
|
||||
</ul> |
||||
<p><button class="btn primary" type="submit"><?php _e('完成升级 »'); ?></button></p>
|
||||
</form> |
||||
<?php endif; ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
?> |
||||
<script> |
||||
(function () { |
||||
if (window.sessionStorage) { |
||||
sessionStorage.removeItem('update'); |
||||
} |
||||
})(); |
||||
</script> |
||||
<?php include 'footer.php'; ?> |
@ -0,0 +1,23 @@ |
||||
<?php |
||||
include 'common.php'; |
||||
include 'header.php'; |
||||
include 'menu.php'; |
||||
?> |
||||
|
||||
<div class="main"> |
||||
<div class="body container"> |
||||
<?php include 'page-title.php'; ?> |
||||
<div class="row typecho-page-main" role="form"> |
||||
<div class="col-mb-12 col-tb-6 col-tb-offset-3"> |
||||
<?php Typecho_Widget::widget('Widget_Users_Edit')->form()->render(); ?> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<?php |
||||
include 'copyright.php'; |
||||
include 'common-js.php'; |
||||
include 'form-js.php'; |
||||
include 'footer.php'; |
||||
?> |