@ -0,0 +1,26 @@ |
|||||
|
<!doctype html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
||||
|
<title>404</title> |
||||
|
<style> |
||||
|
body{ |
||||
|
background-color:#444; |
||||
|
font-size:14px; |
||||
|
} |
||||
|
h3{ |
||||
|
font-size:60px; |
||||
|
color:#eee; |
||||
|
text-align:center; |
||||
|
padding-top:30px; |
||||
|
font-weight:normal; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
|
||||
|
<body> |
||||
|
<h3>404,您请求的文件不存在!</h3> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,825 @@ |
|||||
|
<?php |
||||
|
define('IN_API', true); |
||||
|
require_once './framework/bootstrap.inc.php'; |
||||
|
load()->model('reply'); |
||||
|
load()->model('attachment'); |
||||
|
load()->app('common'); |
||||
|
load()->classs('wesession'); |
||||
|
$hash = $_GPC['hash']; |
||||
|
if (!empty($hash)) { |
||||
|
$id = pdo_fetchcolumn("SELECT acid FROM " . tablename('account') . " WHERE hash = :hash", array(':hash' => $hash)); |
||||
|
} |
||||
|
if (!empty($_GPC['appid'])) { |
||||
|
$appid = ltrim($_GPC['appid'], '/'); |
||||
|
if ($appid == 'wx570bc396a51b8ff8') { |
||||
|
$_W['account'] = array( |
||||
|
'type' => '3', |
||||
|
'key' => 'wx570bc396a51b8ff8', |
||||
|
'level' => 4, |
||||
|
'token' => 'platformtestaccount' |
||||
|
); |
||||
|
} else { |
||||
|
$id = pdo_fetchcolumn("SELECT acid FROM " . tablename('account_wechats') . " WHERE `key` = :appid", array(':appid' => $appid)); |
||||
|
if (empty($id)) { |
||||
|
$id = table('account_wxapp')->where('key', $appid)->getcolumn('acid'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (empty($id)) { |
||||
|
$id = intval($_GPC['id']); |
||||
|
} |
||||
|
if (!empty($id)) { |
||||
|
$uniacid = pdo_getcolumn('account', array('acid' => $id), 'uniacid'); |
||||
|
$_W['account'] = $_W['uniaccount'] = uni_fetch($uniacid); |
||||
|
} |
||||
|
if (empty($_W['account'])) { |
||||
|
exit('initial error hash or id'); |
||||
|
} |
||||
|
if (empty($_W['account']['token'])) { |
||||
|
exit('initial missing token'); |
||||
|
} |
||||
|
$_W['debug'] = intval($_GPC['debug']); |
||||
|
$_W['acid'] = $_W['account']['acid']; |
||||
|
$_W['uniacid'] = $_W['account']['uniacid']; |
||||
|
$_W['account']['groupid'] = $_W['uniaccount']['groupid']; |
||||
|
$_W['account']['qrcode'] = $_W['attachurl'] . 'qrcode_' . $_W['acid'] . '.jpg?time=' . $_W['timestamp']; |
||||
|
$_W['account']['avatar'] = $_W['attachurl'] . 'headimg_' . $_W['acid'] . '.jpg?time=' . $_W['timestamp']; |
||||
|
$_W['attachurl'] = attachment_set_attach_url(); |
||||
|
|
||||
|
//register_shutdown_function('visit_update_today', 'app', 'we7_api'); |
||||
|
|
||||
|
$engine = new WeEngine(); |
||||
|
if (!empty($_W['setting']['copyright']['status'])) { |
||||
|
$engine->died('抱歉,站点已关闭,关闭原因:' . $_W['setting']['copyright']['reason']); |
||||
|
} |
||||
|
if (!empty($_W['uniaccount']['endtime']) && TIMESTAMP > $_W['uniaccount']['endtime'] && !in_array($_W['uniaccount']['endtime'], array(USER_ENDTIME_GROUP_EMPTY_TYPE, USER_ENDTIME_GROUP_UNLIMIT_TYPE))) { |
||||
|
$engine->died('抱歉,您的公众号已过期,请及时联系管理员'); |
||||
|
} |
||||
|
|
||||
|
if ($_W['isajax'] && $_W['ispost'] && $_GPC['flag'] == 1) { |
||||
|
$engine->encrypt(); |
||||
|
} |
||||
|
if ($_W['isajax'] && $_W['ispost'] && $_GPC['flag'] == 2) { |
||||
|
$engine->decrypt(); |
||||
|
} |
||||
|
$_W['isajax'] = false; |
||||
|
$engine->start(); |
||||
|
|
||||
|
|
||||
|
class WeEngine |
||||
|
{ |
||||
|
|
||||
|
private $account = null; |
||||
|
|
||||
|
private $modules = array(); |
||||
|
|
||||
|
public $keyword = array(); |
||||
|
|
||||
|
public $message = array(); |
||||
|
|
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
global $_W; |
||||
|
$this->account = WeAccount::create($_W['account']); |
||||
|
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') { |
||||
|
$this->modules = ['weliam_smartcity']; |
||||
|
$this->modules[] = 'cover'; |
||||
|
$this->modules[] = 'default'; |
||||
|
$this->modules[] = 'reply'; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function encrypt() |
||||
|
{ |
||||
|
global $_W; |
||||
|
if (empty($this->account)) { |
||||
|
exit('Miss Account.'); |
||||
|
} |
||||
|
$timestamp = TIMESTAMP; |
||||
|
$nonce = random(5); |
||||
|
$token = $_W['account']['token']; |
||||
|
$signkey = array($token, TIMESTAMP, $nonce); |
||||
|
sort($signkey, SORT_STRING); |
||||
|
$signString = implode($signkey); |
||||
|
$signString = sha1($signString); |
||||
|
|
||||
|
$_GET['timestamp'] = $timestamp; |
||||
|
$_GET['nonce'] = $nonce; |
||||
|
$_GET['signature'] = $signString; |
||||
|
$postStr = file_get_contents('php://input'); |
||||
|
if (!empty($_W['account']['encodingaeskey']) && strlen($_W['account']['encodingaeskey']) == 43 && !empty($_W['account']['key']) && $_W['setting']['development'] != 1) { |
||||
|
$data = $this->account->encryptMsg($postStr); |
||||
|
$array = array('encrypt_type' => 'aes', 'timestamp' => $timestamp, 'nonce' => $nonce, 'signature' => $signString, 'msg_signature' => $data[0], 'msg' => $data[1]); |
||||
|
} else { |
||||
|
$data = array('', ''); |
||||
|
$array = array('encrypt_type' => '', 'timestamp' => $timestamp, 'nonce' => $nonce, 'signature' => $signString, 'msg_signature' => $data[0], 'msg' => $data[1]); |
||||
|
} |
||||
|
exit(json_encode($array)); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function decrypt() |
||||
|
{ |
||||
|
global $_W; |
||||
|
if (empty($this->account)) { |
||||
|
exit('Miss Account.'); |
||||
|
} |
||||
|
$postStr = file_get_contents('php://input'); |
||||
|
if (!empty($_W['account']['encodingaeskey']) && strlen($_W['account']['encodingaeskey']) == 43 && !empty($_W['account']['key']) && $_W['setting']['development'] != 1) { |
||||
|
$resp = $this->account->local_decryptMsg($postStr); |
||||
|
} else { |
||||
|
$resp = $postStr; |
||||
|
} |
||||
|
exit($resp); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function start() |
||||
|
{ |
||||
|
global $_W; |
||||
|
if (empty($this->account)) { |
||||
|
exit('Miss Account.'); |
||||
|
} |
||||
|
if (!$this->account->checkSign()) { |
||||
|
exit('Check Sign Fail.'); |
||||
|
} |
||||
|
if (strtolower($_SERVER['REQUEST_METHOD']) == 'get') { |
||||
|
$row = array(); |
||||
|
$row['isconnect'] = 1; |
||||
|
pdo_update('account', $row, array('uniacid' => $_W['uniacid'])); |
||||
|
cache_delete(cache_system_key('uniaccount', array('uniacid' => $_W['uniacid']))); |
||||
|
exit(htmlspecialchars($_GET['echostr'])); |
||||
|
} |
||||
|
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post') { |
||||
|
$postStr = file_get_contents('php://input'); |
||||
|
if (!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') { |
||||
|
$postStr = $this->account->decryptMsg($postStr); |
||||
|
} |
||||
|
WeUtility::logging('trace', $postStr); |
||||
|
$message = $this->account->parse($postStr); |
||||
|
|
||||
|
$this->message = $message; |
||||
|
if (empty($message)) { |
||||
|
WeUtility::logging('waring', 'Request Failed'); |
||||
|
exit('Request Failed'); |
||||
|
} |
||||
|
if (in_array($message['event'], array('weapp_audit_success', 'weapp_audit_fail', 'weapp_audit_delay'))) { |
||||
|
$this->weapp_audit(); |
||||
|
exit('success'); |
||||
|
} |
||||
|
$_W['openid'] = $message['from']; |
||||
|
$_W['fans'] = array('from_user' => $_W['openid']); |
||||
|
$this->booking($message); |
||||
|
if ($message['event'] == 'unsubscribe') { |
||||
|
$this->receive(array(), array(), array()); |
||||
|
exit(); |
||||
|
} |
||||
|
$sessionid = md5($message['from'] . $message['to'] . $_W['uniacid']); |
||||
|
session_id($sessionid); |
||||
|
WeSession::start($_W['uniacid'], $_W['openid']); |
||||
|
|
||||
|
$_SESSION['openid'] = $_W['openid']; |
||||
|
$pars = $this->analyze($message); |
||||
|
$pars[] = array( |
||||
|
'message' => $message, |
||||
|
'module' => 'default', |
||||
|
'rule' => '-1', |
||||
|
); |
||||
|
$hitParam['rule'] = -2; |
||||
|
$hitParam['module'] = ''; |
||||
|
$hitParam['message'] = $message; |
||||
|
|
||||
|
$hitKeyword = array(); |
||||
|
$response = array(); |
||||
|
foreach ($pars as $par) { |
||||
|
if (empty($par['module'])) { |
||||
|
continue; |
||||
|
} |
||||
|
$par['message'] = $message; |
||||
|
$response = $this->process($par); |
||||
|
if ($this->isValidResponse($response)) { |
||||
|
$hitParam = $par; |
||||
|
if (!empty($par['keyword'])) { |
||||
|
$hitKeyword = $par['keyword']; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
$response_debug = $response; |
||||
|
$pars_debug = $pars; |
||||
|
if ($hitParam['module'] == 'default' && is_array($response) && is_array($response['params'])) { |
||||
|
foreach ($response['params'] as $par) { |
||||
|
if (empty($par['module'])) { |
||||
|
continue; |
||||
|
} |
||||
|
$response = $this->process($par); |
||||
|
if ($this->isValidResponse($response)) { |
||||
|
$hitParam = $par; |
||||
|
if (!empty($par['keyword'])) { |
||||
|
$hitKeyword = $par['keyword']; |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
WeUtility::logging('params', var_export($hitParam, true)); |
||||
|
WeUtility::logging('response', $response); |
||||
|
$resp = $this->account->response($response); |
||||
|
if (!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') { |
||||
|
$resp = $this->account->encryptMsg($resp); |
||||
|
$resp = $this->account->xmlDetract($resp); |
||||
|
} |
||||
|
if ($resp !== 'success') { |
||||
|
$mapping = array( |
||||
|
'[from]' => $this->message['from'], |
||||
|
'[to]' => $this->message['to'], |
||||
|
'[rule]' => $this->params['rule'] |
||||
|
); |
||||
|
$resp = str_replace(array_keys($mapping), array_values($mapping), $resp); |
||||
|
} |
||||
|
|
||||
|
$reply_times_info = (array)$_SESSION['__reply_times']; |
||||
|
if ($reply_times_info['content'] == $message['content']) { |
||||
|
$new_times = intval($reply_times_info['times']) + 1; |
||||
|
} else { |
||||
|
$new_times = 1; |
||||
|
} |
||||
|
$_SESSION['__reply_times'] = array('content' => $message['content'], 'date' => date('Y-m-d'), 'times' => $new_times); |
||||
|
ob_start(); |
||||
|
echo $resp; |
||||
|
ob_start(); |
||||
|
$this->receive($hitParam, $hitKeyword, $response); |
||||
|
ob_end_clean(); |
||||
|
exit(); |
||||
|
} |
||||
|
WeUtility::logging('waring', 'Request Failed'); |
||||
|
exit('Request Failed'); |
||||
|
} |
||||
|
|
||||
|
private function isValidResponse($response) |
||||
|
{ |
||||
|
if ($response === 'success') { |
||||
|
return true; |
||||
|
} |
||||
|
if (is_array($response)) { |
||||
|
if ($response['type'] == 'text' && !empty($response['content'])) { |
||||
|
return true; |
||||
|
} |
||||
|
if ($response['type'] == 'news' && !empty($response['items'])) { |
||||
|
return true; |
||||
|
} |
||||
|
if (!in_array($response['type'], array('text', 'news', 'image'))) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private function booking($message) |
||||
|
{ |
||||
|
global $_W; |
||||
|
if ($message['event'] == 'unsubscribe' || $message['event'] == 'subscribe') { |
||||
|
$todaystat = pdo_get('stat_fans', array('date' => date('Ymd'), 'uniacid' => $_W['uniacid'])); |
||||
|
if ($message['event'] == 'unsubscribe') { |
||||
|
if (empty($todaystat)) { |
||||
|
$updatestat = array( |
||||
|
'new' => 0, |
||||
|
'uniacid' => $_W['uniacid'], |
||||
|
'cancel' => 1, |
||||
|
'cumulate' => 0, |
||||
|
'date' => date('Ymd'), |
||||
|
); |
||||
|
pdo_insert('stat_fans', $updatestat); |
||||
|
} else { |
||||
|
$updatestat = array( |
||||
|
'cancel' => $todaystat['cancel'] + 1, |
||||
|
); |
||||
|
pdo_update('stat_fans', $updatestat, array('id' => $todaystat['id'])); |
||||
|
} |
||||
|
} elseif ($message['event'] == 'subscribe') { |
||||
|
if (empty($todaystat)) { |
||||
|
$updatestat = array( |
||||
|
'new' => 1, |
||||
|
'uniacid' => $_W['uniacid'], |
||||
|
'cancel' => 0, |
||||
|
'cumulate' => 0, |
||||
|
'date' => date('Ymd'), |
||||
|
); |
||||
|
pdo_insert('stat_fans', $updatestat); |
||||
|
} else { |
||||
|
$updatestat = array( |
||||
|
'new' => $todaystat['new'] + 1, |
||||
|
); |
||||
|
pdo_update('stat_fans', $updatestat, array('id' => $todaystat['id'])); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
load()->model('mc'); |
||||
|
$setting = uni_setting($_W['uniacid'], array('passport')); |
||||
|
$fans = mc_fansinfo($message['from']); |
||||
|
$default_groupid = cache_load(cache_system_key('defaultgroupid', array('uniacid' => $_W['uniacid']))); |
||||
|
if (empty($default_groupid)) { |
||||
|
$default_groupid = pdo_fetchcolumn('SELECT groupid FROM ' . tablename('mc_groups') . ' WHERE uniacid = :uniacid AND isdefault = 1', array(':uniacid' => $_W['uniacid'])); |
||||
|
cache_write(cache_system_key('defaultgroupid', array('uniacid' => $_W['uniacid'])), $default_groupid); |
||||
|
} |
||||
|
if (!empty($fans)) { |
||||
|
if ($message['event'] == 'unsubscribe') { |
||||
|
cache_build_memberinfo($fans['uid']); |
||||
|
pdo_update('mc_mapping_fans', array('follow' => 0, 'unfollowtime' => TIMESTAMP), array('fanid' => $fans['fanid'])); |
||||
|
pdo_delete('mc_fans_tag_mapping', array('fanid' => $fans['fanid'])); |
||||
|
} elseif ($message['event'] != 'ShakearoundUserShake' && $message['type'] != 'trace') { |
||||
|
$rec = array(); |
||||
|
if (empty($fans['follow'])) { |
||||
|
$rec['follow'] = 1; |
||||
|
$rec['followtime'] = $message['time']; |
||||
|
} |
||||
|
$member = array(); |
||||
|
if (!empty($fans['uid'])) { |
||||
|
$member = mc_fetch($fans['uid']); |
||||
|
} |
||||
|
if (empty($member)) { |
||||
|
if (!isset($setting['passport']) || empty($setting['passport']['focusreg'])) { |
||||
|
$data = array( |
||||
|
'uniacid' => $_W['uniacid'], |
||||
|
'email' => md5($message['from']) . '@we7.cc', |
||||
|
'salt' => random(8), |
||||
|
'groupid' => $default_groupid, |
||||
|
'createtime' => TIMESTAMP, |
||||
|
); |
||||
|
$data['password'] = md5($message['from'] . $data['salt'] . $_W['config']['setting']['authkey']); |
||||
|
pdo_insert('mc_members', $data); |
||||
|
$rec['uid'] = pdo_insertid(); |
||||
|
} |
||||
|
} |
||||
|
if (!empty($rec)) { |
||||
|
pdo_update('mc_mapping_fans', $rec, array('openid' => $message['from'])); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
if ($message['event'] == 'subscribe' || $message['type'] == 'text' || $message['type'] == 'image') { |
||||
|
load()->model('mc'); |
||||
|
$force_init_member = false; |
||||
|
if (!isset($setting['passport']) || empty($setting['passport']['focusreg'])) { |
||||
|
$force_init_member = true; |
||||
|
} |
||||
|
mc_init_fans_info($message['from'], $force_init_member); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private function receive($par, $keyword, $response) |
||||
|
{ |
||||
|
global $_W; |
||||
|
fastcgi_finish_request(); |
||||
|
|
||||
|
$subscribe = cache_load(cache_system_key('module_receive_enable')); |
||||
|
if (empty($subscribe)) { |
||||
|
$subscribe = cache_build_module_subscribe_type(); |
||||
|
} |
||||
|
$modules = uni_modules(); |
||||
|
$obj = WeUtility::createModuleReceiver('core'); |
||||
|
$obj->message = $this->message; |
||||
|
$obj->params = $par; |
||||
|
$obj->response = $response; |
||||
|
$obj->keyword = $keyword; |
||||
|
$obj->module = 'core'; |
||||
|
$obj->uniacid = $_W['uniacid']; |
||||
|
$obj->acid = $_W['acid']; |
||||
|
if (method_exists($obj, 'receive')) { |
||||
|
@$obj->receive(); |
||||
|
} |
||||
|
load()->func('communication'); |
||||
|
if ((empty($subscribe[$this->message['type']]) || $this->message['type'] == 'event') && !empty($this->message['event'])) { |
||||
|
$subscribe[$this->message['type']] = $subscribe[strtolower($this->message['event'])]; |
||||
|
} |
||||
|
if (!empty($subscribe[$this->message['type']])) { |
||||
|
foreach ($subscribe[$this->message['type']] as $modulename) { |
||||
|
if (!in_array($modulename, array_keys($modules))) { |
||||
|
continue; |
||||
|
} |
||||
|
$params = array( |
||||
|
'i' => $GLOBALS['uniacid'], |
||||
|
'modulename' => $modulename, |
||||
|
'request' => json_encode($par), |
||||
|
'response' => json_encode($response), |
||||
|
'message' => json_encode($this->message), |
||||
|
); |
||||
|
$response = ihttp_request(wurl('utility/subscribe/receive'), $params, array(), 10); |
||||
|
if (is_error($response) || $response['code'] != 200) { |
||||
|
$response = ihttp_request($_W['siteroot'] . 'web/' . wurl('utility/subscribe/receive'), $params, array(), 10); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private function analyze(&$message) |
||||
|
{ |
||||
|
global $_W; |
||||
|
$params = array(); |
||||
|
if (in_array($message['type'], array('event', 'qr'))) { |
||||
|
$params = call_user_func_array(array($this, 'analyze' . $message['type']), array(&$message)); |
||||
|
if (!empty($params)) { |
||||
|
return (array)$params; |
||||
|
} |
||||
|
} |
||||
|
if (!empty($_SESSION['__contextmodule']) && in_array($_SESSION['__contextmodule'], $this->modules)) { |
||||
|
if ($_SESSION['__contextexpire'] > TIMESTAMP) { |
||||
|
$params[] = array( |
||||
|
'message' => $message, |
||||
|
'module' => $_SESSION['__contextmodule'], |
||||
|
'rule' => $_SESSION['__contextrule'], |
||||
|
'priority' => $_SESSION['__contextpriority'], |
||||
|
'context' => true |
||||
|
); |
||||
|
return $params; |
||||
|
} else { |
||||
|
unset($_SESSION); |
||||
|
session_destroy(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$reply_times_info = (array)$_SESSION['__reply_times']; |
||||
|
if (!empty($_W['account']['setting']) && !empty($reply_times_info) && intval($_W['account']['setting']['reply_setting']) > 0 && strtotime($reply_times_info['date']) >= strtotime(date('Y-m-d')) && $reply_times_info['times'] >= $_W['account']['setting']['reply_setting'] && $reply_times_info['content'] == $message['content']) { |
||||
|
exit('success'); |
||||
|
} |
||||
|
|
||||
|
if (method_exists($this, 'analyze' . $message['type'])) { |
||||
|
$temp = call_user_func_array(array($this, 'analyze' . $message['type']), array(&$message)); |
||||
|
if (!empty($temp) && is_array($temp)) { |
||||
|
$params += $temp; |
||||
|
} |
||||
|
} else { |
||||
|
$params += $this->handler($message['type']); |
||||
|
} |
||||
|
return $params; |
||||
|
} |
||||
|
|
||||
|
private function analyzeSubscribe(&$message) |
||||
|
{ |
||||
|
global $_W; |
||||
|
$params = array(); |
||||
|
$message['type'] = 'text'; |
||||
|
$message['redirection'] = true; |
||||
|
if (!empty($message['scene'])) { |
||||
|
$message['source'] = 'qr'; |
||||
|
$sceneid = trim($message['scene']); |
||||
|
if (is_numeric($sceneid)) { |
||||
|
$scene_condition = " `qrcid` = :sceneid"; |
||||
|
} else { |
||||
|
$scene_condition = " `scene_str` = :sceneid"; |
||||
|
} |
||||
|
$condition = array(':sceneid' => $sceneid, ':uniacid' => $_W['uniacid']); |
||||
|
$qr = pdo_fetch("SELECT `id`, `keyword` FROM " . tablename('qrcode') . " WHERE {$scene_condition} AND `uniacid` = :uniacid", $condition); |
||||
|
if (!empty($qr)) { |
||||
|
$message['content'] = $qr['keyword']; |
||||
|
if (!empty($qr['type']) && $qr['type'] == 'scene') { |
||||
|
$message['msgtype'] = 'text'; |
||||
|
} |
||||
|
$params += $this->analyzeText($message); |
||||
|
return $params; |
||||
|
} |
||||
|
} |
||||
|
$message['source'] = 'subscribe'; |
||||
|
$setting = uni_setting($_W['uniacid'], array('welcome')); |
||||
|
if (!empty($setting['welcome'])) { |
||||
|
$message['content'] = $setting['welcome']; |
||||
|
$params += $this->analyzeText($message); |
||||
|
} |
||||
|
|
||||
|
return $params; |
||||
|
} |
||||
|
|
||||
|
private function analyzeQR(&$message) |
||||
|
{ |
||||
|
global $_W; |
||||
|
$params = array(); |
||||
|
$default_message = $message; |
||||
|
$message['type'] = 'text'; |
||||
|
$message['redirection'] = true; |
||||
|
if (!empty($message['scene'])) { |
||||
|
$message['source'] = 'qr'; |
||||
|
$sceneid = trim($message['scene']); |
||||
|
if (is_numeric($sceneid)) { |
||||
|
$scene_condition = " `qrcid` = :sceneid"; |
||||
|
} else { |
||||
|
$scene_condition = " `scene_str` = :sceneid"; |
||||
|
} |
||||
|
$condition_params = array(':sceneid' => $sceneid, ':uniacid' => $_W['uniacid']); |
||||
|
$qr = pdo_fetch("SELECT `id`, `keyword` FROM " . tablename('qrcode') . " WHERE {$scene_condition} AND `uniacid` = :uniacid AND `type` = 'scene'", $condition_params); |
||||
|
|
||||
|
} |
||||
|
if (empty($qr) && !empty($message['ticket'])) { |
||||
|
$message['source'] = 'qr'; |
||||
|
$ticket = trim($message['ticket']); |
||||
|
if (!empty($ticket)) { |
||||
|
$qr = pdo_fetchall("SELECT `id`, `keyword` FROM " . tablename('qrcode') . " WHERE `uniacid` = :uniacid AND ticket = :ticket", array(':uniacid' => $_W['uniacid'], ':ticket' => $ticket)); |
||||
|
if (!empty($qr)) { |
||||
|
if (count($qr) != 1) { |
||||
|
$qr = array(); |
||||
|
} else { |
||||
|
$qr = $qr[0]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (!empty($qr)) { |
||||
|
$message['content'] = $qr['keyword']; |
||||
|
if (!empty($qr['type']) && $qr['type'] == 'scene') { |
||||
|
$message['msgtype'] = 'text'; |
||||
|
} |
||||
|
$params += $this->analyzeText($message); |
||||
|
} |
||||
|
if (empty($qr)) { |
||||
|
$params = $this->handler($default_message['type']); |
||||
|
if (!empty($params)) { |
||||
|
$message = $default_message; |
||||
|
return $params; |
||||
|
} |
||||
|
} |
||||
|
if (empty($params)) { |
||||
|
$params = $this->handler($message['type']); |
||||
|
} |
||||
|
return $params; |
||||
|
} |
||||
|
|
||||
|
public function analyzeText(&$message, $order = 0) |
||||
|
{ |
||||
|
global $_W; |
||||
|
|
||||
|
$pars = array(); |
||||
|
|
||||
|
$order = intval($order); |
||||
|
if (!isset($message['content'])) { |
||||
|
return $pars; |
||||
|
} |
||||
|
$cachekey = cache_system_key('keyword', array('content' => md5($message['content']), 'uniacid' => $_W['uniacid'])); |
||||
|
$keyword_cache = cache_load($cachekey); |
||||
|
if (!empty($keyword_cache) && $keyword_cache['expire'] > TIMESTAMP) { |
||||
|
foreach ($keyword_cache['data'] as $key => &$value) { |
||||
|
$value['message'] = $message; |
||||
|
} |
||||
|
unset($value); |
||||
|
return $keyword_cache['data']; |
||||
|
} |
||||
|
$condition = <<<EOF |
||||
|
`uniacid` IN ( 0, {$_W['uniacid']} ) |
||||
|
AND |
||||
|
( |
||||
|
( `type` = 1 AND `content` = :c1 ) |
||||
|
or |
||||
|
( `type` = 2 AND instr(:c2, `content`) ) |
||||
|
or |
||||
|
( `type` = 3 AND :c3 REGEXP `content`) |
||||
|
or |
||||
|
( `type` = 4 ) |
||||
|
) |
||||
|
AND `status`=1 |
||||
|
EOF; |
||||
|
|
||||
|
$params = array(); |
||||
|
$params[':c1'] = $message['content']; |
||||
|
$params[':c2'] = $message['content']; |
||||
|
$params[':c3'] = $message['content']; |
||||
|
|
||||
|
if (intval($order) > 0) { |
||||
|
$condition .= " AND `displayorder` > :order"; |
||||
|
$params[':order'] = $order; |
||||
|
} |
||||
|
|
||||
|
$keywords = reply_keywords_search($condition, $params); |
||||
|
if (empty($keywords)) { |
||||
|
return $pars; |
||||
|
} |
||||
|
|
||||
|
$system_module_reply = true; |
||||
|
foreach ($keywords as $keyword) { |
||||
|
if (!in_array($keyword['module'], array('defalut', 'cover', 'reply'))) { |
||||
|
$system_module_reply = false; |
||||
|
} |
||||
|
$params = array( |
||||
|
'message' => $message, |
||||
|
'module' => $keyword['module'], |
||||
|
'rule' => $keyword['rid'], |
||||
|
'priority' => $keyword['displayorder'], |
||||
|
'keyword' => $keyword, |
||||
|
'reply_type' => $keyword['reply_type'] |
||||
|
); |
||||
|
$pars[] = $params; |
||||
|
} |
||||
|
if (!empty($system_module_reply)) { |
||||
|
$cache = array( |
||||
|
'data' => $pars, |
||||
|
'expire' => TIMESTAMP + 5 * 60, |
||||
|
); |
||||
|
cache_write($cachekey, $cache); |
||||
|
} |
||||
|
return $pars; |
||||
|
} |
||||
|
|
||||
|
private function analyzeEvent(&$message) |
||||
|
{ |
||||
|
$event = strtolower($message['event']); |
||||
|
if ($event == 'subscribe') { |
||||
|
return $this->analyzeSubscribe($message); |
||||
|
} |
||||
|
if ($event == 'click') { |
||||
|
$message['content'] = strval($message['eventkey']); |
||||
|
return $this->analyzeClick($message); |
||||
|
} |
||||
|
if (in_array($event, array('pic_photo_or_album', 'pic_weixin', 'pic_sysphoto'))) { |
||||
|
pdo_delete('menu_event', array('createtime <' => $GLOBALS['_W']['timestamp'] - 100, 'openid' => $message['from']), 'OR'); |
||||
|
if (!empty($message['sendpicsinfo']['count'])) { |
||||
|
foreach ($message['sendpicsinfo']['piclist'] as $item) { |
||||
|
pdo_insert('menu_event', array( |
||||
|
'uniacid' => $GLOBALS['_W']['uniacid'], |
||||
|
'keyword' => $message['eventkey'], |
||||
|
'type' => $message['event'], |
||||
|
'picmd5' => $item, |
||||
|
'openid' => $message['from'], |
||||
|
'createtime' => TIMESTAMP, |
||||
|
)); |
||||
|
} |
||||
|
} else { |
||||
|
pdo_insert('menu_event', array( |
||||
|
'uniacid' => $GLOBALS['_W']['uniacid'], |
||||
|
'keyword' => $message['eventkey'], |
||||
|
'type' => $message['event'], |
||||
|
'picmd5' => $item, |
||||
|
'openid' => $message['from'], |
||||
|
'createtime' => TIMESTAMP, |
||||
|
)); |
||||
|
} |
||||
|
$message['content'] = strval($message['eventkey']); |
||||
|
$message['source'] = $message['event']; |
||||
|
return $this->analyzeText($message); |
||||
|
} |
||||
|
if (!empty($message['eventkey'])) { |
||||
|
$message['content'] = strval($message['eventkey']); |
||||
|
$message['type'] = 'text'; |
||||
|
$message['redirection'] = true; |
||||
|
$message['source'] = $message['event']; |
||||
|
return $this->analyzeText($message); |
||||
|
} |
||||
|
return $this->handler($message['event']); |
||||
|
} |
||||
|
|
||||
|
private function analyzeClick(&$message) |
||||
|
{ |
||||
|
if (!empty($message['content']) || $message['content'] !== '') { |
||||
|
$message['type'] = 'text'; |
||||
|
$message['redirection'] = true; |
||||
|
$message['source'] = 'click'; |
||||
|
return $this->analyzeText($message); |
||||
|
} |
||||
|
|
||||
|
return array(); |
||||
|
} |
||||
|
|
||||
|
private function analyzeImage(&$message) |
||||
|
{ |
||||
|
load()->func('communication'); |
||||
|
if (!empty($message['picurl'])) { |
||||
|
$response = ihttp_get($message['picurl']); |
||||
|
if (!empty($response)) { |
||||
|
$md5 = md5($response['content']); |
||||
|
$event = pdo_get('menu_event', array('picmd5' => $md5), array('keyword', 'type')); |
||||
|
if (!empty($event['keyword'])) { |
||||
|
pdo_delete('menu_event', array('picmd5' => $md5)); |
||||
|
} else { |
||||
|
$event = pdo_get('menu_event', array('openid' => $message['from']), array('keyword', 'type')); |
||||
|
} |
||||
|
if (!empty($event)) { |
||||
|
$message['content'] = $event['keyword']; |
||||
|
$message['eventkey'] = $event['keyword']; |
||||
|
$message['type'] = 'text'; |
||||
|
$message['event'] = $event['type']; |
||||
|
$message['redirection'] = true; |
||||
|
$message['source'] = $event['type']; |
||||
|
return $this->analyzeText($message); |
||||
|
} |
||||
|
} |
||||
|
return $this->handler('image'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private function analyzeVoice(&$message) |
||||
|
{ |
||||
|
$params = $this->handler('voice'); |
||||
|
if (empty($params) && !empty($message['recognition'])) { |
||||
|
$message['type'] = 'text'; |
||||
|
$message['redirection'] = true; |
||||
|
$message['source'] = 'voice'; |
||||
|
$message['content'] = $message['recognition']; |
||||
|
return $this->analyzeText($message); |
||||
|
} else { |
||||
|
return $params; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private function handler($type) |
||||
|
{ |
||||
|
if (empty($type)) { |
||||
|
return array(); |
||||
|
} |
||||
|
global $_W; |
||||
|
$params = array(); |
||||
|
$setting = uni_setting($_W['uniacid'], array('default_message')); |
||||
|
$default_message = $setting['default_message']; |
||||
|
if (is_array($default_message) && !empty($default_message[$type]['type'])) { |
||||
|
if ($default_message[$type]['type'] == 'keyword') { |
||||
|
$message = $this->message; |
||||
|
$message['type'] = 'text'; |
||||
|
$message['redirection'] = true; |
||||
|
$message['source'] = $type; |
||||
|
$message['content'] = $default_message[$type]['keyword']; |
||||
|
return $this->analyzeText($message); |
||||
|
} else { |
||||
|
$params[] = array( |
||||
|
'message' => $this->message, |
||||
|
'module' => is_array($default_message[$type]) ? $default_message[$type]['module'] : $default_message[$type], |
||||
|
'rule' => '-1', |
||||
|
); |
||||
|
return $params; |
||||
|
} |
||||
|
} |
||||
|
return array(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
private function process($param) |
||||
|
{ |
||||
|
global $_W; |
||||
|
if (empty($param['module']) || !in_array($param['module'], $this->modules)) { |
||||
|
return false; |
||||
|
} |
||||
|
if ($param['module'] == 'reply') { |
||||
|
$processor = WeUtility::createModuleProcessor('core'); |
||||
|
} else { |
||||
|
$processor = WeUtility::createModuleProcessor($param['module']); |
||||
|
} |
||||
|
$processor->message = $param['message']; |
||||
|
$processor->rule = $param['rule']; |
||||
|
$processor->reply_type = $param['reply_type']; |
||||
|
$processor->priority = intval($param['priority']); |
||||
|
$processor->inContext = $param['context'] === true; |
||||
|
$response = $processor->respond(); |
||||
|
if (empty($response)) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return $response; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function died($content = '') |
||||
|
{ |
||||
|
global $_W, $engine; |
||||
|
if (empty($content)) { |
||||
|
exit(''); |
||||
|
} |
||||
|
$response['FromUserName'] = $engine->message['to']; |
||||
|
$response['ToUserName'] = $engine->message['from']; |
||||
|
$response['MsgType'] = 'text'; |
||||
|
$response['Content'] = htmlspecialchars_decode($content); |
||||
|
$response['CreateTime'] = TIMESTAMP; |
||||
|
$response['FuncFlag'] = 0; |
||||
|
$xml = array2xml($response); |
||||
|
if (!empty($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') { |
||||
|
$resp = $engine->account->encryptMsg($xml); |
||||
|
$resp = $engine->account->xmlDetract($resp); |
||||
|
} else { |
||||
|
$resp = $xml; |
||||
|
} |
||||
|
exit($resp); |
||||
|
} |
||||
|
|
||||
|
public function weapp_audit() |
||||
|
{ |
||||
|
$wxapp_register_version_table = table('wxapp_register_version'); |
||||
|
$wxapp_register_version = $wxapp_register_version_table->getWithAccountWxappOriginal($this->message['to']); |
||||
|
if (empty($wxapp_register_version)) { |
||||
|
return false; |
||||
|
} |
||||
|
switch ($this->message['event']) { |
||||
|
case 'weapp_audit_success': |
||||
|
$data = array('status' => WXAPP_REGISTER_VERSION_STATUS_CHECKSUCCESS, 'reason' => ''); |
||||
|
break; |
||||
|
case 'weapp_audit_fail': |
||||
|
$data = array('status' => WXAPP_REGISTER_VERSION_STATUS_CHECKFAIL, 'reason' => $this->message['reason']); |
||||
|
break; |
||||
|
default: |
||||
|
$data = array(); |
||||
|
break; |
||||
|
} |
||||
|
if ($data) { |
||||
|
$wxapp_register_version_table->where('id', $wxapp_register_version['id'])->fill($data)->save(); |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,85 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
PHPExcel_Autoloader::Register(); |
||||
|
// As we always try to run the autoloader before anything else, we can use it to do a few |
||||
|
// simple checks and initialisations |
||||
|
//PHPExcel_Shared_ZipStreamWrapper::register(); |
||||
|
// check mbstring.func_overload |
||||
|
if (ini_get('mbstring.func_overload') & 2) { |
||||
|
throw new PHPExcel_Exception('Multibyte function overloading in PHP must be disabled for string functions (2).'); |
||||
|
} |
||||
|
PHPExcel_Shared_String::buildCharacterSets(); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Autoloader |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Autoloader |
||||
|
{ |
||||
|
/** |
||||
|
* Register the Autoloader with SPL |
||||
|
* |
||||
|
*/ |
||||
|
public static function Register() { |
||||
|
if (function_exists('__autoload')) { |
||||
|
// Register any existing autoloader function with SPL, so we don't get any clashes |
||||
|
spl_autoload_register('__autoload'); |
||||
|
} |
||||
|
// Register ourselves with SPL |
||||
|
return spl_autoload_register(array('PHPExcel_Autoloader', 'Load')); |
||||
|
} // function Register() |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Autoload a class identified by name |
||||
|
* |
||||
|
* @param string $pClassName Name of the object to load |
||||
|
*/ |
||||
|
public static function Load($pClassName){ |
||||
|
if ((class_exists($pClassName,FALSE)) || (strpos($pClassName, 'PHPExcel') !== 0)) { |
||||
|
// Either already loaded, or not a PHPExcel class request |
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
$pClassFilePath = PHPEXCEL_ROOT . |
||||
|
str_replace('_',DIRECTORY_SEPARATOR,$pClassName) . |
||||
|
'.php'; |
||||
|
|
||||
|
if ((file_exists($pClassFilePath) === FALSE) || (is_readable($pClassFilePath) === FALSE)) { |
||||
|
// Can't load |
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
require($pClassFilePath); |
||||
|
} // function Load() |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,409 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Style |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Style_Alignment |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Style |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable |
||||
|
{ |
||||
|
/* Horizontal alignment styles */ |
||||
|
const HORIZONTAL_GENERAL = 'general'; |
||||
|
const HORIZONTAL_LEFT = 'left'; |
||||
|
const HORIZONTAL_RIGHT = 'right'; |
||||
|
const HORIZONTAL_CENTER = 'center'; |
||||
|
const HORIZONTAL_CENTER_CONTINUOUS = 'centerContinuous'; |
||||
|
const HORIZONTAL_JUSTIFY = 'justify'; |
||||
|
|
||||
|
/* Vertical alignment styles */ |
||||
|
const VERTICAL_BOTTOM = 'bottom'; |
||||
|
const VERTICAL_TOP = 'top'; |
||||
|
const VERTICAL_CENTER = 'center'; |
||||
|
const VERTICAL_JUSTIFY = 'justify'; |
||||
|
|
||||
|
/** |
||||
|
* Horizontal |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; |
||||
|
|
||||
|
/** |
||||
|
* Vertical |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; |
||||
|
|
||||
|
/** |
||||
|
* Text rotation |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_textRotation = 0; |
||||
|
|
||||
|
/** |
||||
|
* Wrap text |
||||
|
* |
||||
|
* @var boolean |
||||
|
*/ |
||||
|
protected $_wrapText = FALSE; |
||||
|
|
||||
|
/** |
||||
|
* Shrink to fit |
||||
|
* |
||||
|
* @var boolean |
||||
|
*/ |
||||
|
protected $_shrinkToFit = FALSE; |
||||
|
|
||||
|
/** |
||||
|
* Indent - only possible with horizontal alignment left and right |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_indent = 0; |
||||
|
|
||||
|
/** |
||||
|
* Create a new PHPExcel_Style_Alignment |
||||
|
* |
||||
|
* @param boolean $isSupervisor Flag indicating if this is a supervisor or not |
||||
|
* Leave this value at default unless you understand exactly what |
||||
|
* its ramifications are |
||||
|
* @param boolean $isConditional Flag indicating if this is a conditional style or not |
||||
|
* Leave this value at default unless you understand exactly what |
||||
|
* its ramifications are |
||||
|
*/ |
||||
|
public function __construct($isSupervisor = FALSE, $isConditional = FALSE) |
||||
|
{ |
||||
|
// Supervisor? |
||||
|
parent::__construct($isSupervisor); |
||||
|
|
||||
|
if ($isConditional) { |
||||
|
$this->_horizontal = NULL; |
||||
|
$this->_vertical = NULL; |
||||
|
$this->_textRotation = NULL; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the shared style component for the currently active cell in currently active sheet. |
||||
|
* Only used for style supervisor |
||||
|
* |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function getSharedComponent() |
||||
|
{ |
||||
|
return $this->_parent->getSharedComponent()->getAlignment(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Build style array from subcomponents |
||||
|
* |
||||
|
* @param array $array |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getStyleArray($array) |
||||
|
{ |
||||
|
return array('alignment' => $array); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Apply styles from array |
||||
|
* |
||||
|
* <code> |
||||
|
* $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray( |
||||
|
* array( |
||||
|
* 'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER, |
||||
|
* 'vertical' => PHPExcel_Style_Alignment::VERTICAL_CENTER, |
||||
|
* 'rotation' => 0, |
||||
|
* 'wrap' => TRUE |
||||
|
* ) |
||||
|
* ); |
||||
|
* </code> |
||||
|
* |
||||
|
* @param array $pStyles Array containing style information |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function applyFromArray($pStyles = NULL) { |
||||
|
if (is_array($pStyles)) { |
||||
|
if ($this->_isSupervisor) { |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells()) |
||||
|
->applyFromArray($this->getStyleArray($pStyles)); |
||||
|
} else { |
||||
|
if (isset($pStyles['horizontal'])) { |
||||
|
$this->setHorizontal($pStyles['horizontal']); |
||||
|
} |
||||
|
if (isset($pStyles['vertical'])) { |
||||
|
$this->setVertical($pStyles['vertical']); |
||||
|
} |
||||
|
if (isset($pStyles['rotation'])) { |
||||
|
$this->setTextRotation($pStyles['rotation']); |
||||
|
} |
||||
|
if (isset($pStyles['wrap'])) { |
||||
|
$this->setWrapText($pStyles['wrap']); |
||||
|
} |
||||
|
if (isset($pStyles['shrinkToFit'])) { |
||||
|
$this->setShrinkToFit($pStyles['shrinkToFit']); |
||||
|
} |
||||
|
if (isset($pStyles['indent'])) { |
||||
|
$this->setIndent($pStyles['indent']); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception("Invalid style array passed."); |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Horizontal |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getHorizontal() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getHorizontal(); |
||||
|
} |
||||
|
return $this->_horizontal; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Horizontal |
||||
|
* |
||||
|
* @param string $pValue |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) { |
||||
|
if ($pValue == '') { |
||||
|
$pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL; |
||||
|
} |
||||
|
|
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('horizontal' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} |
||||
|
else { |
||||
|
$this->_horizontal = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Vertical |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getVertical() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getVertical(); |
||||
|
} |
||||
|
return $this->_vertical; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Vertical |
||||
|
* |
||||
|
* @param string $pValue |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM) { |
||||
|
if ($pValue == '') { |
||||
|
$pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM; |
||||
|
} |
||||
|
|
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('vertical' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_vertical = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get TextRotation |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getTextRotation() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getTextRotation(); |
||||
|
} |
||||
|
return $this->_textRotation; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set TextRotation |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function setTextRotation($pValue = 0) { |
||||
|
// Excel2007 value 255 => PHPExcel value -165 |
||||
|
if ($pValue == 255) { |
||||
|
$pValue = -165; |
||||
|
} |
||||
|
|
||||
|
// Set rotation |
||||
|
if ( ($pValue >= -90 && $pValue <= 90) || $pValue == -165 ) { |
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('rotation' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_textRotation = $pValue; |
||||
|
} |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception("Text rotation should be a value between -90 and 90."); |
||||
|
} |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Wrap Text |
||||
|
* |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function getWrapText() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getWrapText(); |
||||
|
} |
||||
|
return $this->_wrapText; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Wrap Text |
||||
|
* |
||||
|
* @param boolean $pValue |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function setWrapText($pValue = FALSE) { |
||||
|
if ($pValue == '') { |
||||
|
$pValue = FALSE; |
||||
|
} |
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('wrap' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_wrapText = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Shrink to fit |
||||
|
* |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function getShrinkToFit() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getShrinkToFit(); |
||||
|
} |
||||
|
return $this->_shrinkToFit; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Shrink to fit |
||||
|
* |
||||
|
* @param boolean $pValue |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function setShrinkToFit($pValue = FALSE) { |
||||
|
if ($pValue == '') { |
||||
|
$pValue = FALSE; |
||||
|
} |
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_shrinkToFit = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get indent |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getIndent() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getIndent(); |
||||
|
} |
||||
|
return $this->_indent; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set indent |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Style_Alignment |
||||
|
*/ |
||||
|
public function setIndent($pValue = 0) { |
||||
|
if ($pValue > 0) { |
||||
|
if ($this->getHorizontal() != self::HORIZONTAL_GENERAL && |
||||
|
$this->getHorizontal() != self::HORIZONTAL_LEFT && |
||||
|
$this->getHorizontal() != self::HORIZONTAL_RIGHT) { |
||||
|
$pValue = 0; // indent not supported |
||||
|
} |
||||
|
} |
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('indent' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_indent = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get hash code |
||||
|
* |
||||
|
* @return string Hash code |
||||
|
*/ |
||||
|
public function getHashCode() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getHashCode(); |
||||
|
} |
||||
|
return md5( |
||||
|
$this->_horizontal |
||||
|
. $this->_vertical |
||||
|
. $this->_textRotation |
||||
|
. ($this->_wrapText ? 't' : 'f') |
||||
|
. ($this->_shrinkToFit ? 't' : 'f') |
||||
|
. $this->_indent |
||||
|
. __CLASS__ |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,294 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Style |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Style_Border |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Style |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable |
||||
|
{ |
||||
|
/* Border style */ |
||||
|
const BORDER_NONE = 'none'; |
||||
|
const BORDER_DASHDOT = 'dashDot'; |
||||
|
const BORDER_DASHDOTDOT = 'dashDotDot'; |
||||
|
const BORDER_DASHED = 'dashed'; |
||||
|
const BORDER_DOTTED = 'dotted'; |
||||
|
const BORDER_DOUBLE = 'double'; |
||||
|
const BORDER_HAIR = 'hair'; |
||||
|
const BORDER_MEDIUM = 'medium'; |
||||
|
const BORDER_MEDIUMDASHDOT = 'mediumDashDot'; |
||||
|
const BORDER_MEDIUMDASHDOTDOT = 'mediumDashDotDot'; |
||||
|
const BORDER_MEDIUMDASHED = 'mediumDashed'; |
||||
|
const BORDER_SLANTDASHDOT = 'slantDashDot'; |
||||
|
const BORDER_THICK = 'thick'; |
||||
|
const BORDER_THIN = 'thin'; |
||||
|
|
||||
|
/** |
||||
|
* Border style |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_borderStyle = PHPExcel_Style_Border::BORDER_NONE; |
||||
|
|
||||
|
/** |
||||
|
* Border color |
||||
|
* |
||||
|
* @var PHPExcel_Style_Color |
||||
|
*/ |
||||
|
protected $_color; |
||||
|
|
||||
|
/** |
||||
|
* Parent property name |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_parentPropertyName; |
||||
|
|
||||
|
/** |
||||
|
* Create a new PHPExcel_Style_Border |
||||
|
* |
||||
|
* @param boolean $isSupervisor Flag indicating if this is a supervisor or not |
||||
|
* Leave this value at default unless you understand exactly what |
||||
|
* its ramifications are |
||||
|
* @param boolean $isConditional Flag indicating if this is a conditional style or not |
||||
|
* Leave this value at default unless you understand exactly what |
||||
|
* its ramifications are |
||||
|
*/ |
||||
|
public function __construct($isSupervisor = FALSE, $isConditional = FALSE) |
||||
|
{ |
||||
|
// Supervisor? |
||||
|
parent::__construct($isSupervisor); |
||||
|
|
||||
|
// Initialise values |
||||
|
$this->_color = new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor); |
||||
|
|
||||
|
// bind parent if we are a supervisor |
||||
|
if ($isSupervisor) { |
||||
|
$this->_color->bindParent($this, '_color'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Bind parent. Only used for supervisor |
||||
|
* |
||||
|
* @param PHPExcel_Style_Borders $parent |
||||
|
* @param string $parentPropertyName |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function bindParent($parent, $parentPropertyName=NULL) |
||||
|
{ |
||||
|
$this->_parent = $parent; |
||||
|
$this->_parentPropertyName = $parentPropertyName; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the shared style component for the currently active cell in currently active sheet. |
||||
|
* Only used for style supervisor |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
* @throws PHPExcel_Exception |
||||
|
*/ |
||||
|
public function getSharedComponent() |
||||
|
{ |
||||
|
switch ($this->_parentPropertyName) { |
||||
|
case '_allBorders': |
||||
|
case '_horizontal': |
||||
|
case '_inside': |
||||
|
case '_outline': |
||||
|
case '_vertical': |
||||
|
throw new PHPExcel_Exception('Cannot get shared component for a pseudo-border.'); |
||||
|
break; |
||||
|
case '_bottom': |
||||
|
return $this->_parent->getSharedComponent()->getBottom(); break; |
||||
|
case '_diagonal': |
||||
|
return $this->_parent->getSharedComponent()->getDiagonal(); break; |
||||
|
case '_left': |
||||
|
return $this->_parent->getSharedComponent()->getLeft(); break; |
||||
|
case '_right': |
||||
|
return $this->_parent->getSharedComponent()->getRight(); break; |
||||
|
case '_top': |
||||
|
return $this->_parent->getSharedComponent()->getTop(); break; |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Build style array from subcomponents |
||||
|
* |
||||
|
* @param array $array |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getStyleArray($array) |
||||
|
{ |
||||
|
switch ($this->_parentPropertyName) { |
||||
|
case '_allBorders': |
||||
|
$key = 'allborders'; break; |
||||
|
case '_bottom': |
||||
|
$key = 'bottom'; break; |
||||
|
case '_diagonal': |
||||
|
$key = 'diagonal'; break; |
||||
|
case '_horizontal': |
||||
|
$key = 'horizontal'; break; |
||||
|
case '_inside': |
||||
|
$key = 'inside'; break; |
||||
|
case '_left': |
||||
|
$key = 'left'; break; |
||||
|
case '_outline': |
||||
|
$key = 'outline'; break; |
||||
|
case '_right': |
||||
|
$key = 'right'; break; |
||||
|
case '_top': |
||||
|
$key = 'top'; break; |
||||
|
case '_vertical': |
||||
|
$key = 'vertical'; break; |
||||
|
} |
||||
|
return $this->_parent->getStyleArray(array($key => $array)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Apply styles from array |
||||
|
* |
||||
|
* <code> |
||||
|
* $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray( |
||||
|
* array( |
||||
|
* 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, |
||||
|
* 'color' => array( |
||||
|
* 'rgb' => '808080' |
||||
|
* ) |
||||
|
* ) |
||||
|
* ); |
||||
|
* </code> |
||||
|
* |
||||
|
* @param array $pStyles Array containing style information |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function applyFromArray($pStyles = null) { |
||||
|
if (is_array($pStyles)) { |
||||
|
if ($this->_isSupervisor) { |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); |
||||
|
} else { |
||||
|
if (isset($pStyles['style'])) { |
||||
|
$this->setBorderStyle($pStyles['style']); |
||||
|
} |
||||
|
if (isset($pStyles['color'])) { |
||||
|
$this->getColor()->applyFromArray($pStyles['color']); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception("Invalid style array passed."); |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Border style |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getBorderStyle() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getBorderStyle(); |
||||
|
} |
||||
|
return $this->_borderStyle; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Border style |
||||
|
* |
||||
|
* @param string|boolean $pValue |
||||
|
* When passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE |
||||
|
* and TRUE to PHPExcel_Style_Border::BORDER_MEDIUM |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE) { |
||||
|
|
||||
|
if (empty($pValue)) { |
||||
|
$pValue = PHPExcel_Style_Border::BORDER_NONE; |
||||
|
} elseif(is_bool($pValue) && $pValue) { |
||||
|
$pValue = PHPExcel_Style_Border::BORDER_MEDIUM; |
||||
|
} |
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('style' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_borderStyle = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Border Color |
||||
|
* |
||||
|
* @return PHPExcel_Style_Color |
||||
|
*/ |
||||
|
public function getColor() { |
||||
|
return $this->_color; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Border Color |
||||
|
* |
||||
|
* @param PHPExcel_Style_Color $pValue |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function setColor(PHPExcel_Style_Color $pValue = null) { |
||||
|
// make sure parameter is a real color and not a supervisor |
||||
|
$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue; |
||||
|
|
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB())); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_color = $color; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get hash code |
||||
|
* |
||||
|
* @return string Hash code |
||||
|
*/ |
||||
|
public function getHashCode() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getHashCode(); |
||||
|
} |
||||
|
return md5( |
||||
|
$this->_borderStyle |
||||
|
. $this->_color->getHashCode() |
||||
|
. __CLASS__ |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,424 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Style |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Style_Borders |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Style |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable |
||||
|
{ |
||||
|
/* Diagonal directions */ |
||||
|
const DIAGONAL_NONE = 0; |
||||
|
const DIAGONAL_UP = 1; |
||||
|
const DIAGONAL_DOWN = 2; |
||||
|
const DIAGONAL_BOTH = 3; |
||||
|
|
||||
|
/** |
||||
|
* Left |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_left; |
||||
|
|
||||
|
/** |
||||
|
* Right |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_right; |
||||
|
|
||||
|
/** |
||||
|
* Top |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_top; |
||||
|
|
||||
|
/** |
||||
|
* Bottom |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_bottom; |
||||
|
|
||||
|
/** |
||||
|
* Diagonal |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_diagonal; |
||||
|
|
||||
|
/** |
||||
|
* DiagonalDirection |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_diagonalDirection; |
||||
|
|
||||
|
/** |
||||
|
* All borders psedo-border. Only applies to supervisor. |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_allBorders; |
||||
|
|
||||
|
/** |
||||
|
* Outline psedo-border. Only applies to supervisor. |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_outline; |
||||
|
|
||||
|
/** |
||||
|
* Inside psedo-border. Only applies to supervisor. |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_inside; |
||||
|
|
||||
|
/** |
||||
|
* Vertical pseudo-border. Only applies to supervisor. |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_vertical; |
||||
|
|
||||
|
/** |
||||
|
* Horizontal pseudo-border. Only applies to supervisor. |
||||
|
* |
||||
|
* @var PHPExcel_Style_Border |
||||
|
*/ |
||||
|
protected $_horizontal; |
||||
|
|
||||
|
/** |
||||
|
* Create a new PHPExcel_Style_Borders |
||||
|
* |
||||
|
* @param boolean $isSupervisor Flag indicating if this is a supervisor or not |
||||
|
* Leave this value at default unless you understand exactly what |
||||
|
* its ramifications are |
||||
|
* @param boolean $isConditional Flag indicating if this is a conditional style or not |
||||
|
* Leave this value at default unless you understand exactly what |
||||
|
* its ramifications are |
||||
|
*/ |
||||
|
public function __construct($isSupervisor = FALSE, $isConditional = FALSE) |
||||
|
{ |
||||
|
// Supervisor? |
||||
|
parent::__construct($isSupervisor); |
||||
|
|
||||
|
// Initialise values |
||||
|
$this->_left = new PHPExcel_Style_Border($isSupervisor, $isConditional); |
||||
|
$this->_right = new PHPExcel_Style_Border($isSupervisor, $isConditional); |
||||
|
$this->_top = new PHPExcel_Style_Border($isSupervisor, $isConditional); |
||||
|
$this->_bottom = new PHPExcel_Style_Border($isSupervisor, $isConditional); |
||||
|
$this->_diagonal = new PHPExcel_Style_Border($isSupervisor, $isConditional); |
||||
|
$this->_diagonalDirection = PHPExcel_Style_Borders::DIAGONAL_NONE; |
||||
|
|
||||
|
// Specially for supervisor |
||||
|
if ($isSupervisor) { |
||||
|
// Initialize pseudo-borders |
||||
|
$this->_allBorders = new PHPExcel_Style_Border(TRUE); |
||||
|
$this->_outline = new PHPExcel_Style_Border(TRUE); |
||||
|
$this->_inside = new PHPExcel_Style_Border(TRUE); |
||||
|
$this->_vertical = new PHPExcel_Style_Border(TRUE); |
||||
|
$this->_horizontal = new PHPExcel_Style_Border(TRUE); |
||||
|
|
||||
|
// bind parent if we are a supervisor |
||||
|
$this->_left->bindParent($this, '_left'); |
||||
|
$this->_right->bindParent($this, '_right'); |
||||
|
$this->_top->bindParent($this, '_top'); |
||||
|
$this->_bottom->bindParent($this, '_bottom'); |
||||
|
$this->_diagonal->bindParent($this, '_diagonal'); |
||||
|
$this->_allBorders->bindParent($this, '_allBorders'); |
||||
|
$this->_outline->bindParent($this, '_outline'); |
||||
|
$this->_inside->bindParent($this, '_inside'); |
||||
|
$this->_vertical->bindParent($this, '_vertical'); |
||||
|
$this->_horizontal->bindParent($this, '_horizontal'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the shared style component for the currently active cell in currently active sheet. |
||||
|
* Only used for style supervisor |
||||
|
* |
||||
|
* @return PHPExcel_Style_Borders |
||||
|
*/ |
||||
|
public function getSharedComponent() |
||||
|
{ |
||||
|
return $this->_parent->getSharedComponent()->getBorders(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Build style array from subcomponents |
||||
|
* |
||||
|
* @param array $array |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function getStyleArray($array) |
||||
|
{ |
||||
|
return array('borders' => $array); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Apply styles from array |
||||
|
* |
||||
|
* <code> |
||||
|
* $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( |
||||
|
* array( |
||||
|
* 'bottom' => array( |
||||
|
* 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, |
||||
|
* 'color' => array( |
||||
|
* 'rgb' => '808080' |
||||
|
* ) |
||||
|
* ), |
||||
|
* 'top' => array( |
||||
|
* 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, |
||||
|
* 'color' => array( |
||||
|
* 'rgb' => '808080' |
||||
|
* ) |
||||
|
* ) |
||||
|
* ) |
||||
|
* ); |
||||
|
* </code> |
||||
|
* <code> |
||||
|
* $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray( |
||||
|
* array( |
||||
|
* 'allborders' => array( |
||||
|
* 'style' => PHPExcel_Style_Border::BORDER_DASHDOT, |
||||
|
* 'color' => array( |
||||
|
* 'rgb' => '808080' |
||||
|
* ) |
||||
|
* ) |
||||
|
* ) |
||||
|
* ); |
||||
|
* </code> |
||||
|
* |
||||
|
* @param array $pStyles Array containing style information |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Style_Borders |
||||
|
*/ |
||||
|
public function applyFromArray($pStyles = null) { |
||||
|
if (is_array($pStyles)) { |
||||
|
if ($this->_isSupervisor) { |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles)); |
||||
|
} else { |
||||
|
if (array_key_exists('left', $pStyles)) { |
||||
|
$this->getLeft()->applyFromArray($pStyles['left']); |
||||
|
} |
||||
|
if (array_key_exists('right', $pStyles)) { |
||||
|
$this->getRight()->applyFromArray($pStyles['right']); |
||||
|
} |
||||
|
if (array_key_exists('top', $pStyles)) { |
||||
|
$this->getTop()->applyFromArray($pStyles['top']); |
||||
|
} |
||||
|
if (array_key_exists('bottom', $pStyles)) { |
||||
|
$this->getBottom()->applyFromArray($pStyles['bottom']); |
||||
|
} |
||||
|
if (array_key_exists('diagonal', $pStyles)) { |
||||
|
$this->getDiagonal()->applyFromArray($pStyles['diagonal']); |
||||
|
} |
||||
|
if (array_key_exists('diagonaldirection', $pStyles)) { |
||||
|
$this->setDiagonalDirection($pStyles['diagonaldirection']); |
||||
|
} |
||||
|
if (array_key_exists('allborders', $pStyles)) { |
||||
|
$this->getLeft()->applyFromArray($pStyles['allborders']); |
||||
|
$this->getRight()->applyFromArray($pStyles['allborders']); |
||||
|
$this->getTop()->applyFromArray($pStyles['allborders']); |
||||
|
$this->getBottom()->applyFromArray($pStyles['allborders']); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception("Invalid style array passed."); |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Left |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function getLeft() { |
||||
|
return $this->_left; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Right |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function getRight() { |
||||
|
return $this->_right; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Top |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function getTop() { |
||||
|
return $this->_top; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Bottom |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function getBottom() { |
||||
|
return $this->_bottom; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Diagonal |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
*/ |
||||
|
public function getDiagonal() { |
||||
|
return $this->_diagonal; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get AllBorders (pseudo-border). Only applies to supervisor. |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
* @throws PHPExcel_Exception |
||||
|
*/ |
||||
|
public function getAllBorders() { |
||||
|
if (!$this->_isSupervisor) { |
||||
|
throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); |
||||
|
} |
||||
|
return $this->_allBorders; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Outline (pseudo-border). Only applies to supervisor. |
||||
|
* |
||||
|
* @return boolean |
||||
|
* @throws PHPExcel_Exception |
||||
|
*/ |
||||
|
public function getOutline() { |
||||
|
if (!$this->_isSupervisor) { |
||||
|
throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); |
||||
|
} |
||||
|
return $this->_outline; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Inside (pseudo-border). Only applies to supervisor. |
||||
|
* |
||||
|
* @return boolean |
||||
|
* @throws PHPExcel_Exception |
||||
|
*/ |
||||
|
public function getInside() { |
||||
|
if (!$this->_isSupervisor) { |
||||
|
throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); |
||||
|
} |
||||
|
return $this->_inside; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Vertical (pseudo-border). Only applies to supervisor. |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
* @throws PHPExcel_Exception |
||||
|
*/ |
||||
|
public function getVertical() { |
||||
|
if (!$this->_isSupervisor) { |
||||
|
throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); |
||||
|
} |
||||
|
return $this->_vertical; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Horizontal (pseudo-border). Only applies to supervisor. |
||||
|
* |
||||
|
* @return PHPExcel_Style_Border |
||||
|
* @throws PHPExcel_Exception |
||||
|
*/ |
||||
|
public function getHorizontal() { |
||||
|
if (!$this->_isSupervisor) { |
||||
|
throw new PHPExcel_Exception('Can only get pseudo-border for supervisor.'); |
||||
|
} |
||||
|
return $this->_horizontal; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get DiagonalDirection |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getDiagonalDirection() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getDiagonalDirection(); |
||||
|
} |
||||
|
return $this->_diagonalDirection; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set DiagonalDirection |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Style_Borders |
||||
|
*/ |
||||
|
public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE) { |
||||
|
if ($pValue == '') { |
||||
|
$pValue = PHPExcel_Style_Borders::DIAGONAL_NONE; |
||||
|
} |
||||
|
if ($this->_isSupervisor) { |
||||
|
$styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue)); |
||||
|
$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray); |
||||
|
} else { |
||||
|
$this->_diagonalDirection = $pValue; |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get hash code |
||||
|
* |
||||
|
* @return string Hash code |
||||
|
*/ |
||||
|
public function getHashCode() { |
||||
|
if ($this->_isSupervisor) { |
||||
|
return $this->getSharedComponent()->getHashcode(); |
||||
|
} |
||||
|
return md5( |
||||
|
$this->getLeft()->getHashCode() |
||||
|
. $this->getRight()->getHashCode() |
||||
|
. $this->getTop()->getHashCode() |
||||
|
. $this->getBottom()->getHashCode() |
||||
|
. $this->getDiagonal()->getHashCode() |
||||
|
. $this->getDiagonalDirection() |
||||
|
. __CLASS__ |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,858 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Worksheet |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Worksheet_AutoFilter |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Worksheet |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Worksheet_AutoFilter |
||||
|
{ |
||||
|
/** |
||||
|
* Autofilter Worksheet |
||||
|
* |
||||
|
* @var PHPExcel_Worksheet |
||||
|
*/ |
||||
|
private $_workSheet = NULL; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Autofilter Range |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
private $_range = ''; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Autofilter Column Ruleset |
||||
|
* |
||||
|
* @var array of PHPExcel_Worksheet_AutoFilter_Column |
||||
|
*/ |
||||
|
private $_columns = array(); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Create a new PHPExcel_Worksheet_AutoFilter |
||||
|
* |
||||
|
* @param string $pRange Cell range (i.e. A1:E10) |
||||
|
* @param PHPExcel_Worksheet $pSheet |
||||
|
*/ |
||||
|
public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL) |
||||
|
{ |
||||
|
$this->_range = $pRange; |
||||
|
$this->_workSheet = $pSheet; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get AutoFilter Parent Worksheet |
||||
|
* |
||||
|
* @return PHPExcel_Worksheet |
||||
|
*/ |
||||
|
public function getParent() { |
||||
|
return $this->_workSheet; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set AutoFilter Parent Worksheet |
||||
|
* |
||||
|
* @param PHPExcel_Worksheet $pSheet |
||||
|
* @return PHPExcel_Worksheet_AutoFilter |
||||
|
*/ |
||||
|
public function setParent(PHPExcel_Worksheet $pSheet = NULL) { |
||||
|
$this->_workSheet = $pSheet; |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get AutoFilter Range |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getRange() { |
||||
|
return $this->_range; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set AutoFilter Range |
||||
|
* |
||||
|
* @param string $pRange Cell range (i.e. A1:E10) |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_AutoFilter |
||||
|
*/ |
||||
|
public function setRange($pRange = '') { |
||||
|
// Uppercase coordinate |
||||
|
$cellAddress = explode('!',strtoupper($pRange)); |
||||
|
if (count($cellAddress) > 1) { |
||||
|
list($worksheet,$pRange) = $cellAddress; |
||||
|
} |
||||
|
|
||||
|
if (strpos($pRange,':') !== FALSE) { |
||||
|
$this->_range = $pRange; |
||||
|
} elseif(empty($pRange)) { |
||||
|
$this->_range = ''; |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception('Autofilter must be set on a range of cells.'); |
||||
|
} |
||||
|
|
||||
|
if (empty($pRange)) { |
||||
|
// Discard all column rules |
||||
|
$this->_columns = array(); |
||||
|
} else { |
||||
|
// Discard any column rules that are no longer valid within this range |
||||
|
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); |
||||
|
foreach($this->_columns as $key => $value) { |
||||
|
$colIndex = PHPExcel_Cell::columnIndexFromString($key); |
||||
|
if (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) { |
||||
|
unset($this->_columns[$key]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get all AutoFilter Columns |
||||
|
* |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return array of PHPExcel_Worksheet_AutoFilter_Column |
||||
|
*/ |
||||
|
public function getColumns() { |
||||
|
return $this->_columns; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Validate that the specified column is in the AutoFilter range |
||||
|
* |
||||
|
* @param string $column Column name (e.g. A) |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return integer The column offset within the autofilter range |
||||
|
*/ |
||||
|
public function testColumnInRange($column) { |
||||
|
if (empty($this->_range)) { |
||||
|
throw new PHPExcel_Exception("No autofilter range is defined."); |
||||
|
} |
||||
|
|
||||
|
$columnIndex = PHPExcel_Cell::columnIndexFromString($column); |
||||
|
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); |
||||
|
if (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) { |
||||
|
throw new PHPExcel_Exception("Column is outside of current autofilter range."); |
||||
|
} |
||||
|
|
||||
|
return $columnIndex - $rangeStart[0]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a specified AutoFilter Column Offset within the defined AutoFilter range |
||||
|
* |
||||
|
* @param string $pColumn Column name (e.g. A) |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return integer The offset of the specified column within the autofilter range |
||||
|
*/ |
||||
|
public function getColumnOffset($pColumn) { |
||||
|
return $this->testColumnInRange($pColumn); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a specified AutoFilter Column |
||||
|
* |
||||
|
* @param string $pColumn Column name (e.g. A) |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_AutoFilter_Column |
||||
|
*/ |
||||
|
public function getColumn($pColumn) { |
||||
|
$this->testColumnInRange($pColumn); |
||||
|
|
||||
|
if (!isset($this->_columns[$pColumn])) { |
||||
|
$this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); |
||||
|
} |
||||
|
|
||||
|
return $this->_columns[$pColumn]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get a specified AutoFilter Column by it's offset |
||||
|
* |
||||
|
* @param integer $pColumnOffset Column offset within range (starting from 0) |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_AutoFilter_Column |
||||
|
*/ |
||||
|
public function getColumnByOffset($pColumnOffset = 0) { |
||||
|
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); |
||||
|
$pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1); |
||||
|
|
||||
|
return $this->getColumn($pColumn); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set AutoFilter |
||||
|
* |
||||
|
* @param PHPExcel_Worksheet_AutoFilter_Column|string $pColumn |
||||
|
* A simple string containing a Column ID like 'A' is permitted |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_AutoFilter |
||||
|
*/ |
||||
|
public function setColumn($pColumn) |
||||
|
{ |
||||
|
if ((is_string($pColumn)) && (!empty($pColumn))) { |
||||
|
$column = $pColumn; |
||||
|
} elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { |
||||
|
$column = $pColumn->getColumnIndex(); |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception("Column is not within the autofilter range."); |
||||
|
} |
||||
|
$this->testColumnInRange($column); |
||||
|
|
||||
|
if (is_string($pColumn)) { |
||||
|
$this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this); |
||||
|
} elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) { |
||||
|
$pColumn->setParent($this); |
||||
|
$this->_columns[$column] = $pColumn; |
||||
|
} |
||||
|
ksort($this->_columns); |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Clear a specified AutoFilter Column |
||||
|
* |
||||
|
* @param string $pColumn Column name (e.g. A) |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_AutoFilter |
||||
|
*/ |
||||
|
public function clearColumn($pColumn) { |
||||
|
$this->testColumnInRange($pColumn); |
||||
|
|
||||
|
if (isset($this->_columns[$pColumn])) { |
||||
|
unset($this->_columns[$pColumn]); |
||||
|
} |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Shift an AutoFilter Column Rule to a different column |
||||
|
* |
||||
|
* Note: This method bypasses validation of the destination column to ensure it is within this AutoFilter range. |
||||
|
* Nor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value. |
||||
|
* Use with caution. |
||||
|
* |
||||
|
* @param string $fromColumn Column name (e.g. A) |
||||
|
* @param string $toColumn Column name (e.g. B) |
||||
|
* @return PHPExcel_Worksheet_AutoFilter |
||||
|
*/ |
||||
|
public function shiftColumn($fromColumn=NULL,$toColumn=NULL) { |
||||
|
$fromColumn = strtoupper($fromColumn); |
||||
|
$toColumn = strtoupper($toColumn); |
||||
|
|
||||
|
if (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) { |
||||
|
$this->_columns[$fromColumn]->setParent(); |
||||
|
$this->_columns[$fromColumn]->setColumnIndex($toColumn); |
||||
|
$this->_columns[$toColumn] = $this->_columns[$fromColumn]; |
||||
|
$this->_columns[$toColumn]->setParent($this); |
||||
|
unset($this->_columns[$fromColumn]); |
||||
|
|
||||
|
ksort($this->_columns); |
||||
|
} |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Test if cell value is in the defined set of values |
||||
|
* |
||||
|
* @param mixed $cellValue |
||||
|
* @param mixed[] $dataSet |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
private static function _filterTestInSimpleDataSet($cellValue,$dataSet) |
||||
|
{ |
||||
|
$dataSetValues = $dataSet['filterValues']; |
||||
|
$blanks = $dataSet['blanks']; |
||||
|
if (($cellValue == '') || ($cellValue === NULL)) { |
||||
|
return $blanks; |
||||
|
} |
||||
|
return in_array($cellValue,$dataSetValues); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test if cell value is in the defined set of Excel date values |
||||
|
* |
||||
|
* @param mixed $cellValue |
||||
|
* @param mixed[] $dataSet |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
private static function _filterTestInDateGroupSet($cellValue,$dataSet) |
||||
|
{ |
||||
|
$dateSet = $dataSet['filterValues']; |
||||
|
$blanks = $dataSet['blanks']; |
||||
|
if (($cellValue == '') || ($cellValue === NULL)) { |
||||
|
return $blanks; |
||||
|
} |
||||
|
|
||||
|
if (is_numeric($cellValue)) { |
||||
|
$dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue); |
||||
|
if ($cellValue < 1) { |
||||
|
// Just the time part |
||||
|
$dtVal = date('His',$dateValue); |
||||
|
$dateSet = $dateSet['time']; |
||||
|
} elseif($cellValue == floor($cellValue)) { |
||||
|
// Just the date part |
||||
|
$dtVal = date('Ymd',$dateValue); |
||||
|
$dateSet = $dateSet['date']; |
||||
|
} else { |
||||
|
// date and time parts |
||||
|
$dtVal = date('YmdHis',$dateValue); |
||||
|
$dateSet = $dateSet['dateTime']; |
||||
|
} |
||||
|
foreach($dateSet as $dateValue) { |
||||
|
// Use of substr to extract value at the appropriate group level |
||||
|
if (substr($dtVal,0,strlen($dateValue)) == $dateValue) |
||||
|
return TRUE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test if cell value is within a set of values defined by a ruleset |
||||
|
* |
||||
|
* @param mixed $cellValue |
||||
|
* @param mixed[] $ruleSet |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
private static function _filterTestInCustomDataSet($cellValue, $ruleSet) |
||||
|
{ |
||||
|
$dataSet = $ruleSet['filterRules']; |
||||
|
$join = $ruleSet['join']; |
||||
|
$customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE; |
||||
|
|
||||
|
if (!$customRuleForBlanks) { |
||||
|
// Blank cells are always ignored, so return a FALSE |
||||
|
if (($cellValue == '') || ($cellValue === NULL)) { |
||||
|
return FALSE; |
||||
|
} |
||||
|
} |
||||
|
$returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND); |
||||
|
foreach($dataSet as $rule) { |
||||
|
if (is_numeric($rule['value'])) { |
||||
|
// Numeric values are tested using the appropriate operator |
||||
|
switch ($rule['operator']) { |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : |
||||
|
$retVal = ($cellValue == $rule['value']); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : |
||||
|
$retVal = ($cellValue != $rule['value']); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN : |
||||
|
$retVal = ($cellValue > $rule['value']); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL : |
||||
|
$retVal = ($cellValue >= $rule['value']); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN : |
||||
|
$retVal = ($cellValue < $rule['value']); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL : |
||||
|
$retVal = ($cellValue <= $rule['value']); |
||||
|
break; |
||||
|
} |
||||
|
} elseif($rule['value'] == '') { |
||||
|
switch ($rule['operator']) { |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL : |
||||
|
$retVal = (($cellValue == '') || ($cellValue === NULL)); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL : |
||||
|
$retVal = (($cellValue != '') && ($cellValue !== NULL)); |
||||
|
break; |
||||
|
default : |
||||
|
$retVal = TRUE; |
||||
|
break; |
||||
|
} |
||||
|
} else { |
||||
|
// String values are always tested for equality, factoring in for wildcards (hence a regexp test) |
||||
|
$retVal = preg_match('/^'.$rule['value'].'$/i',$cellValue); |
||||
|
} |
||||
|
// If there are multiple conditions, then we need to test both using the appropriate join operator |
||||
|
switch ($join) { |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR : |
||||
|
$returnVal = $returnVal || $retVal; |
||||
|
// Break as soon as we have a TRUE match for OR joins, |
||||
|
// to avoid unnecessary additional code execution |
||||
|
if ($returnVal) |
||||
|
return $returnVal; |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND : |
||||
|
$returnVal = $returnVal && $retVal; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $returnVal; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Test if cell date value is matches a set of values defined by a set of months |
||||
|
* |
||||
|
* @param mixed $cellValue |
||||
|
* @param mixed[] $monthSet |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
private static function _filterTestInPeriodDateSet($cellValue, $monthSet) |
||||
|
{ |
||||
|
// Blank cells are always ignored, so return a FALSE |
||||
|
if (($cellValue == '') || ($cellValue === NULL)) { |
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
if (is_numeric($cellValue)) { |
||||
|
$dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue)); |
||||
|
if (in_array($dateValue,$monthSet)) { |
||||
|
return TRUE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return FALSE; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Search/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching |
||||
|
* |
||||
|
* @var array |
||||
|
*/ |
||||
|
private static $_fromReplace = array('\*', '\?', '~~', '~.*', '~.?'); |
||||
|
private static $_toReplace = array('.*', '.', '~', '\*', '\?'); |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Convert a dynamic rule daterange to a custom filter range expression for ease of calculation |
||||
|
* |
||||
|
* @param string $dynamicRuleType |
||||
|
* @param PHPExcel_Worksheet_AutoFilter_Column &$filterColumn |
||||
|
* @return mixed[] |
||||
|
*/ |
||||
|
private function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn) |
||||
|
{ |
||||
|
$rDateType = PHPExcel_Calculation_Functions::getReturnDateType(); |
||||
|
PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC); |
||||
|
$val = $maxVal = NULL; |
||||
|
|
||||
|
$ruleValues = array(); |
||||
|
$baseDate = PHPExcel_Calculation_DateTime::DATENOW(); |
||||
|
// Calculate start/end dates for the required date range based on current date |
||||
|
switch ($dynamicRuleType) { |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : |
||||
|
$baseDate = strtotime('-7 days',$baseDate); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : |
||||
|
$baseDate = strtotime('-7 days',$baseDate); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : |
||||
|
$baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : |
||||
|
$baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : |
||||
|
$baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : |
||||
|
$baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : |
||||
|
$baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : |
||||
|
$baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
switch ($dynamicRuleType) { |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : |
||||
|
$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); |
||||
|
$val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE : |
||||
|
$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate)); |
||||
|
$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR : |
||||
|
$maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate))); |
||||
|
++$maxVal; |
||||
|
$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER : |
||||
|
$thisMonth = date('m',$baseDate); |
||||
|
$thisQuarter = floor(--$thisMonth / 3); |
||||
|
$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate))); |
||||
|
++$maxVal; |
||||
|
$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH : |
||||
|
$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate))); |
||||
|
++$maxVal; |
||||
|
$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate))); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK : |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK : |
||||
|
$dayOfWeek = date('w',$baseDate); |
||||
|
$val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek; |
||||
|
$maxVal = $val + 7; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
switch ($dynamicRuleType) { |
||||
|
// Adjust Today dates for Yesterday and Tomorrow |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY : |
||||
|
--$maxVal; |
||||
|
--$val; |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW : |
||||
|
++$maxVal; |
||||
|
++$val; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
// Set the filter column rule attributes ready for writing |
||||
|
$filterColumn->setAttributes(array( 'val' => $val, |
||||
|
'maxVal' => $maxVal |
||||
|
) |
||||
|
); |
||||
|
|
||||
|
// Set the rules for identifying rows for hide/show |
||||
|
$ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL, |
||||
|
'value' => $val |
||||
|
); |
||||
|
$ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN, |
||||
|
'value' => $maxVal |
||||
|
); |
||||
|
PHPExcel_Calculation_Functions::setReturnDateType($rDateType); |
||||
|
|
||||
|
return array( |
||||
|
'method' => '_filterTestInCustomDataSet', |
||||
|
'arguments' => array( 'filterRules' => $ruleValues, |
||||
|
'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
private function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) { |
||||
|
$range = $columnID.$startRow.':'.$columnID.$endRow; |
||||
|
$dataValues = PHPExcel_Calculation_Functions::flattenArray( |
||||
|
$this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE) |
||||
|
); |
||||
|
|
||||
|
$dataValues = array_filter($dataValues); |
||||
|
if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) { |
||||
|
rsort($dataValues); |
||||
|
} else { |
||||
|
sort($dataValues); |
||||
|
} |
||||
|
|
||||
|
return array_pop(array_slice($dataValues,0,$ruleValue)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Apply the AutoFilter rules to the AutoFilter Range |
||||
|
* |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_AutoFilter |
||||
|
*/ |
||||
|
public function showHideRows() |
||||
|
{ |
||||
|
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range); |
||||
|
|
||||
|
// The heading row should always be visible |
||||
|
// echo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL; |
||||
|
$this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE); |
||||
|
|
||||
|
$columnFilterTests = array(); |
||||
|
foreach($this->_columns as $columnID => $filterColumn) { |
||||
|
$rules = $filterColumn->getRules(); |
||||
|
switch ($filterColumn->getFilterType()) { |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER : |
||||
|
$ruleValues = array(); |
||||
|
// Build a list of the filter value selections |
||||
|
foreach($rules as $rule) { |
||||
|
$ruleType = $rule->getRuleType(); |
||||
|
$ruleValues[] = $rule->getValue(); |
||||
|
} |
||||
|
// Test if we want to include blanks in our filter criteria |
||||
|
$blanks = FALSE; |
||||
|
$ruleDataSet = array_filter($ruleValues); |
||||
|
if (count($ruleValues) != count($ruleDataSet)) |
||||
|
$blanks = TRUE; |
||||
|
if ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) { |
||||
|
// Filter on absolute values |
||||
|
$columnFilterTests[$columnID] = array( |
||||
|
'method' => '_filterTestInSimpleDataSet', |
||||
|
'arguments' => array( 'filterValues' => $ruleDataSet, |
||||
|
'blanks' => $blanks |
||||
|
) |
||||
|
); |
||||
|
} else { |
||||
|
// Filter on date group values |
||||
|
$arguments = array(); |
||||
|
foreach($ruleDataSet as $ruleValue) { |
||||
|
$date = $time = ''; |
||||
|
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) && |
||||
|
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== '')) |
||||
|
$date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]); |
||||
|
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) && |
||||
|
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != '')) |
||||
|
$date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]); |
||||
|
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) && |
||||
|
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== '')) |
||||
|
$date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]); |
||||
|
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) && |
||||
|
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== '')) |
||||
|
$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]); |
||||
|
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) && |
||||
|
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== '')) |
||||
|
$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]); |
||||
|
if ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) && |
||||
|
($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== '')) |
||||
|
$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]); |
||||
|
$dateTime = $date . $time; |
||||
|
$arguments['date'][] = $date; |
||||
|
$arguments['time'][] = $time; |
||||
|
$arguments['dateTime'][] = $dateTime; |
||||
|
} |
||||
|
// Remove empty elements |
||||
|
$arguments['date'] = array_filter($arguments['date']); |
||||
|
$arguments['time'] = array_filter($arguments['time']); |
||||
|
$arguments['dateTime'] = array_filter($arguments['dateTime']); |
||||
|
$columnFilterTests[$columnID] = array( |
||||
|
'method' => '_filterTestInDateGroupSet', |
||||
|
'arguments' => array( 'filterValues' => $arguments, |
||||
|
'blanks' => $blanks |
||||
|
) |
||||
|
); |
||||
|
} |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER : |
||||
|
$customRuleForBlanks = FALSE; |
||||
|
$ruleValues = array(); |
||||
|
// Build a list of the filter value selections |
||||
|
foreach($rules as $rule) { |
||||
|
$ruleType = $rule->getRuleType(); |
||||
|
$ruleValue = $rule->getValue(); |
||||
|
if (!is_numeric($ruleValue)) { |
||||
|
// Convert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards |
||||
|
$ruleValue = preg_quote($ruleValue); |
||||
|
$ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue); |
||||
|
if (trim($ruleValue) == '') { |
||||
|
$customRuleForBlanks = TRUE; |
||||
|
$ruleValue = trim($ruleValue); |
||||
|
} |
||||
|
} |
||||
|
$ruleValues[] = array( 'operator' => $rule->getOperator(), |
||||
|
'value' => $ruleValue |
||||
|
); |
||||
|
} |
||||
|
$join = $filterColumn->getJoin(); |
||||
|
$columnFilterTests[$columnID] = array( |
||||
|
'method' => '_filterTestInCustomDataSet', |
||||
|
'arguments' => array( 'filterRules' => $ruleValues, |
||||
|
'join' => $join, |
||||
|
'customRuleForBlanks' => $customRuleForBlanks |
||||
|
) |
||||
|
); |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER : |
||||
|
$ruleValues = array(); |
||||
|
foreach($rules as $rule) { |
||||
|
// We should only ever have one Dynamic Filter Rule anyway |
||||
|
$dynamicRuleType = $rule->getGrouping(); |
||||
|
if (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) || |
||||
|
($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) { |
||||
|
// Number (Average) based |
||||
|
// Calculate the average |
||||
|
$averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')'; |
||||
|
$average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1')); |
||||
|
// Set above/below rule based on greaterThan or LessTan |
||||
|
$operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) |
||||
|
? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN |
||||
|
: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; |
||||
|
$ruleValues[] = array( 'operator' => $operator, |
||||
|
'value' => $average |
||||
|
); |
||||
|
$columnFilterTests[$columnID] = array( |
||||
|
'method' => '_filterTestInCustomDataSet', |
||||
|
'arguments' => array( 'filterRules' => $ruleValues, |
||||
|
'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR |
||||
|
) |
||||
|
); |
||||
|
} else { |
||||
|
// Date based |
||||
|
if ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') { |
||||
|
// Month or Quarter |
||||
|
sscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period); |
||||
|
if ($periodType == 'M') { |
||||
|
$ruleValues = array($period); |
||||
|
} else { |
||||
|
--$period; |
||||
|
$periodEnd = (1+$period)*3; |
||||
|
$periodStart = 1+$period*3; |
||||
|
$ruleValues = range($periodStart,periodEnd); |
||||
|
} |
||||
|
$columnFilterTests[$columnID] = array( |
||||
|
'method' => '_filterTestInPeriodDateSet', |
||||
|
'arguments' => $ruleValues |
||||
|
); |
||||
|
$filterColumn->setAttributes(array()); |
||||
|
} else { |
||||
|
// Date Range |
||||
|
$columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
case PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER : |
||||
|
$ruleValues = array(); |
||||
|
$dataRowCount = $rangeEnd[1] - $rangeStart[1]; |
||||
|
foreach($rules as $rule) { |
||||
|
// We should only ever have one Dynamic Filter Rule anyway |
||||
|
$toptenRuleType = $rule->getGrouping(); |
||||
|
$ruleValue = $rule->getValue(); |
||||
|
$ruleOperator = $rule->getOperator(); |
||||
|
} |
||||
|
if ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) { |
||||
|
$ruleValue = floor($ruleValue * ($dataRowCount / 100)); |
||||
|
} |
||||
|
if ($ruleValue < 1) $ruleValue = 1; |
||||
|
if ($ruleValue > 500) $ruleValue = 500; |
||||
|
|
||||
|
$maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue); |
||||
|
|
||||
|
$operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) |
||||
|
? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL |
||||
|
: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL; |
||||
|
$ruleValues[] = array( 'operator' => $operator, |
||||
|
'value' => $maxVal |
||||
|
); |
||||
|
$columnFilterTests[$columnID] = array( |
||||
|
'method' => '_filterTestInCustomDataSet', |
||||
|
'arguments' => array( 'filterRules' => $ruleValues, |
||||
|
'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR |
||||
|
) |
||||
|
); |
||||
|
$filterColumn->setAttributes( |
||||
|
array('maxVal' => $maxVal) |
||||
|
); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// echo 'Column Filter Test CRITERIA',PHP_EOL; |
||||
|
// var_dump($columnFilterTests); |
||||
|
// |
||||
|
// Execute the column tests for each row in the autoFilter range to determine show/hide, |
||||
|
for ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) { |
||||
|
// echo 'Testing Row = ',$row,PHP_EOL; |
||||
|
$result = TRUE; |
||||
|
foreach($columnFilterTests as $columnID => $columnFilterTest) { |
||||
|
// echo 'Testing cell ',$columnID.$row,PHP_EOL; |
||||
|
$cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue(); |
||||
|
// echo 'Value is ',$cellValue,PHP_EOL; |
||||
|
// Execute the filter test |
||||
|
$result = $result && |
||||
|
call_user_func_array( |
||||
|
array('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']), |
||||
|
array( |
||||
|
$cellValue, |
||||
|
$columnFilterTest['arguments'] |
||||
|
) |
||||
|
); |
||||
|
// echo (($result) ? 'VALID' : 'INVALID'),PHP_EOL; |
||||
|
// If filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests |
||||
|
if (!$result) |
||||
|
break; |
||||
|
} |
||||
|
// Set show/hide for the row based on the result of the autoFilter result |
||||
|
// echo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL; |
||||
|
$this->_workSheet->getRowDimension($row)->setVisible($result); |
||||
|
} |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Implement PHP __clone to create a deep clone, not just a shallow copy. |
||||
|
*/ |
||||
|
public function __clone() { |
||||
|
$vars = get_object_vars($this); |
||||
|
foreach ($vars as $key => $value) { |
||||
|
if (is_object($value)) { |
||||
|
if ($key == '_workSheet') { |
||||
|
// Detach from worksheet |
||||
|
$this->{$key} = NULL; |
||||
|
} else { |
||||
|
$this->{$key} = clone $value; |
||||
|
} |
||||
|
} elseif ((is_array($value)) && ($key == '_columns')) { |
||||
|
// The columns array of PHPExcel_Worksheet_AutoFilter objects |
||||
|
$this->{$key} = array(); |
||||
|
foreach ($value as $k => $v) { |
||||
|
$this->{$key}[$k] = clone $v; |
||||
|
// attach the new cloned Column to this new cloned Autofilter object |
||||
|
$this->{$key}[$k]->setParent($this); |
||||
|
} |
||||
|
} else { |
||||
|
$this->{$key} = $value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* toString method replicates previous behavior by returning the range if object is |
||||
|
* referenced as a property of its parent. |
||||
|
*/ |
||||
|
public function __toString() { |
||||
|
return (string) $this->_range; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,485 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Worksheet |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Worksheet_BaseDrawing |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Worksheet |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable |
||||
|
{ |
||||
|
/** |
||||
|
* Image counter |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
private static $_imageCounter = 0; |
||||
|
|
||||
|
/** |
||||
|
* Image index |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
private $_imageIndex = 0; |
||||
|
|
||||
|
/** |
||||
|
* Name |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_name; |
||||
|
|
||||
|
/** |
||||
|
* Description |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_description; |
||||
|
|
||||
|
/** |
||||
|
* Worksheet |
||||
|
* |
||||
|
* @var PHPExcel_Worksheet |
||||
|
*/ |
||||
|
protected $_worksheet; |
||||
|
|
||||
|
/** |
||||
|
* Coordinates |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_coordinates; |
||||
|
|
||||
|
/** |
||||
|
* Offset X |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_offsetX; |
||||
|
|
||||
|
/** |
||||
|
* Offset Y |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_offsetY; |
||||
|
|
||||
|
/** |
||||
|
* Width |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_width; |
||||
|
|
||||
|
/** |
||||
|
* Height |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_height; |
||||
|
|
||||
|
/** |
||||
|
* Proportional resize |
||||
|
* |
||||
|
* @var boolean |
||||
|
*/ |
||||
|
protected $_resizeProportional; |
||||
|
|
||||
|
/** |
||||
|
* Rotation |
||||
|
* |
||||
|
* @var int |
||||
|
*/ |
||||
|
protected $_rotation; |
||||
|
|
||||
|
/** |
||||
|
* Shadow |
||||
|
* |
||||
|
* @var PHPExcel_Worksheet_Drawing_Shadow |
||||
|
*/ |
||||
|
protected $_shadow; |
||||
|
|
||||
|
/** |
||||
|
* Create a new PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function __construct() |
||||
|
{ |
||||
|
// Initialise values |
||||
|
$this->_name = ''; |
||||
|
$this->_description = ''; |
||||
|
$this->_worksheet = null; |
||||
|
$this->_coordinates = 'A1'; |
||||
|
$this->_offsetX = 0; |
||||
|
$this->_offsetY = 0; |
||||
|
$this->_width = 0; |
||||
|
$this->_height = 0; |
||||
|
$this->_resizeProportional = true; |
||||
|
$this->_rotation = 0; |
||||
|
$this->_shadow = new PHPExcel_Worksheet_Drawing_Shadow(); |
||||
|
|
||||
|
// Set image index |
||||
|
self::$_imageCounter++; |
||||
|
$this->_imageIndex = self::$_imageCounter; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get image index |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getImageIndex() { |
||||
|
return $this->_imageIndex; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Name |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getName() { |
||||
|
return $this->_name; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Name |
||||
|
* |
||||
|
* @param string $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setName($pValue = '') { |
||||
|
$this->_name = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Description |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getDescription() { |
||||
|
return $this->_description; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Description |
||||
|
* |
||||
|
* @param string $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setDescription($pValue = '') { |
||||
|
$this->_description = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Worksheet |
||||
|
* |
||||
|
* @return PHPExcel_Worksheet |
||||
|
*/ |
||||
|
public function getWorksheet() { |
||||
|
return $this->_worksheet; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Worksheet |
||||
|
* |
||||
|
* @param PHPExcel_Worksheet $pValue |
||||
|
* @param bool $pOverrideOld If a Worksheet has already been assigned, overwrite it and remove image from old Worksheet? |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) { |
||||
|
if (is_null($this->_worksheet)) { |
||||
|
// Add drawing to PHPExcel_Worksheet |
||||
|
$this->_worksheet = $pValue; |
||||
|
$this->_worksheet->getCell($this->_coordinates); |
||||
|
$this->_worksheet->getDrawingCollection()->append($this); |
||||
|
} else { |
||||
|
if ($pOverrideOld) { |
||||
|
// Remove drawing from old PHPExcel_Worksheet |
||||
|
$iterator = $this->_worksheet->getDrawingCollection()->getIterator(); |
||||
|
|
||||
|
while ($iterator->valid()) { |
||||
|
if ($iterator->current()->getHashCode() == $this->getHashCode()) { |
||||
|
$this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() ); |
||||
|
$this->_worksheet = null; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Set new PHPExcel_Worksheet |
||||
|
$this->setWorksheet($pValue); |
||||
|
} else { |
||||
|
throw new PHPExcel_Exception("A PHPExcel_Worksheet has already been assigned. Drawings can only exist on one PHPExcel_Worksheet."); |
||||
|
} |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Coordinates |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getCoordinates() { |
||||
|
return $this->_coordinates; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Coordinates |
||||
|
* |
||||
|
* @param string $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setCoordinates($pValue = 'A1') { |
||||
|
$this->_coordinates = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get OffsetX |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getOffsetX() { |
||||
|
return $this->_offsetX; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set OffsetX |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setOffsetX($pValue = 0) { |
||||
|
$this->_offsetX = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get OffsetY |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getOffsetY() { |
||||
|
return $this->_offsetY; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set OffsetY |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setOffsetY($pValue = 0) { |
||||
|
$this->_offsetY = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Width |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getWidth() { |
||||
|
return $this->_width; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Width |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setWidth($pValue = 0) { |
||||
|
// Resize proportional? |
||||
|
if ($this->_resizeProportional && $pValue != 0) { |
||||
|
$ratio = $this->_height / $this->_width; |
||||
|
$this->_height = round($ratio * $pValue); |
||||
|
} |
||||
|
|
||||
|
// Set width |
||||
|
$this->_width = $pValue; |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Height |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getHeight() { |
||||
|
return $this->_height; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Height |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setHeight($pValue = 0) { |
||||
|
// Resize proportional? |
||||
|
if ($this->_resizeProportional && $pValue != 0) { |
||||
|
$ratio = $this->_width / $this->_height; |
||||
|
$this->_width = round($ratio * $pValue); |
||||
|
} |
||||
|
|
||||
|
// Set height |
||||
|
$this->_height = $pValue; |
||||
|
|
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set width and height with proportional resize |
||||
|
* Example: |
||||
|
* <code> |
||||
|
* $objDrawing->setResizeProportional(true); |
||||
|
* $objDrawing->setWidthAndHeight(160,120); |
||||
|
* </code> |
||||
|
* |
||||
|
* @author Vincent@luo MSN:kele_100@hotmail.com |
||||
|
* @param int $width |
||||
|
* @param int $height |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setWidthAndHeight($width = 0, $height = 0) { |
||||
|
$xratio = $width / $this->_width; |
||||
|
$yratio = $height / $this->_height; |
||||
|
if ($this->_resizeProportional && !($width == 0 || $height == 0)) { |
||||
|
if (($xratio * $this->_height) < $height) { |
||||
|
$this->_height = ceil($xratio * $this->_height); |
||||
|
$this->_width = $width; |
||||
|
} else { |
||||
|
$this->_width = ceil($yratio * $this->_width); |
||||
|
$this->_height = $height; |
||||
|
} |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get ResizeProportional |
||||
|
* |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function getResizeProportional() { |
||||
|
return $this->_resizeProportional; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set ResizeProportional |
||||
|
* |
||||
|
* @param boolean $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setResizeProportional($pValue = true) { |
||||
|
$this->_resizeProportional = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Rotation |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getRotation() { |
||||
|
return $this->_rotation; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Rotation |
||||
|
* |
||||
|
* @param int $pValue |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setRotation($pValue = 0) { |
||||
|
$this->_rotation = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Shadow |
||||
|
* |
||||
|
* @return PHPExcel_Worksheet_Drawing_Shadow |
||||
|
*/ |
||||
|
public function getShadow() { |
||||
|
return $this->_shadow; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Shadow |
||||
|
* |
||||
|
* @param PHPExcel_Worksheet_Drawing_Shadow $pValue |
||||
|
* @throws PHPExcel_Exception |
||||
|
* @return PHPExcel_Worksheet_BaseDrawing |
||||
|
*/ |
||||
|
public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) { |
||||
|
$this->_shadow = $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get hash code |
||||
|
* |
||||
|
* @return string Hash code |
||||
|
*/ |
||||
|
public function getHashCode() { |
||||
|
return md5( |
||||
|
$this->_name |
||||
|
. $this->_description |
||||
|
. $this->_worksheet->getHashCode() |
||||
|
. $this->_coordinates |
||||
|
. $this->_offsetX |
||||
|
. $this->_offsetY |
||||
|
. $this->_width |
||||
|
. $this->_height |
||||
|
. $this->_rotation |
||||
|
. $this->_shadow->getHashCode() |
||||
|
. __CLASS__ |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Implement PHP __clone to create a deep clone, not just a shallow copy. |
||||
|
*/ |
||||
|
public function __clone() { |
||||
|
$vars = get_object_vars($this); |
||||
|
foreach ($vars as $key => $value) { |
||||
|
if (is_object($value)) { |
||||
|
$this->$key = clone $value; |
||||
|
} else { |
||||
|
$this->$key = $value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,158 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Writer |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Writer_Abstract |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Writer |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
abstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter |
||||
|
{ |
||||
|
/** |
||||
|
* Write charts that are defined in the workbook? |
||||
|
* Identifies whether the Writer should write definitions for any charts that exist in the PHPExcel object; |
||||
|
* |
||||
|
* @var boolean |
||||
|
*/ |
||||
|
protected $_includeCharts = FALSE; |
||||
|
|
||||
|
/** |
||||
|
* Pre-calculate formulas |
||||
|
* Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are |
||||
|
* immediately available to MS Excel or other office spreadsheet viewer when opening the file |
||||
|
* |
||||
|
* @var boolean |
||||
|
*/ |
||||
|
protected $_preCalculateFormulas = TRUE; |
||||
|
|
||||
|
/** |
||||
|
* Use disk caching where possible? |
||||
|
* |
||||
|
* @var boolean |
||||
|
*/ |
||||
|
protected $_useDiskCaching = FALSE; |
||||
|
|
||||
|
/** |
||||
|
* Disk caching directory |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $_diskCachingDirectory = './'; |
||||
|
|
||||
|
/** |
||||
|
* Write charts in workbook? |
||||
|
* If this is true, then the Writer will write definitions for any charts that exist in the PHPExcel object. |
||||
|
* If false (the default) it will ignore any charts defined in the PHPExcel object. |
||||
|
* |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function getIncludeCharts() { |
||||
|
return $this->_includeCharts; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set write charts in workbook |
||||
|
* Set to true, to advise the Writer to include any charts that exist in the PHPExcel object. |
||||
|
* Set to false (the default) to ignore charts. |
||||
|
* |
||||
|
* @param boolean $pValue |
||||
|
* @return PHPExcel_Writer_IWriter |
||||
|
*/ |
||||
|
public function setIncludeCharts($pValue = FALSE) { |
||||
|
$this->_includeCharts = (boolean) $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get Pre-Calculate Formulas flag |
||||
|
* If this is true (the default), then the writer will recalculate all formulae in a workbook when saving, |
||||
|
* so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet |
||||
|
* viewer when opening the file |
||||
|
* If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower |
||||
|
* when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself |
||||
|
* |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function getPreCalculateFormulas() { |
||||
|
return $this->_preCalculateFormulas; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set Pre-Calculate Formulas |
||||
|
* Set to true (the default) to advise the Writer to calculate all formulae on save |
||||
|
* Set to false to prevent precalculation of formulae on save. |
||||
|
* |
||||
|
* @param boolean $pValue Pre-Calculate Formulas? |
||||
|
* @return PHPExcel_Writer_IWriter |
||||
|
*/ |
||||
|
public function setPreCalculateFormulas($pValue = TRUE) { |
||||
|
$this->_preCalculateFormulas = (boolean) $pValue; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get use disk caching where possible? |
||||
|
* |
||||
|
* @return boolean |
||||
|
*/ |
||||
|
public function getUseDiskCaching() { |
||||
|
return $this->_useDiskCaching; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set use disk caching where possible? |
||||
|
* |
||||
|
* @param boolean $pValue |
||||
|
* @param string $pDirectory Disk caching directory |
||||
|
* @throws PHPExcel_Writer_Exception when directory does not exist |
||||
|
* @return PHPExcel_Writer_Excel2007 |
||||
|
*/ |
||||
|
public function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) { |
||||
|
$this->_useDiskCaching = $pValue; |
||||
|
|
||||
|
if ($pDirectory !== NULL) { |
||||
|
if (is_dir($pDirectory)) { |
||||
|
$this->_diskCachingDirectory = $pDirectory; |
||||
|
} else { |
||||
|
throw new PHPExcel_Writer_Exception("Directory does not exist: $pDirectory"); |
||||
|
} |
||||
|
} |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get disk caching directory |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getDiskCachingDirectory() { |
||||
|
return $this->_diskCachingDirectory; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,255 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHPExcel |
||||
|
* |
||||
|
* Copyright (c) 2006 - 2013 PHPExcel |
||||
|
* |
||||
|
* This library is free software; you can redistribute it and/or |
||||
|
* modify it under the terms of the GNU Lesser General Public |
||||
|
* License as published by the Free Software Foundation; either |
||||
|
* version 2.1 of the License, or (at your option) any later version. |
||||
|
* |
||||
|
* This library is distributed in the hope that it will be useful, |
||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
* Lesser General Public License for more details. |
||||
|
* |
||||
|
* You should have received a copy of the GNU Lesser General Public |
||||
|
* License along with this library; if not, write to the Free Software |
||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Writer_Excel5 |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL |
||||
|
* @version 1.7.9, 2013-06-02 |
||||
|
*/ |
||||
|
|
||||
|
// Original file header of PEAR::Spreadsheet_Excel_Writer_BIFFwriter (used as the base for this class): |
||||
|
// ----------------------------------------------------------------------------------------- |
||||
|
// * Module written/ported by Xavier Noguer <xnoguer@rezebra.com> |
||||
|
// * |
||||
|
// * The majority of this is _NOT_ my code. I simply ported it from the |
||||
|
// * PERL Spreadsheet::WriteExcel module. |
||||
|
// * |
||||
|
// * The author of the Spreadsheet::WriteExcel module is John McNamara |
||||
|
// * <jmcnamara@cpan.org> |
||||
|
// * |
||||
|
// * I _DO_ maintain this code, and John McNamara has nothing to do with the |
||||
|
// * porting of this code to PHP. Any questions directly related to this |
||||
|
// * class library should be directed to me. |
||||
|
// * |
||||
|
// * License Information: |
||||
|
// * |
||||
|
// * Spreadsheet_Excel_Writer: A library for generating Excel Spreadsheets |
||||
|
// * Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com |
||||
|
// * |
||||
|
// * This library is free software; you can redistribute it and/or |
||||
|
// * modify it under the terms of the GNU Lesser General Public |
||||
|
// * License as published by the Free Software Foundation; either |
||||
|
// * version 2.1 of the License, or (at your option) any later version. |
||||
|
// * |
||||
|
// * This library is distributed in the hope that it will be useful, |
||||
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
|
// * Lesser General Public License for more details. |
||||
|
// * |
||||
|
// * You should have received a copy of the GNU Lesser General Public |
||||
|
// * License along with this library; if not, write to the Free Software |
||||
|
// * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||
|
// */ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* PHPExcel_Writer_Excel5_BIFFwriter |
||||
|
* |
||||
|
* @category PHPExcel |
||||
|
* @package PHPExcel_Writer_Excel5 |
||||
|
* @copyright Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel) |
||||
|
*/ |
||||
|
class PHPExcel_Writer_Excel5_BIFFwriter |
||||
|
{ |
||||
|
/** |
||||
|
* The byte order of this architecture. 0 => little endian, 1 => big endian |
||||
|
* @var integer |
||||
|
*/ |
||||
|
private static $_byte_order; |
||||
|
|
||||
|
/** |
||||
|
* The string containing the data of the BIFF stream |
||||
|
* @var string |
||||
|
*/ |
||||
|
public $_data; |
||||
|
|
||||
|
/** |
||||
|
* The size of the data in bytes. Should be the same as strlen($this->_data) |
||||
|
* @var integer |
||||
|
*/ |
||||
|
public $_datasize; |
||||
|
|
||||
|
/** |
||||
|
* The maximum length for a BIFF record (excluding record header and length field). See _addContinue() |
||||
|
* @var integer |
||||
|
* @see _addContinue() |
||||
|
*/ |
||||
|
public $_limit = 8224; |
||||
|
|
||||
|
/** |
||||
|
* Constructor |
||||
|
*/ |
||||
|
public function __construct() |
||||
|
{ |
||||
|
$this->_data = ''; |
||||
|
$this->_datasize = 0; |
||||
|
// $this->_limit = 8224; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Determine the byte order and store it as class data to avoid |
||||
|
* recalculating it for each call to new(). |
||||
|
* |
||||
|
* @return int |
||||
|
*/ |
||||
|
public static function getByteOrder() |
||||
|
{ |
||||
|
if (!isset(self::$_byte_order)) { |
||||
|
// Check if "pack" gives the required IEEE 64bit float |
||||
|
$teststr = pack("d", 1.2345); |
||||
|
$number = pack("C8", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F); |
||||
|
if ($number == $teststr) { |
||||
|
$byte_order = 0; // Little Endian |
||||
|
} elseif ($number == strrev($teststr)){ |
||||
|
$byte_order = 1; // Big Endian |
||||
|
} else { |
||||
|
// Give up. I'll fix this in a later version. |
||||
|
throw new PHPExcel_Writer_Exception("Required floating point format not supported on this platform."); |
||||
|
} |
||||
|
self::$_byte_order = $byte_order; |
||||
|
} |
||||
|
|
||||
|
return self::$_byte_order; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* General storage function |
||||
|
* |
||||
|
* @param string $data binary data to append |
||||
|
* @access private |
||||
|
*/ |
||||
|
function _append($data) |
||||
|
{ |
||||
|
if (strlen($data) - 4 > $this->_limit) { |
||||
|
$data = $this->_addContinue($data); |
||||
|
} |
||||
|
$this->_data .= $data; |
||||
|
$this->_datasize += strlen($data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* General storage function like _append, but returns string instead of modifying $this->_data |
||||
|
* |
||||
|
* @param string $data binary data to write |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function writeData($data) |
||||
|
{ |
||||
|
if (strlen($data) - 4 > $this->_limit) { |
||||
|
$data = $this->_addContinue($data); |
||||
|
} |
||||
|
$this->_datasize += strlen($data); |
||||
|
|
||||
|
return $data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Writes Excel BOF record to indicate the beginning of a stream or |
||||
|
* sub-stream in the BIFF file. |
||||
|
* |
||||
|
* @param integer $type Type of BIFF file to write: 0x0005 Workbook, |
||||
|
* 0x0010 Worksheet. |
||||
|
* @access private |
||||
|
*/ |
||||
|
function _storeBof($type) |
||||
|
{ |
||||
|
$record = 0x0809; // Record identifier (BIFF5-BIFF8) |
||||
|
$length = 0x0010; |
||||
|
|
||||
|
// by inspection of real files, MS Office Excel 2007 writes the following |
||||
|
$unknown = pack("VV", 0x000100D1, 0x00000406); |
||||
|
|
||||
|
$build = 0x0DBB; // Excel 97 |
||||
|
$year = 0x07CC; // Excel 97 |
||||
|
|
||||
|
$version = 0x0600; // BIFF8 |
||||
|
|
||||
|
$header = pack("vv", $record, $length); |
||||
|
$data = pack("vvvv", $version, $type, $build, $year); |
||||
|
$this->_append($header . $data . $unknown); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Writes Excel EOF record to indicate the end of a BIFF stream. |
||||
|
* |
||||
|
* @access private |
||||
|
*/ |
||||
|
function _storeEof() |
||||
|
{ |
||||
|
$record = 0x000A; // Record identifier |
||||
|
$length = 0x0000; // Number of bytes to follow |
||||
|
|
||||
|
$header = pack("vv", $record, $length); |
||||
|
$this->_append($header); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Writes Excel EOF record to indicate the end of a BIFF stream. |
||||
|
* |
||||
|
* @access private |
||||
|
*/ |
||||
|
public function writeEof() |
||||
|
{ |
||||
|
$record = 0x000A; // Record identifier |
||||
|
$length = 0x0000; // Number of bytes to follow |
||||
|
$header = pack("vv", $record, $length); |
||||
|
return $this->writeData($header); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In |
||||
|
* Excel 97 the limit is 8228 bytes. Records that are longer than these limits |
||||
|
* must be split up into CONTINUE blocks. |
||||
|
* |
||||
|
* This function takes a long BIFF record and inserts CONTINUE records as |
||||
|
* necessary. |
||||
|
* |
||||
|
* @param string $data The original binary data to be written |
||||
|
* @return string A very convenient string of continue blocks |
||||
|
* @access private |
||||
|
*/ |
||||
|
function _addContinue($data) |
||||
|
{ |
||||
|
$limit = $this->_limit; |
||||
|
$record = 0x003C; // Record identifier |
||||
|
|
||||
|
// The first 2080/8224 bytes remain intact. However, we have to change |
||||
|
// the length field of the record. |
||||
|
$tmp = substr($data, 0, 2) . pack("v", $limit) . substr($data, 4, $limit); |
||||
|
|
||||
|
$header = pack("vv", $record, $limit); // Headers for continue records |
||||
|
|
||||
|
// Retrieve chunks of 2080/8224 bytes +4 for the header. |
||||
|
$data_length = strlen($data); |
||||
|
for ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) { |
||||
|
$tmp .= $header; |
||||
|
$tmp .= substr($data, $i, $limit); |
||||
|
} |
||||
|
|
||||
|
// Retrieve the last chunk of data |
||||
|
$header = pack("vv", $record, strlen($data) - $i); |
||||
|
$tmp .= $header; |
||||
|
$tmp .= substr($data, $i, strlen($data) - $i); |
||||
|
|
||||
|
return $tmp; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
defined('IN_IA') or exit('Access Denied'); |
||||
|
|
||||
|
load()->web('common'); |
||||
|
load()->web('template'); |
||||
|
load()->func('file'); |
||||
|
load()->func('tpl'); |
||||
|
load()->model('cloud'); |
||||
|
load()->model('user'); |
||||
|
load()->model('permission'); |
||||
|
load()->model('attachment'); |
||||
|
load()->classs('oauth2/oauth2client'); |
||||
|
load()->model('switch'); |
||||
|
load()->model('system'); |
||||
|
|
||||
|
$_W['token'] = token(); |
||||
|
$session = json_decode(authcode($_GPC['__session']), true); |
||||
|
if (is_array($session)) { |
||||
|
$user = user_single(array('uid' => $session['uid'])); |
||||
|
if (is_array($user) && $session['hash'] === $user['hash']) { |
||||
|
$_W['uid'] = $user['uid']; |
||||
|
$_W['username'] = $user['username']; |
||||
|
$user['currentvisit'] = $user['lastvisit']; |
||||
|
$user['currentip'] = $user['lastip']; |
||||
|
$user['lastvisit'] = $session['lastvisit']; |
||||
|
$user['lastip'] = $session['lastip']; |
||||
|
$_W['user'] = $user; |
||||
|
$_W['isfounder'] = user_is_founder($_W['uid']); |
||||
|
$_W['isadmin'] = user_is_founder($_W['uid'], true); |
||||
|
} else { |
||||
|
isetcookie('__session', false, -100); |
||||
|
} |
||||
|
unset($user); |
||||
|
} |
||||
|
unset($session); |
||||
|
$_W['uniacid'] = intval(igetcookie('__uniacid')); |
||||
|
|
||||
|
if (!empty($_W['uid'])) { |
||||
|
$_W['highest_role'] = permission_account_user_role($_W['uid']); |
||||
|
$_W['role'] = permission_account_user_role($_W['uid'], $_W['uniacid']); |
||||
|
} |
||||
|
|
||||
|
$_W['template'] = 'default'; |
||||
|
$_W['attachurl'] = attachment_set_attach_url(); |
||||
@ -0,0 +1,391 @@ |
|||||
|
(function (factory) { |
||||
|
'use strict'; |
||||
|
if (typeof exports === 'object') { |
||||
|
// Node/CommonJS
|
||||
|
module.exports = factory( |
||||
|
typeof angular !== 'undefined' ? angular : require('angular'), |
||||
|
typeof Chart !== 'undefined' ? Chart : require('chart.js')); |
||||
|
} else if (typeof define === 'function' && define.amd) { |
||||
|
// AMD. Register as an anonymous module.
|
||||
|
define(['chart'], factory); |
||||
|
} else { |
||||
|
// Browser globals
|
||||
|
if (typeof angular === 'undefined') { |
||||
|
throw new Error('AngularJS framework needs to be included, see https://angularjs.org/'); |
||||
|
} else if (typeof Chart === 'undefined') { |
||||
|
throw new Error('Chart.js library needs to be included, see http://jtblin.github.io/angular-chart.js/'); |
||||
|
} |
||||
|
factory(angular, Chart); |
||||
|
} |
||||
|
}(function (Chart) { |
||||
|
'use strict'; |
||||
|
|
||||
|
Chart.defaults.global.multiTooltipTemplate = '<%if (datasetLabel){%><%=datasetLabel%>: <%}%><%= value %>'; |
||||
|
Chart.defaults.global.tooltips.mode = 'label'; |
||||
|
Chart.defaults.global.elements.line.borderWidth = 2; |
||||
|
Chart.defaults.global.elements.rectangle.borderWidth = 2; |
||||
|
Chart.defaults.global.legend.display = false; |
||||
|
Chart.defaults.global.colors = [ |
||||
|
'#97BBCD', // blue
|
||||
|
'#DCDCDC', // light grey
|
||||
|
'#F7464A', // red
|
||||
|
'#46BFBD', // green
|
||||
|
'#FDB45C', // yellow
|
||||
|
'#949FB1', // grey
|
||||
|
'#4D5360' // dark grey
|
||||
|
]; |
||||
|
|
||||
|
var useExcanvas = typeof window.G_vmlCanvasManager === 'object' && |
||||
|
window.G_vmlCanvasManager !== null && |
||||
|
typeof window.G_vmlCanvasManager.initElement === 'function'; |
||||
|
|
||||
|
if (useExcanvas) Chart.defaults.global.animation = false; |
||||
|
|
||||
|
return angular.module('chart.js', []) |
||||
|
.provider('ChartJs', ChartJsProvider) |
||||
|
.factory('ChartJsFactory', ['ChartJs', '$timeout', ChartJsFactory]) |
||||
|
.directive('chartBase', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory(); }]) |
||||
|
.directive('chartLine', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('line'); }]) |
||||
|
.directive('chartBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bar'); }]) |
||||
|
.directive('chartHorizontalBar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('horizontalBar'); }]) |
||||
|
.directive('chartRadar', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('radar'); }]) |
||||
|
.directive('chartDoughnut', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('doughnut'); }]) |
||||
|
.directive('chartPie', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('pie'); }]) |
||||
|
.directive('chartPolarArea', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('polarArea'); }]) |
||||
|
.directive('chartBubble', ['ChartJsFactory', function (ChartJsFactory) { return new ChartJsFactory('bubble'); }]) |
||||
|
.name; |
||||
|
|
||||
|
/** |
||||
|
* Wrapper for chart.js |
||||
|
* Allows configuring chart js using the provider |
||||
|
* |
||||
|
* angular.module('myModule', ['chart.js']).config(function(ChartJsProvider) { |
||||
|
* ChartJsProvider.setOptions({ responsive: false }); |
||||
|
* ChartJsProvider.setOptions('Line', { responsive: true }); |
||||
|
* }))) |
||||
|
*/ |
||||
|
function ChartJsProvider () { |
||||
|
var options = { responsive: true }; |
||||
|
var ChartJs = { |
||||
|
Chart: Chart, |
||||
|
getOptions: function (type) { |
||||
|
var typeOptions = type && options[type] || {}; |
||||
|
return angular.extend({}, options, typeOptions); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* Allow to set global options during configuration |
||||
|
*/ |
||||
|
this.setOptions = function (type, customOptions) { |
||||
|
// If no type was specified set option for the global object
|
||||
|
if (! customOptions) { |
||||
|
customOptions = type; |
||||
|
options = angular.merge(options, customOptions); |
||||
|
} else { |
||||
|
// Set options for the specific chart
|
||||
|
options[type] = angular.merge(options[type] || {}, customOptions); |
||||
|
} |
||||
|
|
||||
|
angular.merge(ChartJs.Chart.defaults, options); |
||||
|
}; |
||||
|
|
||||
|
this.$get = function () { |
||||
|
return ChartJs; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function ChartJsFactory (ChartJs, $timeout) { |
||||
|
return function chart (type) { |
||||
|
return { |
||||
|
restrict: 'CA', |
||||
|
scope: { |
||||
|
chartGetColor: '=?', |
||||
|
chartType: '=', |
||||
|
chartData: '=?', |
||||
|
chartLabels: '=?', |
||||
|
chartOptions: '=?', |
||||
|
chartSeries: '=?', |
||||
|
chartColors: '=?', |
||||
|
chartClick: '=?', |
||||
|
chartHover: '=?', |
||||
|
chartDatasetOverride: '=?' |
||||
|
}, |
||||
|
link: function (scope, elem/*, attrs */) { |
||||
|
if (useExcanvas) window.G_vmlCanvasManager.initElement(elem[0]); |
||||
|
|
||||
|
// Order of setting "watch" matter
|
||||
|
scope.$watch('chartData', watchData, true); |
||||
|
scope.$watch('chartSeries', watchOther, true); |
||||
|
scope.$watch('chartLabels', watchOther, true); |
||||
|
scope.$watch('chartOptions', watchOther, true); |
||||
|
scope.$watch('chartColors', watchOther, true); |
||||
|
scope.$watch('chartDatasetOverride', watchOther, true); |
||||
|
scope.$watch('chartType', watchType, false); |
||||
|
|
||||
|
scope.$on('$destroy', function () { |
||||
|
destroyChart(scope); |
||||
|
}); |
||||
|
|
||||
|
scope.$on('$resize', function () { |
||||
|
if (scope.chart) scope.chart.resize(); |
||||
|
}); |
||||
|
|
||||
|
function watchData (newVal, oldVal) { |
||||
|
if (! newVal || ! newVal.length || (Array.isArray(newVal[0]) && ! newVal[0].length)) { |
||||
|
destroyChart(scope); |
||||
|
return; |
||||
|
} |
||||
|
var chartType = type || scope.chartType; |
||||
|
if (! chartType) return; |
||||
|
|
||||
|
if (scope.chart && canUpdateChart(newVal, oldVal)) |
||||
|
return updateChart(newVal, scope); |
||||
|
|
||||
|
createChart(chartType, scope, elem); |
||||
|
} |
||||
|
|
||||
|
function watchOther (newVal, oldVal) { |
||||
|
if (isEmpty(newVal)) return; |
||||
|
if (angular.equals(newVal, oldVal)) return; |
||||
|
var chartType = type || scope.chartType; |
||||
|
if (! chartType) return; |
||||
|
|
||||
|
// chart.update() doesn't work for series and labels
|
||||
|
// so we have to re-create the chart entirely
|
||||
|
createChart(chartType, scope, elem); |
||||
|
} |
||||
|
|
||||
|
function watchType (newVal, oldVal) { |
||||
|
if (isEmpty(newVal)) return; |
||||
|
if (angular.equals(newVal, oldVal)) return; |
||||
|
createChart(newVal, scope, elem); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
function createChart (type, scope, elem) { |
||||
|
var options = getChartOptions(type, scope); |
||||
|
if (! hasData(scope) || ! canDisplay(type, scope, elem, options)) return; |
||||
|
|
||||
|
var cvs = elem[0]; |
||||
|
var ctx = cvs.getContext('2d'); |
||||
|
|
||||
|
scope.chartGetColor = getChartColorFn(scope); |
||||
|
var data = getChartData(type, scope); |
||||
|
// Destroy old chart if it exists to avoid ghost charts issue
|
||||
|
// https://github.com/jtblin/angular-chart.js/issues/187
|
||||
|
destroyChart(scope); |
||||
|
|
||||
|
scope.chart = new ChartJs.Chart(ctx, { |
||||
|
type: type, |
||||
|
data: data, |
||||
|
options: options |
||||
|
}); |
||||
|
scope.$emit('chart-create', scope.chart); |
||||
|
bindEvents(cvs, scope); |
||||
|
} |
||||
|
|
||||
|
function canUpdateChart (newVal, oldVal) { |
||||
|
if (newVal && oldVal && newVal.length && oldVal.length) { |
||||
|
return Array.isArray(newVal[0]) ? |
||||
|
newVal.length === oldVal.length && newVal.every(function (element, index) { |
||||
|
return element.length === oldVal[index].length; }) : |
||||
|
oldVal.reduce(sum, 0) > 0 ? newVal.length === oldVal.length : false; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
function sum (carry, val) { |
||||
|
return carry + val; |
||||
|
} |
||||
|
|
||||
|
function getEventHandler (scope, action, triggerOnlyOnChange) { |
||||
|
var lastState = { |
||||
|
point: void 0, |
||||
|
points: void 0 |
||||
|
}; |
||||
|
return function (evt) { |
||||
|
var atEvent = scope.chart.getElementAtEvent || scope.chart.getPointAtEvent; |
||||
|
var atEvents = scope.chart.getElementsAtEvent || scope.chart.getPointsAtEvent; |
||||
|
if (atEvents) { |
||||
|
var points = atEvents.call(scope.chart, evt); |
||||
|
var point = atEvent ? atEvent.call(scope.chart, evt)[0] : void 0; |
||||
|
|
||||
|
if (triggerOnlyOnChange === false || |
||||
|
(! angular.equals(lastState.points, points) && ! angular.equals(lastState.point, point)) |
||||
|
) { |
||||
|
lastState.point = point; |
||||
|
lastState.points = points; |
||||
|
scope[action](points, evt, point); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function getColors (type, scope) { |
||||
|
var colors = angular.copy(scope.chartColors || |
||||
|
ChartJs.getOptions(type).chartColors || |
||||
|
Chart.defaults.global.colors |
||||
|
); |
||||
|
var notEnoughColors = colors.length < scope.chartData.length; |
||||
|
while (colors.length < scope.chartData.length) { |
||||
|
colors.push(scope.chartGetColor()); |
||||
|
} |
||||
|
// mutate colors in this case as we don't want
|
||||
|
// the colors to change on each refresh
|
||||
|
if (notEnoughColors) scope.chartColors = colors; |
||||
|
return colors.map(convertColor); |
||||
|
} |
||||
|
|
||||
|
function convertColor (color) { |
||||
|
// Allows RGB and RGBA colors to be input as a string: e.g.: "rgb(159,204,0)", "rgba(159,204,0, 0.5)"
|
||||
|
if (typeof color === 'string' && color[0] === 'r') return getColor(rgbStringToRgb(color)); |
||||
|
// Allows hex colors to be input as a string.
|
||||
|
if (typeof color === 'string' && color[0] === '#') return getColor(hexToRgb(color.substr(1))); |
||||
|
// Allows colors to be input as an object, bypassing getColor() entirely
|
||||
|
if (typeof color === 'object' && color !== null) return color; |
||||
|
return getRandomColor(); |
||||
|
} |
||||
|
|
||||
|
function getRandomColor () { |
||||
|
var color = [getRandomInt(0, 255), getRandomInt(0, 255), getRandomInt(0, 255)]; |
||||
|
return getColor(color); |
||||
|
} |
||||
|
|
||||
|
function getColor (color) { |
||||
|
var alpha = color[3] || 1; |
||||
|
color = color.slice(0, 3); |
||||
|
return { |
||||
|
backgroundColor: rgba(color, 0.2), |
||||
|
pointBackgroundColor: rgba(color, alpha), |
||||
|
pointHoverBackgroundColor: rgba(color, 0.8), |
||||
|
borderColor: rgba(color, alpha), |
||||
|
pointBorderColor: '#fff', |
||||
|
pointHoverBorderColor: rgba(color, alpha) |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function getRandomInt (min, max) { |
||||
|
return Math.floor(Math.random() * (max - min + 1)) + min; |
||||
|
} |
||||
|
|
||||
|
function rgba (color, alpha) { |
||||
|
// rgba not supported by IE8
|
||||
|
return useExcanvas ? 'rgb(' + color.join(',') + ')' : 'rgba(' + color.concat(alpha).join(',') + ')'; |
||||
|
} |
||||
|
|
||||
|
// Credit: http://stackoverflow.com/a/11508164/1190235
|
||||
|
function hexToRgb (hex) { |
||||
|
var bigint = parseInt(hex, 16), |
||||
|
r = (bigint >> 16) & 255, |
||||
|
g = (bigint >> 8) & 255, |
||||
|
b = bigint & 255; |
||||
|
|
||||
|
return [r, g, b]; |
||||
|
} |
||||
|
|
||||
|
function rgbStringToRgb (color) { |
||||
|
var match = color.match(/^rgba?\(([\d,.]+)\)$/); |
||||
|
if (! match) throw new Error('Cannot parse rgb value'); |
||||
|
color = match[1].split(','); |
||||
|
return color.map(Number); |
||||
|
} |
||||
|
|
||||
|
function hasData (scope) { |
||||
|
return scope.chartData && scope.chartData.length; |
||||
|
} |
||||
|
|
||||
|
function getChartColorFn (scope) { |
||||
|
return typeof scope.chartGetColor === 'function' ? scope.chartGetColor : getRandomColor; |
||||
|
} |
||||
|
|
||||
|
function getChartData (type, scope) { |
||||
|
var colors = getColors(type, scope); |
||||
|
return Array.isArray(scope.chartData[0]) ? |
||||
|
getDataSets(scope.chartLabels, scope.chartData, scope.chartSeries || [], colors, scope.chartDatasetOverride) : |
||||
|
getData(scope.chartLabels, scope.chartData, colors, scope.chartDatasetOverride); |
||||
|
} |
||||
|
|
||||
|
function getDataSets (labels, data, series, colors, datasetOverride) { |
||||
|
return { |
||||
|
labels: labels, |
||||
|
datasets: data.map(function (item, i) { |
||||
|
var dataset = angular.extend({}, colors[i], { |
||||
|
label: series[i], |
||||
|
data: item |
||||
|
}); |
||||
|
if (datasetOverride && datasetOverride.length >= i) { |
||||
|
angular.merge(dataset, datasetOverride[i]); |
||||
|
} |
||||
|
return dataset; |
||||
|
}) |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
function getData (labels, data, colors, datasetOverride) { |
||||
|
var dataset = { |
||||
|
labels: labels, |
||||
|
datasets: [{ |
||||
|
data: data, |
||||
|
backgroundColor: colors.map(function (color) { |
||||
|
return color.pointBackgroundColor; |
||||
|
}), |
||||
|
hoverBackgroundColor: colors.map(function (color) { |
||||
|
return color.backgroundColor; |
||||
|
}) |
||||
|
}] |
||||
|
}; |
||||
|
if (datasetOverride) { |
||||
|
angular.merge(dataset.datasets[0], datasetOverride); |
||||
|
} |
||||
|
return dataset; |
||||
|
} |
||||
|
|
||||
|
function getChartOptions (type, scope) { |
||||
|
return angular.extend({}, ChartJs.getOptions(type), scope.chartOptions); |
||||
|
} |
||||
|
|
||||
|
function bindEvents (cvs, scope) { |
||||
|
cvs.onclick = scope.chartClick ? getEventHandler(scope, 'chartClick', false) : angular.noop; |
||||
|
cvs.onmousemove = scope.chartHover ? getEventHandler(scope, 'chartHover', true) : angular.noop; |
||||
|
} |
||||
|
|
||||
|
function updateChart (values, scope) { |
||||
|
if (Array.isArray(scope.chartData[0])) { |
||||
|
scope.chart.data.datasets.forEach(function (dataset, i) { |
||||
|
dataset.data = values[i]; |
||||
|
}); |
||||
|
} else { |
||||
|
scope.chart.data.datasets[0].data = values; |
||||
|
} |
||||
|
|
||||
|
scope.chart.update(); |
||||
|
scope.$emit('chart-update', scope.chart); |
||||
|
} |
||||
|
|
||||
|
function isEmpty (value) { |
||||
|
return ! value || |
||||
|
(Array.isArray(value) && ! value.length) || |
||||
|
(typeof value === 'object' && ! Object.keys(value).length); |
||||
|
} |
||||
|
|
||||
|
function canDisplay (type, scope, elem, options) { |
||||
|
// TODO: check parent?
|
||||
|
if (options.responsive && elem[0].clientHeight === 0) { |
||||
|
$timeout(function () { |
||||
|
createChart(type, scope, elem); |
||||
|
}, 50, false); |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
function destroyChart(scope) { |
||||
|
if(! scope.chart) return; |
||||
|
scope.chart.destroy(); |
||||
|
scope.$emit('chart-destroy', scope.chart); |
||||
|
} |
||||
|
} |
||||
|
})); |
||||
@ -0,0 +1,46 @@ |
|||||
|
/******************************************************************************* |
||||
|
* KindEditor - WYSIWYG HTML Editor for Internet |
||||
|
* Copyright (C) 2006-2011 kindsoft.net |
||||
|
* |
||||
|
* @author Roddy <luolonghao@gmail.com> |
||||
|
* @site http://www.kindsoft.net/
|
||||
|
* @licence http://www.kindsoft.net/license.php
|
||||
|
*******************************************************************************/ |
||||
|
|
||||
|
KindEditor.plugin('anchor', function(K) { |
||||
|
var self = this, name = 'anchor', lang = self.lang(name + '.'); |
||||
|
self.plugin.anchor = { |
||||
|
edit : function() { |
||||
|
var html = ['<div style="padding:20px;">', |
||||
|
'<div class="ke-dialog-row">', |
||||
|
'<label for="keName">' + lang.name + '</label>', |
||||
|
'<input class="ke-input-text" type="text" id="keName" name="name" value="" style="width:100px;" />', |
||||
|
'</div>', |
||||
|
'</div>'].join(''); |
||||
|
var dialog = self.createDialog({ |
||||
|
name : name, |
||||
|
width : 300, |
||||
|
title : self.lang(name), |
||||
|
body : html, |
||||
|
yesBtn : { |
||||
|
name : self.lang('yes'), |
||||
|
click : function(e) { |
||||
|
self.insertHtml('<a name="' + nameBox.val() + '">').hideDialog().focus(); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
var div = dialog.div, |
||||
|
nameBox = K('input[name="name"]', div); |
||||
|
var img = self.plugin.getSelectedAnchor(); |
||||
|
if (img) { |
||||
|
nameBox.val(unescape(img.attr('data-ke-name'))); |
||||
|
} |
||||
|
nameBox[0].focus(); |
||||
|
nameBox[0].select(); |
||||
|
}, |
||||
|
'delete' : function() { |
||||
|
self.plugin.getSelectedAnchor().remove(); |
||||
|
} |
||||
|
}; |
||||
|
self.clickToolbar(name, self.plugin.anchor.edit); |
||||
|
}); |
||||
@ -0,0 +1,54 @@ |
|||||
|
/******************************************************************************* |
||||
|
* KindEditor - WYSIWYG HTML Editor for Internet |
||||
|
* Copyright (C) 2006-2011 kindsoft.net |
||||
|
* |
||||
|
* @author Roddy <luolonghao@gmail.com> |
||||
|
* @site http://www.kindsoft.net/
|
||||
|
* @licence http://www.kindsoft.net/license.php
|
||||
|
*******************************************************************************/ |
||||
|
|
||||
|
KindEditor.plugin('autoheight', function(K) { |
||||
|
var self = this; |
||||
|
|
||||
|
if (!self.autoHeightMode) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var minHeight; |
||||
|
|
||||
|
function hideScroll() { |
||||
|
var edit = self.edit; |
||||
|
var body = edit.doc.body; |
||||
|
edit.iframe[0].scroll = 'no'; |
||||
|
body.style.overflowY = 'hidden'; |
||||
|
} |
||||
|
|
||||
|
function resetHeight() { |
||||
|
var edit = self.edit; |
||||
|
var body = edit.doc.body; |
||||
|
edit.iframe.height(minHeight); |
||||
|
self.resize(null, Math.max((K.IE ? body.scrollHeight : body.offsetHeight) + 76, minHeight)); |
||||
|
} |
||||
|
|
||||
|
function init() { |
||||
|
minHeight = K.removeUnit(self.height); |
||||
|
|
||||
|
self.edit.afterChange(resetHeight); |
||||
|
hideScroll(); |
||||
|
resetHeight(); |
||||
|
} |
||||
|
|
||||
|
if (self.isCreated) { |
||||
|
init(); |
||||
|
} else { |
||||
|
self.afterCreate(init); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
/* |
||||
|
* 如何实现真正的自动高度? |
||||
|
* 修改编辑器高度之后,再次获取body内容高度时,最小值只会是当前iframe的设置高度,这样就导致高度只增不减。 |
||||
|
* 所以每次获取body内容高度之前,先将iframe的高度重置为最小高度,这样就能获取body的实际高度。 |
||||
|
* 由此就实现了真正的自动高度 |
||||
|
* 测试:chrome、firefox、IE9、IE8 |
||||
|
* */ |
||||
@ -0,0 +1,93 @@ |
|||||
|
/******************************************************************************* |
||||
|
* KindEditor - WYSIWYG HTML Editor for Internet |
||||
|
* Copyright (C) 2006-2011 kindsoft.net |
||||
|
* |
||||
|
* @author Roddy <luolonghao@gmail.com> |
||||
|
* @site http://www.kindsoft.net/
|
||||
|
* @licence http://www.kindsoft.net/license.php
|
||||
|
*******************************************************************************/ |
||||
|
|
||||
|
// Baidu Maps: http://dev.baidu.com/wiki/map/index.php?title=%E9%A6%96%E9%A1%B5
|
||||
|
|
||||
|
KindEditor.plugin('baidumap', function(K) { |
||||
|
var self = this, name = 'baidumap', lang = self.lang(name + '.'); |
||||
|
var mapWidth = K.undef(self.mapWidth, 558); |
||||
|
var mapHeight = K.undef(self.mapHeight, 360); |
||||
|
self.clickToolbar(name, function() { |
||||
|
var html = ['<div style="padding:10px 20px;">', |
||||
|
'<div class="ke-header">', |
||||
|
// left start
|
||||
|
'<div class="ke-left">', |
||||
|
lang.address + ' <input id="kindeditor_plugin_map_address" name="address" class="ke-input-text" value="" style="width:200px;" /> ', |
||||
|
'<span class="ke-button-common ke-button-outer">', |
||||
|
'<input type="button" name="searchBtn" class="ke-button-common ke-button" value="' + lang.search + '" />', |
||||
|
'</span>', |
||||
|
'</div>', |
||||
|
// right start
|
||||
|
'<div class="ke-right">', |
||||
|
'<input type="checkbox" id="keInsertDynamicMap" name="insertDynamicMap" value="1" /> <label for="keInsertDynamicMap">' + lang.insertDynamicMap + '</label>', |
||||
|
'</div>', |
||||
|
'<div class="ke-clearfix"></div>', |
||||
|
'</div>', |
||||
|
'<div class="ke-map" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></div>', |
||||
|
'</div>'].join(''); |
||||
|
var dialog = self.createDialog({ |
||||
|
name : name, |
||||
|
width : mapWidth + 42, |
||||
|
title : self.lang(name), |
||||
|
body : html, |
||||
|
yesBtn : { |
||||
|
name : self.lang('yes'), |
||||
|
click : function(e) { |
||||
|
var map = win.map; |
||||
|
var centerObj = map.getCenter(); |
||||
|
var center = centerObj.lng + ',' + centerObj.lat; |
||||
|
var zoom = map.getZoom(); |
||||
|
var url = [checkbox[0].checked ? self.pluginsPath + 'baidumap/index.html' : 'http://api.map.baidu.com/staticimage', |
||||
|
'?center=' + encodeURIComponent(center), |
||||
|
'&zoom=' + encodeURIComponent(zoom), |
||||
|
'&width=' + mapWidth, |
||||
|
'&height=' + mapHeight, |
||||
|
'&markers=' + encodeURIComponent(center), |
||||
|
'&markerStyles=' + encodeURIComponent('l,A')].join(''); |
||||
|
if (checkbox[0].checked) { |
||||
|
self.insertHtml('<iframe src="' + url + '" frameborder="0" style="width:' + (mapWidth + 2) + 'px;height:' + (mapHeight + 2) + 'px;"></iframe>'); |
||||
|
} else { |
||||
|
self.exec('insertimage', url); |
||||
|
} |
||||
|
self.hideDialog().focus(); |
||||
|
} |
||||
|
}, |
||||
|
beforeRemove : function() { |
||||
|
searchBtn.remove(); |
||||
|
if (doc) { |
||||
|
doc.write(''); |
||||
|
} |
||||
|
iframe.remove(); |
||||
|
} |
||||
|
}); |
||||
|
var div = dialog.div, |
||||
|
addressBox = K('[name="address"]', div), |
||||
|
searchBtn = K('[name="searchBtn"]', div), |
||||
|
checkbox = K('[name="insertDynamicMap"]', dialog.div), |
||||
|
win, doc; |
||||
|
var iframe = K('<iframe class="ke-textarea" frameborder="0" src="' + self.pluginsPath + 'baidumap/map.html" style="width:' + mapWidth + 'px;height:' + mapHeight + 'px;"></iframe>'); |
||||
|
function ready() { |
||||
|
win = iframe[0].contentWindow; |
||||
|
doc = K.iframeDoc(iframe); |
||||
|
} |
||||
|
iframe.bind('load', function() { |
||||
|
iframe.unbind('load'); |
||||
|
if (K.IE) { |
||||
|
ready(); |
||||
|
} else { |
||||
|
setTimeout(ready, 0); |
||||
|
} |
||||
|
}); |
||||
|
K('.ke-map', div).replaceWith(iframe); |
||||
|
// search map
|
||||
|
searchBtn.click(function() { |
||||
|
win.search(addressBox.val()); |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1015 B |
|
After Width: | Height: | Size: 1003 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 996 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1012 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1008 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 999 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1022 B |
|
After Width: | Height: | Size: 1013 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 956 B |
|
After Width: | Height: | Size: 1022 B |
|
After Width: | Height: | Size: 972 B |
|
After Width: | Height: | Size: 980 B |
|
After Width: | Height: | Size: 945 B |
|
After Width: | Height: | Size: 936 B |
|
After Width: | Height: | Size: 1012 B |
|
After Width: | Height: | Size: 968 B |
|
After Width: | Height: | Size: 654 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 639 B |
|
After Width: | Height: | Size: 636 B |
|
After Width: | Height: | Size: 625 B |
|
After Width: | Height: | Size: 371 B |
|
After Width: | Height: | Size: 43 B |
|
After Width: | Height: | Size: 788 B |
|
After Width: | Height: | Size: 53 B |
@ -0,0 +1,40 @@ |
|||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
||||
|
"http://www.w3.org/TR/html4/loose.dtd"> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
||||
|
<title></title> |
||||
|
<style type="text/css"> |
||||
|
*{color: #838383;margin: 0;padding: 0} |
||||
|
html,body {font-size: 12px;overflow: hidden; } |
||||
|
.content{padding:5px 0 0 15px;} |
||||
|
input{width:210px;height:21px;line-height:21px;margin-left: 4px;} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div class="content"> |
||||
|
<span><var id="lang_input_anchorName"></var></span><input id="anchorName" value="" /> |
||||
|
</div> |
||||
|
<script type="text/javascript" src="../internal.js"></script> |
||||
|
<script type="text/javascript"> |
||||
|
var anchorInput = $G('anchorName'), |
||||
|
node = editor.selection.getRange().getClosedNode(); |
||||
|
if(node && node.tagName == 'IMG' && (node = node.getAttribute('anchorname'))){ |
||||
|
anchorInput.value = node; |
||||
|
} |
||||
|
anchorInput.onkeydown = function(evt){ |
||||
|
evt = evt || window.event; |
||||
|
if(evt.keyCode == 13){ |
||||
|
editor.execCommand('anchor', anchorInput.value); |
||||
|
dialog.close(); |
||||
|
domUtils.preventDefault(evt) |
||||
|
} |
||||
|
}; |
||||
|
dialog.onok = function (){ |
||||
|
editor.execCommand('anchor', anchorInput.value); |
||||
|
dialog.close(); |
||||
|
}; |
||||
|
$focus(anchorInput); |
||||
|
</script> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,60 @@ |
|||||
|
<!doctype html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<title>ueditor图片对话框</title> |
||||
|
<script type="text/javascript" src="../internal.js"></script> |
||||
|
|
||||
|
<!-- jquery --> |
||||
|
<script type="text/javascript" src="../../third-party/jquery-1.10.2.min.js"></script> |
||||
|
|
||||
|
<!-- webuploader --> |
||||
|
<script src="../../third-party/webuploader/webuploader.min.js"></script> |
||||
|
<link rel="stylesheet" type="text/css" href="../../third-party/webuploader/webuploader.css"> |
||||
|
|
||||
|
<!-- attachment dialog --> |
||||
|
<link rel="stylesheet" href="attachment.css" type="text/css" /> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<div class="wrapper"> |
||||
|
<div id="tabhead" class="tabhead"> |
||||
|
<span class="tab focus" data-content-id="upload"><var id="lang_tab_upload"></var></span> |
||||
|
<span class="tab" data-content-id="online"><var id="lang_tab_online"></var></span> |
||||
|
</div> |
||||
|
<div id="tabbody" class="tabbody"> |
||||
|
<!-- 上传图片 --> |
||||
|
<div id="upload" class="panel focus"> |
||||
|
<div id="queueList" class="queueList"> |
||||
|
<div class="statusBar element-invisible"> |
||||
|
<div class="progress"> |
||||
|
<span class="text">0%</span> |
||||
|
<span class="percentage"></span> |
||||
|
</div><div class="info"></div> |
||||
|
<div class="btns"> |
||||
|
<div id="filePickerBtn"></div> |
||||
|
<div class="uploadBtn"><var id="lang_start_upload"></var></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="dndArea" class="placeholder"> |
||||
|
<div class="filePickerContainer"> |
||||
|
<div id="filePickerReady"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<ul class="filelist element-invisible"> |
||||
|
<li id="filePickerBlock" class="filePickerBlock"></li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 在线图片 --> |
||||
|
<div id="online" class="panel"> |
||||
|
<div id="fileList"><var id="lang_imgLoading"></var></div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<script type="text/javascript" src="attachment.js"></script> |
||||
|
|
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,754 @@ |
|||||
|
/** |
||||
|
* User: Jinqn |
||||
|
* Date: 14-04-08 |
||||
|
* Time: 下午16:34 |
||||
|
* 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片 |
||||
|
*/ |
||||
|
|
||||
|
(function () { |
||||
|
|
||||
|
var uploadFile, |
||||
|
onlineFile; |
||||
|
|
||||
|
window.onload = function () { |
||||
|
initTabs(); |
||||
|
initButtons(); |
||||
|
}; |
||||
|
|
||||
|
/* 初始化tab标签 */ |
||||
|
function initTabs() { |
||||
|
var tabs = $G('tabhead').children; |
||||
|
for (var i = 0; i < tabs.length; i++) { |
||||
|
domUtils.on(tabs[i], "click", function (e) { |
||||
|
var target = e.target || e.srcElement; |
||||
|
setTabFocus(target.getAttribute('data-content-id')); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
setTabFocus('upload'); |
||||
|
} |
||||
|
|
||||
|
/* 初始化tabbody */ |
||||
|
function setTabFocus(id) { |
||||
|
if(!id) return; |
||||
|
var i, bodyId, tabs = $G('tabhead').children; |
||||
|
for (i = 0; i < tabs.length; i++) { |
||||
|
bodyId = tabs[i].getAttribute('data-content-id') |
||||
|
if (bodyId == id) { |
||||
|
domUtils.addClass(tabs[i], 'focus'); |
||||
|
domUtils.addClass($G(bodyId), 'focus'); |
||||
|
} else { |
||||
|
domUtils.removeClasses(tabs[i], 'focus'); |
||||
|
domUtils.removeClasses($G(bodyId), 'focus'); |
||||
|
} |
||||
|
} |
||||
|
switch (id) { |
||||
|
case 'upload': |
||||
|
uploadFile = uploadFile || new UploadFile('queueList'); |
||||
|
break; |
||||
|
case 'online': |
||||
|
onlineFile = onlineFile || new OnlineFile('fileList'); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 初始化onok事件 */ |
||||
|
function initButtons() { |
||||
|
|
||||
|
dialog.onok = function () { |
||||
|
var list = [], id, tabs = $G('tabhead').children; |
||||
|
for (var i = 0; i < tabs.length; i++) { |
||||
|
if (domUtils.hasClass(tabs[i], 'focus')) { |
||||
|
id = tabs[i].getAttribute('data-content-id'); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
switch (id) { |
||||
|
case 'upload': |
||||
|
list = uploadFile.getInsertList(); |
||||
|
var count = uploadFile.getQueueCount(); |
||||
|
if (count) { |
||||
|
$('.info', '#queueList').html('<span style="color:red;">' + '还有2个未上传文件'.replace(/[\d]/, count) + '</span>'); |
||||
|
return false; |
||||
|
} |
||||
|
break; |
||||
|
case 'online': |
||||
|
list = onlineFile.getInsertList(); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
editor.execCommand('insertfile', list); |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* 上传附件 */ |
||||
|
function UploadFile(target) { |
||||
|
this.$wrap = target.constructor == String ? $('#' + target) : $(target); |
||||
|
this.init(); |
||||
|
} |
||||
|
UploadFile.prototype = { |
||||
|
init: function () { |
||||
|
this.fileList = []; |
||||
|
this.initContainer(); |
||||
|
this.initUploader(); |
||||
|
}, |
||||
|
initContainer: function () { |
||||
|
this.$queue = this.$wrap.find('.filelist'); |
||||
|
}, |
||||
|
/* 初始化容器 */ |
||||
|
initUploader: function () { |
||||
|
var _this = this, |
||||
|
$ = jQuery, // just in case. Make sure it's not an other libaray.
|
||||
|
$wrap = _this.$wrap, |
||||
|
// 图片容器
|
||||
|
$queue = $wrap.find('.filelist'), |
||||
|
// 状态栏,包括进度和控制按钮
|
||||
|
$statusBar = $wrap.find('.statusBar'), |
||||
|
// 文件总体选择信息。
|
||||
|
$info = $statusBar.find('.info'), |
||||
|
// 上传按钮
|
||||
|
$upload = $wrap.find('.uploadBtn'), |
||||
|
// 上传按钮
|
||||
|
$filePickerBtn = $wrap.find('.filePickerBtn'), |
||||
|
// 上传按钮
|
||||
|
$filePickerBlock = $wrap.find('.filePickerBlock'), |
||||
|
// 没选择文件之前的内容。
|
||||
|
$placeHolder = $wrap.find('.placeholder'), |
||||
|
// 总体进度条
|
||||
|
$progress = $statusBar.find('.progress').hide(), |
||||
|
// 添加的文件数量
|
||||
|
fileCount = 0, |
||||
|
// 添加的文件总大小
|
||||
|
fileSize = 0, |
||||
|
// 优化retina, 在retina下这个值是2
|
||||
|
ratio = window.devicePixelRatio || 1, |
||||
|
// 缩略图大小
|
||||
|
thumbnailWidth = 113 * ratio, |
||||
|
thumbnailHeight = 113 * ratio, |
||||
|
// 可能有pedding, ready, uploading, confirm, done.
|
||||
|
state = '', |
||||
|
// 所有文件的进度信息,key为file id
|
||||
|
percentages = {}, |
||||
|
supportTransition = (function () { |
||||
|
var s = document.createElement('p').style, |
||||
|
r = 'transition' in s || |
||||
|
'WebkitTransition' in s || |
||||
|
'MozTransition' in s || |
||||
|
'msTransition' in s || |
||||
|
'OTransition' in s; |
||||
|
s = null; |
||||
|
return r; |
||||
|
})(), |
||||
|
// WebUploader实例
|
||||
|
uploader, |
||||
|
actionUrl = editor.getActionUrl(editor.getOpt('fileActionName')), |
||||
|
fileMaxSize = editor.getOpt('fileMaxSize'), |
||||
|
acceptExtensions = (editor.getOpt('fileAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, '');; |
||||
|
|
||||
|
if (!WebUploader.Uploader.support()) { |
||||
|
$('#filePickerReady').after($('<div>').html(lang.errorNotSupport)).hide(); |
||||
|
return; |
||||
|
} else if (!editor.getOpt('fileActionName')) { |
||||
|
$('#filePickerReady').after($('<div>').html(lang.errorLoadConfig)).hide(); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
uploader = _this.uploader = WebUploader.create({ |
||||
|
pick: { |
||||
|
id: '#filePickerReady', |
||||
|
label: lang.uploadSelectFile |
||||
|
}, |
||||
|
swf: '../../third-party/webuploader/Uploader.swf', |
||||
|
server: actionUrl, |
||||
|
fileVal: editor.getOpt('fileFieldName'), |
||||
|
duplicate: true, |
||||
|
fileSingleSizeLimit: fileMaxSize, |
||||
|
compress: false |
||||
|
}); |
||||
|
uploader.addButton({ |
||||
|
id: '#filePickerBlock' |
||||
|
}); |
||||
|
uploader.addButton({ |
||||
|
id: '#filePickerBtn', |
||||
|
label: lang.uploadAddFile |
||||
|
}); |
||||
|
|
||||
|
setState('pedding'); |
||||
|
|
||||
|
// 当有文件添加进来时执行,负责view的创建
|
||||
|
function addFile(file) { |
||||
|
var $li = $('<li id="' + file.id + '">' + |
||||
|
'<p class="title">' + file.name + '</p>' + |
||||
|
'<p class="imgWrap"></p>' + |
||||
|
'<p class="progress"><span></span></p>' + |
||||
|
'</li>'), |
||||
|
|
||||
|
$btns = $('<div class="file-panel">' + |
||||
|
'<span class="cancel">' + lang.uploadDelete + '</span>' + |
||||
|
'<span class="rotateRight">' + lang.uploadTurnRight + '</span>' + |
||||
|
'<span class="rotateLeft">' + lang.uploadTurnLeft + '</span></div>').appendTo($li), |
||||
|
$prgress = $li.find('p.progress span'), |
||||
|
$wrap = $li.find('p.imgWrap'), |
||||
|
$info = $('<p class="error"></p>').hide().appendTo($li), |
||||
|
|
||||
|
showError = function (code) { |
||||
|
switch (code) { |
||||
|
case 'exceed_size': |
||||
|
text = lang.errorExceedSize; |
||||
|
break; |
||||
|
case 'interrupt': |
||||
|
text = lang.errorInterrupt; |
||||
|
break; |
||||
|
case 'http': |
||||
|
text = lang.errorHttp; |
||||
|
break; |
||||
|
case 'not_allow_type': |
||||
|
text = lang.errorFileType; |
||||
|
break; |
||||
|
default: |
||||
|
text = lang.errorUploadRetry; |
||||
|
break; |
||||
|
} |
||||
|
$info.text(text).show(); |
||||
|
}; |
||||
|
|
||||
|
if (file.getStatus() === 'invalid') { |
||||
|
showError(file.statusText); |
||||
|
} else { |
||||
|
$wrap.text(lang.uploadPreview); |
||||
|
if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) { |
||||
|
$wrap.empty().addClass('notimage').append('<i class="file-preview file-type-' + file.ext.toLowerCase() + '"></i>' + |
||||
|
'<span class="file-title" title="' + file.name + '">' + file.name + '</span>'); |
||||
|
} else { |
||||
|
if (browser.ie && browser.version <= 7) { |
||||
|
$wrap.text(lang.uploadNoPreview); |
||||
|
} else { |
||||
|
uploader.makeThumb(file, function (error, src) { |
||||
|
if (error || !src) { |
||||
|
$wrap.text(lang.uploadNoPreview); |
||||
|
} else { |
||||
|
var $img = $('<img src="' + src + '">'); |
||||
|
$wrap.empty().append($img); |
||||
|
$img.on('error', function () { |
||||
|
$wrap.text(lang.uploadNoPreview); |
||||
|
}); |
||||
|
} |
||||
|
}, thumbnailWidth, thumbnailHeight); |
||||
|
} |
||||
|
} |
||||
|
percentages[ file.id ] = [ file.size, 0 ]; |
||||
|
file.rotation = 0; |
||||
|
|
||||
|
/* 检查文件格式 */ |
||||
|
if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) { |
||||
|
showError('not_allow_type'); |
||||
|
uploader.removeFile(file); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
file.on('statuschange', function (cur, prev) { |
||||
|
if (prev === 'progress') { |
||||
|
$prgress.hide().width(0); |
||||
|
} else if (prev === 'queued') { |
||||
|
$li.off('mouseenter mouseleave'); |
||||
|
$btns.remove(); |
||||
|
} |
||||
|
// 成功
|
||||
|
if (cur === 'error' || cur === 'invalid') { |
||||
|
showError(file.statusText); |
||||
|
percentages[ file.id ][ 1 ] = 1; |
||||
|
} else if (cur === 'interrupt') { |
||||
|
showError('interrupt'); |
||||
|
} else if (cur === 'queued') { |
||||
|
percentages[ file.id ][ 1 ] = 0; |
||||
|
} else if (cur === 'progress') { |
||||
|
$info.hide(); |
||||
|
$prgress.css('display', 'block'); |
||||
|
} else if (cur === 'complete') { |
||||
|
} |
||||
|
|
||||
|
$li.removeClass('state-' + prev).addClass('state-' + cur); |
||||
|
}); |
||||
|
|
||||
|
$li.on('mouseenter', function () { |
||||
|
$btns.stop().animate({height: 30}); |
||||
|
}); |
||||
|
$li.on('mouseleave', function () { |
||||
|
$btns.stop().animate({height: 0}); |
||||
|
}); |
||||
|
|
||||
|
$btns.on('click', 'span', function () { |
||||
|
var index = $(this).index(), |
||||
|
deg; |
||||
|
|
||||
|
switch (index) { |
||||
|
case 0: |
||||
|
uploader.removeFile(file); |
||||
|
return; |
||||
|
case 1: |
||||
|
file.rotation += 90; |
||||
|
break; |
||||
|
case 2: |
||||
|
file.rotation -= 90; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (supportTransition) { |
||||
|
deg = 'rotate(' + file.rotation + 'deg)'; |
||||
|
$wrap.css({ |
||||
|
'-webkit-transform': deg, |
||||
|
'-mos-transform': deg, |
||||
|
'-o-transform': deg, |
||||
|
'transform': deg |
||||
|
}); |
||||
|
} else { |
||||
|
$wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')'); |
||||
|
} |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
$li.insertBefore($filePickerBlock); |
||||
|
} |
||||
|
|
||||
|
// 负责view的销毁
|
||||
|
function removeFile(file) { |
||||
|
var $li = $('#' + file.id); |
||||
|
delete percentages[ file.id ]; |
||||
|
updateTotalProgress(); |
||||
|
$li.off().find('.file-panel').off().end().remove(); |
||||
|
} |
||||
|
|
||||
|
function updateTotalProgress() { |
||||
|
var loaded = 0, |
||||
|
total = 0, |
||||
|
spans = $progress.children(), |
||||
|
percent; |
||||
|
|
||||
|
$.each(percentages, function (k, v) { |
||||
|
total += v[ 0 ]; |
||||
|
loaded += v[ 0 ] * v[ 1 ]; |
||||
|
}); |
||||
|
|
||||
|
percent = total ? loaded / total : 0; |
||||
|
|
||||
|
spans.eq(0).text(Math.round(percent * 100) + '%'); |
||||
|
spans.eq(1).css('width', Math.round(percent * 100) + '%'); |
||||
|
updateStatus(); |
||||
|
} |
||||
|
|
||||
|
function setState(val, files) { |
||||
|
|
||||
|
if (val != state) { |
||||
|
|
||||
|
var stats = uploader.getStats(); |
||||
|
|
||||
|
$upload.removeClass('state-' + state); |
||||
|
$upload.addClass('state-' + val); |
||||
|
|
||||
|
switch (val) { |
||||
|
|
||||
|
/* 未选择文件 */ |
||||
|
case 'pedding': |
||||
|
$queue.addClass('element-invisible'); |
||||
|
$statusBar.addClass('element-invisible'); |
||||
|
$placeHolder.removeClass('element-invisible'); |
||||
|
$progress.hide(); $info.hide(); |
||||
|
uploader.refresh(); |
||||
|
break; |
||||
|
|
||||
|
/* 可以开始上传 */ |
||||
|
case 'ready': |
||||
|
$placeHolder.addClass('element-invisible'); |
||||
|
$queue.removeClass('element-invisible'); |
||||
|
$statusBar.removeClass('element-invisible'); |
||||
|
$progress.hide(); $info.show(); |
||||
|
$upload.text(lang.uploadStart); |
||||
|
uploader.refresh(); |
||||
|
break; |
||||
|
|
||||
|
/* 上传中 */ |
||||
|
case 'uploading': |
||||
|
$progress.show(); $info.hide(); |
||||
|
$upload.text(lang.uploadPause); |
||||
|
break; |
||||
|
|
||||
|
/* 暂停上传 */ |
||||
|
case 'paused': |
||||
|
$progress.show(); $info.hide(); |
||||
|
$upload.text(lang.uploadContinue); |
||||
|
break; |
||||
|
|
||||
|
case 'confirm': |
||||
|
$progress.show(); $info.hide(); |
||||
|
$upload.text(lang.uploadStart); |
||||
|
|
||||
|
stats = uploader.getStats(); |
||||
|
if (stats.successNum && !stats.uploadFailNum) { |
||||
|
setState('finish'); |
||||
|
return; |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case 'finish': |
||||
|
$progress.hide(); $info.show(); |
||||
|
if (stats.uploadFailNum) { |
||||
|
$upload.text(lang.uploadRetry); |
||||
|
} else { |
||||
|
$upload.text(lang.uploadStart); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
state = val; |
||||
|
updateStatus(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
if (!_this.getQueueCount()) { |
||||
|
$upload.addClass('disabled') |
||||
|
} else { |
||||
|
$upload.removeClass('disabled') |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
function updateStatus() { |
||||
|
var text = '', stats; |
||||
|
|
||||
|
if (state === 'ready') { |
||||
|
text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize)); |
||||
|
} else if (state === 'confirm') { |
||||
|
stats = uploader.getStats(); |
||||
|
if (stats.uploadFailNum) { |
||||
|
text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum); |
||||
|
} |
||||
|
} else { |
||||
|
stats = uploader.getStats(); |
||||
|
text = lang.updateStatusFinish.replace('_', fileCount). |
||||
|
replace('_KB', WebUploader.formatSize(fileSize)). |
||||
|
replace('_', stats.successNum); |
||||
|
|
||||
|
if (stats.uploadFailNum) { |
||||
|
text += lang.updateStatusError.replace('_', stats.uploadFailNum); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$info.html(text); |
||||
|
} |
||||
|
|
||||
|
uploader.on('fileQueued', function (file) { |
||||
|
fileCount++; |
||||
|
fileSize += file.size; |
||||
|
|
||||
|
if (fileCount === 1) { |
||||
|
$placeHolder.addClass('element-invisible'); |
||||
|
$statusBar.show(); |
||||
|
} |
||||
|
|
||||
|
addFile(file); |
||||
|
}); |
||||
|
|
||||
|
uploader.on('fileDequeued', function (file) { |
||||
|
fileCount--; |
||||
|
fileSize -= file.size; |
||||
|
|
||||
|
removeFile(file); |
||||
|
updateTotalProgress(); |
||||
|
}); |
||||
|
|
||||
|
uploader.on('filesQueued', function (file) { |
||||
|
if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) { |
||||
|
setState('ready'); |
||||
|
} |
||||
|
updateTotalProgress(); |
||||
|
}); |
||||
|
|
||||
|
uploader.on('all', function (type, files) { |
||||
|
switch (type) { |
||||
|
case 'uploadFinished': |
||||
|
setState('confirm', files); |
||||
|
break; |
||||
|
case 'startUpload': |
||||
|
/* 添加额外的GET参数 */ |
||||
|
var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '', |
||||
|
url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params); |
||||
|
uploader.option('server', url); |
||||
|
setState('uploading', files); |
||||
|
break; |
||||
|
case 'stopUpload': |
||||
|
setState('paused', files); |
||||
|
break; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
uploader.on('uploadBeforeSend', function (file, data, header) { |
||||
|
//这里可以通过data对象添加POST参数
|
||||
|
header['X_Requested_With'] = 'XMLHttpRequest'; |
||||
|
}); |
||||
|
|
||||
|
uploader.on('uploadProgress', function (file, percentage) { |
||||
|
var $li = $('#' + file.id), |
||||
|
$percent = $li.find('.progress span'); |
||||
|
|
||||
|
$percent.css('width', percentage * 100 + '%'); |
||||
|
percentages[ file.id ][ 1 ] = percentage; |
||||
|
updateTotalProgress(); |
||||
|
}); |
||||
|
|
||||
|
uploader.on('uploadSuccess', function (file, ret) { |
||||
|
var $file = $('#' + file.id); |
||||
|
try { |
||||
|
var responseText = (ret._raw || ret), |
||||
|
json = utils.str2json(responseText); |
||||
|
if (json.state == 'SUCCESS') { |
||||
|
_this.fileList.push(json); |
||||
|
$file.append('<span class="success"></span>'); |
||||
|
} else { |
||||
|
$file.find('.error').text(json.state).show(); |
||||
|
} |
||||
|
} catch (e) { |
||||
|
$file.find('.error').text(lang.errorServerUpload).show(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
uploader.on('uploadError', function (file, code) { |
||||
|
}); |
||||
|
uploader.on('error', function (code, file) { |
||||
|
if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') { |
||||
|
addFile(file); |
||||
|
} |
||||
|
}); |
||||
|
uploader.on('uploadComplete', function (file, ret) { |
||||
|
}); |
||||
|
|
||||
|
$upload.on('click', function () { |
||||
|
if ($(this).hasClass('disabled')) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (state === 'ready') { |
||||
|
uploader.upload(); |
||||
|
} else if (state === 'paused') { |
||||
|
uploader.upload(); |
||||
|
} else if (state === 'uploading') { |
||||
|
uploader.stop(); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
$upload.addClass('state-' + state); |
||||
|
updateTotalProgress(); |
||||
|
}, |
||||
|
getQueueCount: function () { |
||||
|
var file, i, status, readyFile = 0, files = this.uploader.getFiles(); |
||||
|
for (i = 0; file = files[i++]; ) { |
||||
|
status = file.getStatus(); |
||||
|
if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++; |
||||
|
} |
||||
|
return readyFile; |
||||
|
}, |
||||
|
getInsertList: function () { |
||||
|
var i, link, data, list = [], |
||||
|
prefix = editor.getOpt('fileUrlPrefix'); |
||||
|
for (i = 0; i < this.fileList.length; i++) { |
||||
|
data = this.fileList[i]; |
||||
|
link = data.url; |
||||
|
list.push({ |
||||
|
title: data.original || link.substr(link.lastIndexOf('/') + 1), |
||||
|
url: prefix + link |
||||
|
}); |
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
/* 在线附件 */ |
||||
|
function OnlineFile(target) { |
||||
|
this.container = utils.isString(target) ? document.getElementById(target) : target; |
||||
|
this.init(); |
||||
|
} |
||||
|
OnlineFile.prototype = { |
||||
|
init: function () { |
||||
|
this.initContainer(); |
||||
|
this.initEvents(); |
||||
|
this.initData(); |
||||
|
}, |
||||
|
/* 初始化容器 */ |
||||
|
initContainer: function () { |
||||
|
this.container.innerHTML = ''; |
||||
|
this.list = document.createElement('ul'); |
||||
|
this.clearFloat = document.createElement('li'); |
||||
|
|
||||
|
domUtils.addClass(this.list, 'list'); |
||||
|
domUtils.addClass(this.clearFloat, 'clearFloat'); |
||||
|
|
||||
|
this.list.appendChild(this.clearFloat); |
||||
|
this.container.appendChild(this.list); |
||||
|
}, |
||||
|
/* 初始化滚动事件,滚动到地步自动拉取数据 */ |
||||
|
initEvents: function () { |
||||
|
var _this = this; |
||||
|
|
||||
|
/* 滚动拉取图片 */ |
||||
|
domUtils.on($G('fileList'), 'scroll', function(e){ |
||||
|
var panel = this; |
||||
|
if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) { |
||||
|
_this.getFileData(); |
||||
|
} |
||||
|
}); |
||||
|
/* 选中图片 */ |
||||
|
domUtils.on(this.list, 'click', function (e) { |
||||
|
var target = e.target || e.srcElement, |
||||
|
li = target.parentNode; |
||||
|
|
||||
|
if (li.tagName.toLowerCase() == 'li') { |
||||
|
if (domUtils.hasClass(li, 'selected')) { |
||||
|
domUtils.removeClasses(li, 'selected'); |
||||
|
} else { |
||||
|
domUtils.addClass(li, 'selected'); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/* 初始化第一次的数据 */ |
||||
|
initData: function () { |
||||
|
|
||||
|
/* 拉取数据需要使用的值 */ |
||||
|
this.state = 0; |
||||
|
this.listSize = editor.getOpt('fileManagerListSize'); |
||||
|
this.listIndex = 0; |
||||
|
this.listEnd = false; |
||||
|
|
||||
|
/* 第一次拉取数据 */ |
||||
|
this.getFileData(); |
||||
|
}, |
||||
|
/* 向后台拉取图片列表数据 */ |
||||
|
getFileData: function () { |
||||
|
var _this = this; |
||||
|
|
||||
|
if(!_this.listEnd && !this.isLoadingData) { |
||||
|
this.isLoadingData = true; |
||||
|
ajax.request(editor.getActionUrl(editor.getOpt('fileManagerActionName')), { |
||||
|
timeout: 100000, |
||||
|
data: utils.extend({ |
||||
|
start: this.listIndex, |
||||
|
size: this.listSize |
||||
|
}, editor.queryCommandValue('serverparam')), |
||||
|
method: 'get', |
||||
|
onsuccess: function (r) { |
||||
|
try { |
||||
|
var json = eval('(' + r.responseText + ')'); |
||||
|
if (json.state == 'SUCCESS') { |
||||
|
_this.pushData(json.list); |
||||
|
_this.listIndex = parseInt(json.start) + parseInt(json.list.length); |
||||
|
if(_this.listIndex >= json.total) { |
||||
|
_this.listEnd = true; |
||||
|
} |
||||
|
_this.isLoadingData = false; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
if(r.responseText.indexOf('ue_separate_ue') != -1) { |
||||
|
var list = r.responseText.split(r.responseText); |
||||
|
_this.pushData(list); |
||||
|
_this.listIndex = parseInt(list.length); |
||||
|
_this.listEnd = true; |
||||
|
_this.isLoadingData = false; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
onerror: function () { |
||||
|
_this.isLoadingData = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/* 添加图片到列表界面上 */ |
||||
|
pushData: function (list) { |
||||
|
var i, item, img, filetype, preview, icon, _this = this, |
||||
|
urlPrefix = editor.getOpt('fileManagerUrlPrefix'); |
||||
|
for (i = 0; i < list.length; i++) { |
||||
|
if(list[i] && list[i].url) { |
||||
|
item = document.createElement('li'); |
||||
|
icon = document.createElement('span'); |
||||
|
filetype = list[i].url.substr(list[i].url.lastIndexOf('.') + 1); |
||||
|
|
||||
|
if ( "png|jpg|jpeg|gif|bmp".indexOf(filetype) != -1 ) { |
||||
|
preview = document.createElement('img'); |
||||
|
domUtils.on(preview, 'load', (function(image){ |
||||
|
return function(){ |
||||
|
_this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight); |
||||
|
}; |
||||
|
})(preview)); |
||||
|
preview.width = 113; |
||||
|
preview.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) ); |
||||
|
} else { |
||||
|
var ic = document.createElement('i'), |
||||
|
textSpan = document.createElement('span'); |
||||
|
textSpan.innerHTML = list[i].url.substr(list[i].url.lastIndexOf('/') + 1); |
||||
|
preview = document.createElement('div'); |
||||
|
preview.appendChild(ic); |
||||
|
preview.appendChild(textSpan); |
||||
|
domUtils.addClass(preview, 'file-wrapper'); |
||||
|
domUtils.addClass(textSpan, 'file-title'); |
||||
|
domUtils.addClass(ic, 'file-type-' + filetype); |
||||
|
domUtils.addClass(ic, 'file-preview'); |
||||
|
} |
||||
|
domUtils.addClass(icon, 'icon'); |
||||
|
item.setAttribute('data-url', urlPrefix + list[i].url); |
||||
|
if (list[i].original) { |
||||
|
item.setAttribute('data-title', list[i].original); |
||||
|
} |
||||
|
|
||||
|
item.appendChild(preview); |
||||
|
item.appendChild(icon); |
||||
|
this.list.insertBefore(item, this.clearFloat); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
/* 改变图片大小 */ |
||||
|
scale: function (img, w, h, type) { |
||||
|
var ow = img.width, |
||||
|
oh = img.height; |
||||
|
|
||||
|
if (type == 'justify') { |
||||
|
if (ow >= oh) { |
||||
|
img.width = w; |
||||
|
img.height = h * oh / ow; |
||||
|
img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; |
||||
|
} else { |
||||
|
img.width = w * ow / oh; |
||||
|
img.height = h; |
||||
|
img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; |
||||
|
} |
||||
|
} else { |
||||
|
if (ow >= oh) { |
||||
|
img.width = w * ow / oh; |
||||
|
img.height = h; |
||||
|
img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; |
||||
|
} else { |
||||
|
img.width = w; |
||||
|
img.height = h * oh / ow; |
||||
|
img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
getInsertList: function () { |
||||
|
var i, lis = this.list.children, list = []; |
||||
|
for (i = 0; i < lis.length; i++) { |
||||
|
if (domUtils.hasClass(lis[i], 'selected')) { |
||||
|
var url = lis[i].getAttribute('data-url'); |
||||
|
var title = lis[i].getAttribute('data-title') || url.substr(url.lastIndexOf('/') + 1); |
||||
|
list.push({ |
||||
|
title: title, |
||||
|
url: url |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
})(); |
||||
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
@ -0,0 +1 @@ |
|||||
|
#imgManager li,#imgManager ul{list-style:none;padding:0;display:block}#imageList,#imgManager li,body{overflow:hidden}#imageList img,#imgManager li,#imgManager li img{cursor:pointer}.wrapper{width:424px;margin:10px auto;zoom:1;position:relative}.tabbody{height:225px}.tabbody .panel{position:absolute;width:100%;height:100%;background:#fff;display:none}.tabbody .focus{display:block}body{font-size:12px;color:#888}input,label{vertical-align:middle}.clear{clear:both}.pl{padding-left:18px;padding-left:23px\9}#imageList{width:420px;height:215px;margin-top:10px;overflow-y:auto}#imageList div{float:left;width:100px;height:95px;margin:5px 10px}#imageList img{border:2px solid #fff}.bgarea{margin:10px;padding:5px;height:84%;border:1px solid #A8A297}.content div{margin:10px 0 10px 5px}.content .iptradio{margin:0 5px 5px 0}#colorPicker,div.color{margin:0;float:left}.txt{width:280px}.wrapcolor{height:19px}#colorPicker{width:17px;height:17px;border:1px solid #CCC;display:inline-block;border-radius:3px;box-shadow:2px 2px 5px #D3D6DA}#custom,div.alignment{margin-left:23px;margin-left:28px\9}#custom input{height:15px;min-height:15px;width:20px}#repeatType{width:100px}#imgManager{width:100%;height:225px}#imgManager #imageList{width:100%;overflow-x:hidden;overflow-y:auto}#imgManager ul{margin:0}#imgManager li{float:left;width:113px;height:113px;margin:9px 0 0 19px;background-color:#eee;position:relative}#imgManager li.clearFloat{float:none;clear:both;display:block;width:0;height:0;margin:0;padding:0}#imgManager li .icon{cursor:pointer;width:113px;height:113px;position:absolute;top:0;left:0;z-index:2;border:0;background-repeat:no-repeat}#imgManager li .icon:hover,#imgManager li.selected .icon:hover{width:107px;height:107px;border:3px solid #1094fa}#imgManager li.selected .icon{background-image:url(images/success.png);background-position:75px 75px}#imgManager li.selected .icon:hover{background-position:72px 72px} |
||||
@ -0,0 +1,56 @@ |
|||||
|
<!DOCTYPE HTML> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> |
||||
|
<script type="text/javascript" src="../internal.js"></script> |
||||
|
<link rel="stylesheet" type="text/css" href="background.css"> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div id="bg_container" class="wrapper"> |
||||
|
<div id="tabHeads" class="tabhead"> |
||||
|
<span class="focus" data-content-id="normal"><var id="lang_background_normal"></var></span> |
||||
|
<span class="" data-content-id="imgManager"><var id="lang_background_local"></var></span> |
||||
|
</div> |
||||
|
<div id="tabBodys" class="tabbody"> |
||||
|
<div id="normal" class="panel focus"> |
||||
|
<fieldset class="bgarea"> |
||||
|
<legend><var id="lang_background_set"></var></legend> |
||||
|
<div class="content"> |
||||
|
<div> |
||||
|
<label><input id="nocolorRadio" class="iptradio" type="radio" name="t" value="none" checked="checked"><var id="lang_background_none"></var></label> |
||||
|
<label><input id="coloredRadio" class="iptradio" type="radio" name="t" value="color"><var id="lang_background_colored"></var></label> |
||||
|
</div> |
||||
|
<div class="wrapcolor pl"> |
||||
|
<div class="color"> |
||||
|
<var id="lang_background_color"></var>: |
||||
|
</div> |
||||
|
<div id="colorPicker"></div> |
||||
|
<div class="clear"></div> |
||||
|
</div> |
||||
|
<div class="wrapcolor pl"> |
||||
|
<label><var id="lang_background_netimg"></var>:</label><input class="txt" type="text" id="url"> |
||||
|
</div> |
||||
|
<div id="alignment" class="alignment"> |
||||
|
<var id="lang_background_align"></var>:<select id="repeatType"> |
||||
|
<option value="center"></option> |
||||
|
<option value="repeat-x"></option> |
||||
|
<option value="repeat-y"></option> |
||||
|
<option value="repeat"></option> |
||||
|
<option value="self"></option> |
||||
|
</select> |
||||
|
</div> |
||||
|
<div id="custom" > |
||||
|
<var id="lang_background_position"></var>:x:<input type="text" size="1" id="x" maxlength="4" value="0">px y:<input type="text" size="1" id="y" maxlength="4" value="0">px |
||||
|
</div> |
||||
|
</div> |
||||
|
</fieldset> |
||||
|
|
||||
|
</div> |
||||
|
<div id="imgManager" class="panel"> |
||||
|
<div id="imageList" style=""></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<script type="text/javascript" src="background.js"></script> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,376 @@ |
|||||
|
(function () { |
||||
|
|
||||
|
var onlineImage, |
||||
|
backupStyle = editor.queryCommandValue('background'); |
||||
|
|
||||
|
window.onload = function () { |
||||
|
initTabs(); |
||||
|
initColorSelector(); |
||||
|
}; |
||||
|
|
||||
|
/* 初始化tab标签 */ |
||||
|
function initTabs(){ |
||||
|
var tabs = $G('tabHeads').children; |
||||
|
for (var i = 0; i < tabs.length; i++) { |
||||
|
domUtils.on(tabs[i], "click", function (e) { |
||||
|
var target = e.target || e.srcElement; |
||||
|
for (var j = 0; j < tabs.length; j++) { |
||||
|
if(tabs[j] == target){ |
||||
|
tabs[j].className = "focus"; |
||||
|
var contentId = tabs[j].getAttribute('data-content-id'); |
||||
|
$G(contentId).style.display = "block"; |
||||
|
if(contentId == 'imgManager') { |
||||
|
initImagePanel(); |
||||
|
} |
||||
|
}else { |
||||
|
tabs[j].className = ""; |
||||
|
$G(tabs[j].getAttribute('data-content-id')).style.display = "none"; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 初始化颜色设置 */ |
||||
|
function initColorSelector () { |
||||
|
var obj = editor.queryCommandValue('background'); |
||||
|
if (obj) { |
||||
|
var color = obj['background-color'], |
||||
|
repeat = obj['background-repeat'] || 'repeat', |
||||
|
image = obj['background-image'] || '', |
||||
|
position = obj['background-position'] || 'center center', |
||||
|
pos = position.split(' '), |
||||
|
x = parseInt(pos[0]) || 0, |
||||
|
y = parseInt(pos[1]) || 0; |
||||
|
|
||||
|
if(repeat == 'no-repeat' && (x || y)) repeat = 'self'; |
||||
|
|
||||
|
image = image.match(/url[\s]*\(([^\)]*)\)/); |
||||
|
image = image ? image[1]:''; |
||||
|
updateFormState('colored', color, image, repeat, x, y); |
||||
|
} else { |
||||
|
updateFormState(); |
||||
|
} |
||||
|
|
||||
|
var updateHandler = function () { |
||||
|
updateFormState(); |
||||
|
updateBackground(); |
||||
|
} |
||||
|
domUtils.on($G('nocolorRadio'), 'click', updateBackground); |
||||
|
domUtils.on($G('coloredRadio'), 'click', updateHandler); |
||||
|
domUtils.on($G('url'), 'keyup', function(){ |
||||
|
if($G('url').value && $G('alignment').style.display == "none") { |
||||
|
utils.each($G('repeatType').children, function(item){ |
||||
|
item.selected = ('repeat' == item.getAttribute('value') ? 'selected':false); |
||||
|
}); |
||||
|
} |
||||
|
updateHandler(); |
||||
|
}); |
||||
|
domUtils.on($G('repeatType'), 'change', updateHandler); |
||||
|
domUtils.on($G('x'), 'keyup', updateBackground); |
||||
|
domUtils.on($G('y'), 'keyup', updateBackground); |
||||
|
|
||||
|
initColorPicker(); |
||||
|
} |
||||
|
|
||||
|
/* 初始化颜色选择器 */ |
||||
|
function initColorPicker() { |
||||
|
var me = editor, |
||||
|
cp = $G("colorPicker"); |
||||
|
|
||||
|
/* 生成颜色选择器ui对象 */ |
||||
|
var popup = new UE.ui.Popup({ |
||||
|
content: new UE.ui.ColorPicker({ |
||||
|
noColorText: me.getLang("clearColor"), |
||||
|
editor: me, |
||||
|
onpickcolor: function (t, color) { |
||||
|
updateFormState('colored', color); |
||||
|
updateBackground(); |
||||
|
UE.ui.Popup.postHide(); |
||||
|
}, |
||||
|
onpicknocolor: function (t, color) { |
||||
|
updateFormState('colored', 'transparent'); |
||||
|
updateBackground(); |
||||
|
UE.ui.Popup.postHide(); |
||||
|
} |
||||
|
}), |
||||
|
editor: me, |
||||
|
onhide: function () { |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
/* 设置颜色选择器 */ |
||||
|
domUtils.on(cp, "click", function () { |
||||
|
popup.showAnchor(this); |
||||
|
}); |
||||
|
domUtils.on(document, 'mousedown', function (evt) { |
||||
|
var el = evt.target || evt.srcElement; |
||||
|
UE.ui.Popup.postHide(el); |
||||
|
}); |
||||
|
domUtils.on(window, 'scroll', function () { |
||||
|
UE.ui.Popup.postHide(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/* 初始化在线图片列表 */ |
||||
|
function initImagePanel() { |
||||
|
onlineImage = onlineImage || new OnlineImage('imageList'); |
||||
|
} |
||||
|
|
||||
|
/* 更新背景色设置面板 */ |
||||
|
function updateFormState (radio, color, url, align, x, y) { |
||||
|
var nocolorRadio = $G('nocolorRadio'), |
||||
|
coloredRadio = $G('coloredRadio'); |
||||
|
|
||||
|
if(radio) { |
||||
|
nocolorRadio.checked = (radio == 'colored' ? false:'checked'); |
||||
|
coloredRadio.checked = (radio == 'colored' ? 'checked':false); |
||||
|
} |
||||
|
if(color) { |
||||
|
domUtils.setStyle($G("colorPicker"), "background-color", color); |
||||
|
} |
||||
|
|
||||
|
if(url && /^\//.test(url)) { |
||||
|
var a = document.createElement('a'); |
||||
|
a.href = url; |
||||
|
browser.ie && (a.href = a.href); |
||||
|
url = browser.ie ? a.href:(a.protocol + '//' + a.host + a.pathname + a.search + a.hash); |
||||
|
} |
||||
|
|
||||
|
if(url || url === '') { |
||||
|
$G('url').value = url; |
||||
|
} |
||||
|
if(align) { |
||||
|
utils.each($G('repeatType').children, function(item){ |
||||
|
item.selected = (align == item.getAttribute('value') ? 'selected':false); |
||||
|
}); |
||||
|
} |
||||
|
if(x || y) { |
||||
|
$G('x').value = parseInt(x) || 0; |
||||
|
$G('y').value = parseInt(y) || 0; |
||||
|
} |
||||
|
|
||||
|
$G('alignment').style.display = coloredRadio.checked && $G('url').value ? '':'none'; |
||||
|
$G('custom').style.display = coloredRadio.checked && $G('url').value && $G('repeatType').value == 'self' ? '':'none'; |
||||
|
} |
||||
|
|
||||
|
/* 更新背景颜色 */ |
||||
|
function updateBackground () { |
||||
|
if ($G('coloredRadio').checked) { |
||||
|
var color = domUtils.getStyle($G("colorPicker"), "background-color"), |
||||
|
bgimg = $G("url").value, |
||||
|
align = $G("repeatType").value, |
||||
|
backgroundObj = { |
||||
|
"background-repeat": "no-repeat", |
||||
|
"background-position": "center center" |
||||
|
}; |
||||
|
|
||||
|
if (color) backgroundObj["background-color"] = color; |
||||
|
if (bgimg) backgroundObj["background-image"] = 'url(' + bgimg + ')'; |
||||
|
if (align == 'self') { |
||||
|
backgroundObj["background-position"] = $G("x").value + "px " + $G("y").value + "px"; |
||||
|
} else if (align == 'repeat-x' || align == 'repeat-y' || align == 'repeat') { |
||||
|
backgroundObj["background-repeat"] = align; |
||||
|
} |
||||
|
|
||||
|
editor.execCommand('background', backgroundObj); |
||||
|
} else { |
||||
|
editor.execCommand('background', null); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* 在线图片 */ |
||||
|
function OnlineImage(target) { |
||||
|
this.container = utils.isString(target) ? document.getElementById(target) : target; |
||||
|
this.init(); |
||||
|
} |
||||
|
OnlineImage.prototype = { |
||||
|
init: function () { |
||||
|
this.reset(); |
||||
|
this.initEvents(); |
||||
|
}, |
||||
|
/* 初始化容器 */ |
||||
|
initContainer: function () { |
||||
|
this.container.innerHTML = ''; |
||||
|
this.list = document.createElement('ul'); |
||||
|
this.clearFloat = document.createElement('li'); |
||||
|
|
||||
|
domUtils.addClass(this.list, 'list'); |
||||
|
domUtils.addClass(this.clearFloat, 'clearFloat'); |
||||
|
|
||||
|
this.list.id = 'imageListUl'; |
||||
|
this.list.appendChild(this.clearFloat); |
||||
|
this.container.appendChild(this.list); |
||||
|
}, |
||||
|
/* 初始化滚动事件,滚动到地步自动拉取数据 */ |
||||
|
initEvents: function () { |
||||
|
var _this = this; |
||||
|
|
||||
|
/* 滚动拉取图片 */ |
||||
|
domUtils.on($G('imageList'), 'scroll', function(e){ |
||||
|
var panel = this; |
||||
|
if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) { |
||||
|
_this.getImageData(); |
||||
|
} |
||||
|
}); |
||||
|
/* 选中图片 */ |
||||
|
domUtils.on(this.container, 'click', function (e) { |
||||
|
var target = e.target || e.srcElement, |
||||
|
li = target.parentNode, |
||||
|
nodes = $G('imageListUl').childNodes; |
||||
|
|
||||
|
if (li.tagName.toLowerCase() == 'li') { |
||||
|
updateFormState('nocolor', null, ''); |
||||
|
for (var i = 0, node; node = nodes[i++];) { |
||||
|
if (node == li && !domUtils.hasClass(node, 'selected')) { |
||||
|
domUtils.addClass(node, 'selected'); |
||||
|
updateFormState('colored', null, li.firstChild.getAttribute("_src"), 'repeat'); |
||||
|
} else { |
||||
|
domUtils.removeClasses(node, 'selected'); |
||||
|
} |
||||
|
} |
||||
|
updateBackground(); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
/* 初始化第一次的数据 */ |
||||
|
initData: function () { |
||||
|
|
||||
|
/* 拉取数据需要使用的值 */ |
||||
|
this.state = 0; |
||||
|
this.listSize = editor.getOpt('imageManagerListSize'); |
||||
|
this.listIndex = 0; |
||||
|
this.listEnd = false; |
||||
|
|
||||
|
/* 第一次拉取数据 */ |
||||
|
this.getImageData(); |
||||
|
}, |
||||
|
/* 重置界面 */ |
||||
|
reset: function() { |
||||
|
this.initContainer(); |
||||
|
this.initData(); |
||||
|
}, |
||||
|
/* 向后台拉取图片列表数据 */ |
||||
|
getImageData: function () { |
||||
|
var _this = this; |
||||
|
|
||||
|
if(!_this.listEnd && !this.isLoadingData) { |
||||
|
this.isLoadingData = true; |
||||
|
var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')), |
||||
|
isJsonp = utils.isCrossDomainUrl(url); |
||||
|
ajax.request(url, { |
||||
|
'timeout': 100000, |
||||
|
'dataType': isJsonp ? 'jsonp':'', |
||||
|
'data': utils.extend({ |
||||
|
start: this.listIndex, |
||||
|
size: this.listSize |
||||
|
}, editor.queryCommandValue('serverparam')), |
||||
|
'method': 'get', |
||||
|
'onsuccess': function (r) { |
||||
|
try { |
||||
|
var json = isJsonp ? r:eval('(' + r.responseText + ')'); |
||||
|
if (json.state == 'SUCCESS') { |
||||
|
_this.pushData(json.list); |
||||
|
_this.listIndex = parseInt(json.start) + parseInt(json.list.length); |
||||
|
if(_this.listIndex >= json.total) { |
||||
|
_this.listEnd = true; |
||||
|
} |
||||
|
_this.isLoadingData = false; |
||||
|
} |
||||
|
} catch (e) { |
||||
|
if(r.responseText.indexOf('ue_separate_ue') != -1) { |
||||
|
var list = r.responseText.split(r.responseText); |
||||
|
_this.pushData(list); |
||||
|
_this.listIndex = parseInt(list.length); |
||||
|
_this.listEnd = true; |
||||
|
_this.isLoadingData = false; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
'onerror': function () { |
||||
|
_this.isLoadingData = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
/* 添加图片到列表界面上 */ |
||||
|
pushData: function (list) { |
||||
|
var i, item, img, icon, _this = this, |
||||
|
urlPrefix = editor.getOpt('imageManagerUrlPrefix'); |
||||
|
for (i = 0; i < list.length; i++) { |
||||
|
if(list[i] && list[i].url) { |
||||
|
item = document.createElement('li'); |
||||
|
img = document.createElement('img'); |
||||
|
icon = document.createElement('span'); |
||||
|
|
||||
|
domUtils.on(img, 'load', (function(image){ |
||||
|
return function(){ |
||||
|
_this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight); |
||||
|
} |
||||
|
})(img)); |
||||
|
img.width = 113; |
||||
|
img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) ); |
||||
|
img.setAttribute('_src', urlPrefix + list[i].url); |
||||
|
domUtils.addClass(icon, 'icon'); |
||||
|
|
||||
|
item.appendChild(img); |
||||
|
item.appendChild(icon); |
||||
|
this.list.insertBefore(item, this.clearFloat); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
/* 改变图片大小 */ |
||||
|
scale: function (img, w, h, type) { |
||||
|
var ow = img.width, |
||||
|
oh = img.height; |
||||
|
|
||||
|
if (type == 'justify') { |
||||
|
if (ow >= oh) { |
||||
|
img.width = w; |
||||
|
img.height = h * oh / ow; |
||||
|
img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; |
||||
|
} else { |
||||
|
img.width = w * ow / oh; |
||||
|
img.height = h; |
||||
|
img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; |
||||
|
} |
||||
|
} else { |
||||
|
if (ow >= oh) { |
||||
|
img.width = w * ow / oh; |
||||
|
img.height = h; |
||||
|
img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; |
||||
|
} else { |
||||
|
img.width = w; |
||||
|
img.height = h * oh / ow; |
||||
|
img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
getInsertList: function () { |
||||
|
var i, lis = this.list.children, list = [], align = getAlign(); |
||||
|
for (i = 0; i < lis.length; i++) { |
||||
|
if (domUtils.hasClass(lis[i], 'selected')) { |
||||
|
var img = lis[i].firstChild, |
||||
|
src = img.getAttribute('_src'); |
||||
|
list.push({ |
||||
|
src: src, |
||||
|
_src: src, |
||||
|
floatStyle: align |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
dialog.onok = function () { |
||||
|
updateBackground(); |
||||
|
editor.fireEvent('saveScene'); |
||||
|
}; |
||||
|
dialog.oncancel = function () { |
||||
|
editor.execCommand('background', backupStyle); |
||||
|
}; |
||||
|
|
||||
|
})(); |
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
@ -0,0 +1 @@ |
|||||
|
(function(){window.BMAP_PROTOCOL = "https"; window.BMap_loadScriptTime = (new Date).getTime(); document.write('<script type="text/javascript" src="./getscript.js?v=1.1&ak=&services=true&t=20130716024058"></script>');document.write('<link rel="stylesheet" type="text/css" href="https://api.map.baidu.com/res/11/bmaps.css"/>');})(); |
||||
|
After Width: | Height: | Size: 628 B |
|
After Width: | Height: | Size: 608 B |
|
After Width: | Height: | Size: 84 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 184 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,7 @@ |
|||||
|
(function(i,C){function m(a){return typeof a==="number"}function n(a){return a!==D&&a!==null}var D,p,r,s=i.Chart,t=i.extend,z=i.each;r=["path","rect","circle"];p={top:0,left:0,center:0.5,middle:0.5,bottom:1,right:1};var u=C.inArray,A=i.merge,B=function(){this.init.apply(this,arguments)};B.prototype={init:function(a,d){var c=d.shape&&d.shape.type;this.chart=a;var b,f;f={xAxis:0,yAxis:0,title:{style:{},text:"",x:0,y:0},shape:{params:{stroke:"#000000",fill:"transparent",strokeWidth:2}}};b={circle:{params:{x:0, |
||||
|
y:0}}};if(b[c])f.shape=A(f.shape,b[c]);this.options=A({},f,d)},render:function(a){var d=this.chart,c=this.chart.renderer,b=this.group,f=this.title,e=this.shape,h=this.options,i=h.title,l=h.shape;if(!b)b=this.group=c.g();if(!e&&l&&u(l.type,r)!==-1)e=this.shape=c[h.shape.type](l.params),e.add(b);if(!f&&i)f=this.title=c.label(i),f.add(b);b.add(d.annotations.group);this.linkObjects();a!==!1&&this.redraw()},redraw:function(){var a=this.options,d=this.chart,c=this.group,b=this.title,f=this.shape,e=this.linkedObject, |
||||
|
h=d.xAxis[a.xAxis],v=d.yAxis[a.yAxis],l=a.width,w=a.height,x=p[a.anchorY],y=p[a.anchorX],j,o,g,q;if(e)j=e instanceof i.Point?"point":e instanceof i.Series?"series":null,j==="point"?(a.xValue=e.x,a.yValue=e.y,o=e.series):j==="series"&&(o=e),c.visibility!==o.group.visibility&&c.attr({visibility:o.group.visibility});e=n(a.xValue)?h.toPixels(a.xValue+h.minPointOffset)-h.minPixelPadding:a.x;j=n(a.yValue)?v.toPixels(a.yValue):a.y;if(!isNaN(e)&&!isNaN(j)&&m(e)&&m(j)){b&&(b.attr(a.title),b.css(a.title.style)); |
||||
|
if(f){b=t({},a.shape.params);if(a.units==="values"){for(g in b)u(g,["width","x"])>-1?b[g]=h.translate(b[g]):u(g,["height","y"])>-1&&(b[g]=v.translate(b[g]));b.width&&(b.width-=h.toPixels(0)-h.left);b.x&&(b.x+=h.minPixelPadding);if(a.shape.type==="path"){g=b.d;o=e;for(var r=j,s=g.length,k=0;k<s;)typeof g[k]==="number"&&typeof g[k+1]==="number"?(g[k]=h.toPixels(g[k])-o,g[k+1]=v.toPixels(g[k+1])-r,k+=2):k+=1}}a.shape.type==="circle"&&(b.x+=b.r,b.y+=b.r);f.attr(b)}c.bBox=null;if(!m(l))q=c.getBBox(),l= |
||||
|
q.width;if(!m(w))q||(q=c.getBBox()),w=q.height;if(!m(y))y=p.center;if(!m(x))x=p.center;e-=l*y;j-=w*x;d.animation&&n(c.translateX)&&n(c.translateY)?c.animate({translateX:e,translateY:j}):c.translate(e,j)}},destroy:function(){var a=this,d=this.chart.annotations.allItems,c=d.indexOf(a);c>-1&&d.splice(c,1);z(["title","shape","group"],function(b){a[b]&&(a[b].destroy(),a[b]=null)});a.group=a.title=a.shape=a.chart=a.options=null},update:function(a,d){t(this.options,a);this.linkObjects();this.render(d)}, |
||||
|
linkObjects:function(){var a=this.chart,d=this.linkedObject,c=d&&(d.id||d.options.id),b=this.options.linkedTo;if(n(b)){if(!n(d)||b!==c)this.linkedObject=a.get(b)}else this.linkedObject=null}};t(s.prototype,{annotations:{add:function(a,d){var c=this.allItems,b=this.chart,f,e;Object.prototype.toString.call(a)==="[object Array]"||(a=[a]);for(e=a.length;e--;)f=new B(b,a[e]),c.push(f),f.render(d)},redraw:function(){z(this.allItems,function(a){a.redraw()})}}});s.prototype.callbacks.push(function(a){var d= |
||||
|
a.options.annotations,c;c=a.renderer.g("annotations");c.attr({zIndex:7});c.add();a.annotations.allItems=[];a.annotations.chart=a;a.annotations.group=c;Object.prototype.toString.call(d)==="[object Array]"&&d.length>0&&a.annotations.add(a.options.annotations);i.addEvent(a,"redraw",function(){a.annotations.redraw()})})})(Highcharts,HighchartsAdapter); |
||||
@ -0,0 +1,401 @@ |
|||||
|
(function (Highcharts, HighchartsAdapter) { |
||||
|
|
||||
|
var UNDEFINED, |
||||
|
ALIGN_FACTOR, |
||||
|
ALLOWED_SHAPES, |
||||
|
Chart = Highcharts.Chart, |
||||
|
extend = Highcharts.extend, |
||||
|
each = Highcharts.each; |
||||
|
|
||||
|
ALLOWED_SHAPES = ["path", "rect", "circle"]; |
||||
|
|
||||
|
ALIGN_FACTOR = { |
||||
|
top: 0, |
||||
|
left: 0, |
||||
|
center: 0.5, |
||||
|
middle: 0.5, |
||||
|
bottom: 1, |
||||
|
right: 1 |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// Highcharts helper methods
|
||||
|
var inArray = HighchartsAdapter.inArray, |
||||
|
merge = Highcharts.merge; |
||||
|
|
||||
|
function defaultOptions(shapeType) { |
||||
|
var shapeOptions, |
||||
|
options; |
||||
|
|
||||
|
options = { |
||||
|
xAxis: 0, |
||||
|
yAxis: 0, |
||||
|
title: { |
||||
|
style: {}, |
||||
|
text: "", |
||||
|
x: 0, |
||||
|
y: 0 |
||||
|
}, |
||||
|
shape: { |
||||
|
params: { |
||||
|
stroke: "#000000", |
||||
|
fill: "transparent", |
||||
|
strokeWidth: 2 |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
shapeOptions = { |
||||
|
circle: { |
||||
|
params: { |
||||
|
x: 0, |
||||
|
y: 0 |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
if (shapeOptions[shapeType]) { |
||||
|
options.shape = merge(options.shape, shapeOptions[shapeType]); |
||||
|
} |
||||
|
|
||||
|
return options; |
||||
|
} |
||||
|
|
||||
|
function isArray(obj) { |
||||
|
return Object.prototype.toString.call(obj) === '[object Array]'; |
||||
|
} |
||||
|
|
||||
|
function isNumber(n) { |
||||
|
return typeof n === 'number'; |
||||
|
} |
||||
|
|
||||
|
function defined(obj) { |
||||
|
return obj !== UNDEFINED && obj !== null; |
||||
|
} |
||||
|
|
||||
|
function translatePath(d, xAxis, yAxis, xOffset, yOffset) { |
||||
|
var len = d.length, |
||||
|
i = 0; |
||||
|
|
||||
|
while (i < len) { |
||||
|
if (typeof d[i] === 'number' && typeof d[i + 1] === 'number') { |
||||
|
d[i] = xAxis.toPixels(d[i]) - xOffset; |
||||
|
d[i + 1] = yAxis.toPixels(d[i + 1]) - yOffset; |
||||
|
i += 2; |
||||
|
} else { |
||||
|
i += 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return d; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Define annotation prototype
|
||||
|
var Annotation = function () { |
||||
|
this.init.apply(this, arguments); |
||||
|
}; |
||||
|
Annotation.prototype = { |
||||
|
/* |
||||
|
* Initialize the annotation |
||||
|
*/ |
||||
|
init: function (chart, options) { |
||||
|
var shapeType = options.shape && options.shape.type; |
||||
|
|
||||
|
this.chart = chart; |
||||
|
this.options = merge({}, defaultOptions(shapeType), options); |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Render the annotation |
||||
|
*/ |
||||
|
render: function (redraw) { |
||||
|
var annotation = this, |
||||
|
chart = this.chart, |
||||
|
renderer = annotation.chart.renderer, |
||||
|
group = annotation.group, |
||||
|
title = annotation.title, |
||||
|
shape = annotation.shape, |
||||
|
options = annotation.options, |
||||
|
titleOptions = options.title, |
||||
|
shapeOptions = options.shape; |
||||
|
|
||||
|
if (!group) { |
||||
|
group = annotation.group = renderer.g(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
if (!shape && shapeOptions && inArray(shapeOptions.type, ALLOWED_SHAPES) !== -1) { |
||||
|
shape = annotation.shape = renderer[options.shape.type](shapeOptions.params); |
||||
|
shape.add(group); |
||||
|
} |
||||
|
|
||||
|
if (!title && titleOptions) { |
||||
|
title = annotation.title = renderer.label(titleOptions); |
||||
|
title.add(group); |
||||
|
} |
||||
|
|
||||
|
group.add(chart.annotations.group); |
||||
|
|
||||
|
// link annotations to point or series
|
||||
|
annotation.linkObjects(); |
||||
|
|
||||
|
if (redraw !== false) { |
||||
|
annotation.redraw(); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Redraw the annotation title or shape after options update |
||||
|
*/ |
||||
|
redraw: function () { |
||||
|
var options = this.options, |
||||
|
chart = this.chart, |
||||
|
group = this.group, |
||||
|
title = this.title, |
||||
|
shape = this.shape, |
||||
|
linkedTo = this.linkedObject, |
||||
|
xAxis = chart.xAxis[options.xAxis], |
||||
|
yAxis = chart.yAxis[options.yAxis], |
||||
|
width = options.width, |
||||
|
height = options.height, |
||||
|
anchorY = ALIGN_FACTOR[options.anchorY], |
||||
|
anchorX = ALIGN_FACTOR[options.anchorX], |
||||
|
resetBBox = false, |
||||
|
shapeParams, |
||||
|
linkType, |
||||
|
series, |
||||
|
param, |
||||
|
bbox, |
||||
|
x, |
||||
|
y; |
||||
|
|
||||
|
if (linkedTo) { |
||||
|
linkType = (linkedTo instanceof Highcharts.Point) ? 'point' : |
||||
|
(linkedTo instanceof Highcharts.Series) ? 'series' : null; |
||||
|
|
||||
|
if (linkType === 'point') { |
||||
|
options.xValue = linkedTo.x; |
||||
|
options.yValue = linkedTo.y; |
||||
|
series = linkedTo.series; |
||||
|
} else if (linkType === 'series') { |
||||
|
series = linkedTo; |
||||
|
} |
||||
|
|
||||
|
if (group.visibility !== series.group.visibility) { |
||||
|
group.attr({ |
||||
|
visibility: series.group.visibility |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Based on given options find annotation pixel position
|
||||
|
x = (defined(options.xValue) ? xAxis.toPixels(options.xValue + xAxis.minPointOffset) - xAxis.minPixelPadding : options.x); |
||||
|
y = defined(options.yValue) ? yAxis.toPixels(options.yValue) : options.y; |
||||
|
|
||||
|
if (isNaN(x) || isNaN(y) || !isNumber(x) || !isNumber(y)) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
if (title) { |
||||
|
title.attr(options.title); |
||||
|
title.css(options.title.style); |
||||
|
resetBBox = true; |
||||
|
} |
||||
|
|
||||
|
if (shape) { |
||||
|
shapeParams = extend({}, options.shape.params); |
||||
|
|
||||
|
if (options.units === 'values') { |
||||
|
for (param in shapeParams) { |
||||
|
if (inArray(param, ['width', 'x']) > -1) { |
||||
|
shapeParams[param] = xAxis.translate(shapeParams[param]); |
||||
|
} else if (inArray(param, ['height', 'y']) > -1) { |
||||
|
shapeParams[param] = yAxis.translate(shapeParams[param]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (shapeParams.width) { |
||||
|
shapeParams.width -= xAxis.toPixels(0) - xAxis.left; |
||||
|
} |
||||
|
|
||||
|
if (shapeParams.x) { |
||||
|
shapeParams.x += xAxis.minPixelPadding; |
||||
|
} |
||||
|
|
||||
|
if (options.shape.type === 'path') { |
||||
|
translatePath(shapeParams.d, xAxis, yAxis, x, y); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// move the center of the circle to shape x/y
|
||||
|
if (options.shape.type === 'circle') { |
||||
|
shapeParams.x += shapeParams.r; |
||||
|
shapeParams.y += shapeParams.r; |
||||
|
} |
||||
|
|
||||
|
resetBBox = true; |
||||
|
shape.attr(shapeParams); |
||||
|
} |
||||
|
|
||||
|
group.bBox = null; |
||||
|
|
||||
|
// If annotation width or height is not defined in options use bounding box size
|
||||
|
if (!isNumber(width)) { |
||||
|
bbox = group.getBBox(); |
||||
|
width = bbox.width; |
||||
|
} |
||||
|
|
||||
|
if (!isNumber(height)) { |
||||
|
// get bbox only if it wasn't set before
|
||||
|
if (!bbox) { |
||||
|
bbox = group.getBBox(); |
||||
|
} |
||||
|
|
||||
|
height = bbox.height; |
||||
|
} |
||||
|
|
||||
|
// Calculate anchor point
|
||||
|
if (!isNumber(anchorX)) { |
||||
|
anchorX = ALIGN_FACTOR.center; |
||||
|
} |
||||
|
|
||||
|
if (!isNumber(anchorY)) { |
||||
|
anchorY = ALIGN_FACTOR.center; |
||||
|
} |
||||
|
|
||||
|
// Translate group according to its dimension and anchor point
|
||||
|
x = x - width * anchorX; |
||||
|
y = y - height * anchorY; |
||||
|
|
||||
|
if (chart.animation && defined(group.translateX) && defined(group.translateY)) { |
||||
|
group.animate({ |
||||
|
translateX: x, |
||||
|
translateY: y |
||||
|
}); |
||||
|
} else { |
||||
|
group.translate(x, y); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Destroy the annotation |
||||
|
*/ |
||||
|
destroy: function () { |
||||
|
var annotation = this, |
||||
|
chart = this.chart, |
||||
|
allItems = chart.annotations.allItems, |
||||
|
index = allItems.indexOf(annotation); |
||||
|
|
||||
|
if (index > -1) { |
||||
|
allItems.splice(index, 1); |
||||
|
} |
||||
|
|
||||
|
each(['title', 'shape', 'group'], function (element) { |
||||
|
if (annotation[element]) { |
||||
|
annotation[element].destroy(); |
||||
|
annotation[element] = null; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
annotation.group = annotation.title = annotation.shape = annotation.chart = annotation.options = null; |
||||
|
}, |
||||
|
|
||||
|
/* |
||||
|
* Update the annotation with a given options |
||||
|
*/ |
||||
|
update: function (options, redraw) { |
||||
|
extend(this.options, options); |
||||
|
|
||||
|
// update link to point or series
|
||||
|
this.linkObjects(); |
||||
|
|
||||
|
this.render(redraw); |
||||
|
}, |
||||
|
|
||||
|
linkObjects: function () { |
||||
|
var annotation = this, |
||||
|
chart = annotation.chart, |
||||
|
linkedTo = annotation.linkedObject, |
||||
|
linkedId = linkedTo && (linkedTo.id || linkedTo.options.id), |
||||
|
options = annotation.options, |
||||
|
id = options.linkedTo; |
||||
|
|
||||
|
if (!defined(id)) { |
||||
|
annotation.linkedObject = null; |
||||
|
} else if (!defined(linkedTo) || id !== linkedId) { |
||||
|
annotation.linkedObject = chart.get(id); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// Add annotations methods to chart prototype
|
||||
|
extend(Chart.prototype, { |
||||
|
annotations: { |
||||
|
/* |
||||
|
* Unified method for adding annotations to the chart |
||||
|
*/ |
||||
|
add: function (options, redraw) { |
||||
|
var annotations = this.allItems, |
||||
|
chart = this.chart, |
||||
|
item, |
||||
|
len; |
||||
|
|
||||
|
if (!isArray(options)) { |
||||
|
options = [options]; |
||||
|
} |
||||
|
|
||||
|
len = options.length; |
||||
|
|
||||
|
while (len--) { |
||||
|
item = new Annotation(chart, options[len]); |
||||
|
annotations.push(item); |
||||
|
item.render(redraw); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Redraw all annotations, method used in chart events |
||||
|
*/ |
||||
|
redraw: function () { |
||||
|
each(this.allItems, function (annotation) { |
||||
|
annotation.redraw(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
// Initialize on chart load
|
||||
|
Chart.prototype.callbacks.push(function (chart) { |
||||
|
var options = chart.options.annotations, |
||||
|
group; |
||||
|
|
||||
|
group = chart.renderer.g("annotations"); |
||||
|
group.attr({ |
||||
|
zIndex: 7 |
||||
|
}); |
||||
|
group.add(); |
||||
|
|
||||
|
// initialize empty array for annotations
|
||||
|
chart.annotations.allItems = []; |
||||
|
|
||||
|
// link chart object to annotations
|
||||
|
chart.annotations.chart = chart; |
||||
|
|
||||
|
// link annotations group element to the chart
|
||||
|
chart.annotations.group = group; |
||||
|
|
||||
|
if (isArray(options) && options.length > 0) { |
||||
|
chart.annotations.add(chart.options.annotations); |
||||
|
} |
||||
|
|
||||
|
// update annotations after chart redraw
|
||||
|
Highcharts.addEvent(chart, 'redraw', function () { |
||||
|
chart.annotations.redraw(); |
||||
|
}); |
||||
|
}); |
||||
|
}(Highcharts, HighchartsAdapter)); |
||||