@ -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)); |
|||