| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881 |
- <?php /**
- * ZenTaoPHP的helper类。
- * The helper class file of ZenTaoPHP framework.
- *
- * The author disclaims copyright to this source code. In place of
- * a legal notice, here is a blessing:
- *
- * May you do good and not evil.
- * May you find forgiveness for yourself and forgive others.
- * May you share freely, never taking more than you give.
- */
- /**
- * 该类实现了一些常用的方法
- * The helper class, contains the tool functions.
- *
- * @package framework
- */
- include __DIR__ . '/base/helper.class.php';
- class helper extends baseHelper
- {
- /**
- * @param bool $source
- */
- public static function getViewType($source = false)
- {
- global $config, $app;
- if($config->requestType != 'GET')
- {
- $pathInfo = $app->getPathInfo();
- if(!empty($pathInfo))
- {
- $dotPos = strrpos((string) $pathInfo, '.');
- if($dotPos)
- {
- $viewType = substr((string) $pathInfo, $dotPos + 1);
- }
- else
- {
- $config->default->view = $config->default->view == 'mhtml' ? 'html' : $config->default->view;
- }
- }
- }
- elseif($config->requestType == 'GET')
- {
- if(isset($_GET[$config->viewVar]))
- {
- $viewType = $_GET[$config->viewVar];
- }
- else
- {
- /* Set default view when url has not module name. such as only domain. */
- $config->default->view = ($config->default->view == 'mhtml' and isset($_GET[$config->moduleVar])) ? 'html' : $config->default->view;
- }
- }
- if($source and isset($viewType)) return $viewType;
- if(isset($viewType) and strpos((string) $config->views, ',' . $viewType . ',') === false) $viewType = $config->default->view;
- return $viewType ?? $config->default->view;
- }
- /**
- * Encode json for $.parseJSON
- *
- * @param array $data
- * @param int $options
- * @static
- * @access public
- * @return string
- */
- public static function jsonEncode4Parse($data, $options = 0)
- {
- $json = json_encode($data);
- if($options) $json = str_replace(array("'", '"'), array('\u0027', '\u0022'), $json);
- $escapers = array("\\", "/", "\"", "'", "\n", "\r", "\t", "\x08", "\x0c", "\\\\u");
- $replacements = array("\\\\", "\\/", "\\\"", "\'", "\\n", "\\r", "\\t", "\\f", "\\b", "\\u");
- return str_replace($escapers, $replacements, $json);
- }
- /**
- * Verify that the system has opened on the feature.
- *
- * @param string $feature scrum_risk | risk | scrum
- * @static
- * @access public
- * @return bool
- */
- public static function hasFeature($feature)
- {
- global $config;
- if(in_array($feature, array('waterfall', 'waterfallplus')))
- {
- return strpos(",$config->disabledFeatures,", ",{$feature},") === false; // 轻量级模式排除瀑布、融合瀑布模型
- }
- if(strpos($feature, '_') !== false)
- {
- $code = explode('_', $feature);
- $code = $code[0] . ucfirst($code[1]);
- return strpos(",$config->disabledFeatures,", ",{$code},") === false;
- }
- $hasFeature = false;
- $canConfigFeature = false;
- foreach($config->featureGroup as $group => $modules)
- {
- foreach($modules as $module)
- {
- if($feature != $group && $feature != $module) continue;
- $canConfigFeature = true;
- $hasFeature |= helper::hasFeature("{$group}_{$module}");
- }
- }
- return !$canConfigFeature || ($hasFeature && strpos(",$config->disabledFeatures,", ",{$feature},") === false);
- }
- /**
- * Convert encoding.
- *
- * @param string $string
- * @param string $fromEncoding
- * @param string $toEncoding
- * @static
- * @access public
- * @return string
- */
- public static function convertEncoding($string, $fromEncoding, $toEncoding = 'utf-8')
- {
- $toEncoding = str_replace('utf8', 'utf-8', $toEncoding);
- if(function_exists('mb_convert_encoding'))
- {
- /* Remove like utf-8//TRANSLIT. */
- $position = strpos($toEncoding, '//');
- if($position !== false) $toEncoding = substr($toEncoding, 0, $position);
- /* Check string encoding. */
- $encodings = array_merge(array('GB2312', 'GBK', 'BIG5'), mb_list_encodings());
- $encoding = strtolower(mb_detect_encoding($string, $encodings));
- if($encoding == $toEncoding) return $string;
- return mb_convert_encoding($string, $toEncoding, $encoding);
- }
- elseif(function_exists('iconv'))
- {
- if($fromEncoding == $toEncoding) return $string;
- $errorlevel = error_reporting();
- error_reporting(0);
- $convertString = iconv($fromEncoding, $toEncoding, $string);
- error_reporting($errorlevel);
- /* iconv error then return original. */
- if(!$convertString) return $string;
- return $convertString;
- }
- return $string;
- }
- /**
- * Calculate two working days.
- *
- * @param string $begin
- * @param string $end
- * @return bool|float
- */
- public static function workDays($begin, $end)
- {
- $begin = strtotime($begin);
- $end = strtotime($end);
- if($end < $begin) return false;
- $double = floor(($end - $begin) / (7 * 24 * 3600));
- $begin = date('w', $begin);
- $end = date('w', $end);
- $end = $begin > $end ? $end + 5 : $end;
- return $double * 5 + $end - $begin;
- }
- /**
- * Unify string to standard chars.
- *
- * @param string $string
- * @param string $to
- * @static
- * @access public
- * @return string
- */
- public static function unify($string, $to = ',')
- {
- $labels = array('_', '、', ' ', '-', '?', '@', '&', '%', '~', '`', '+', '*', '/', '\\', ',', '。');
- $string = str_replace($labels, $to, $string);
- return preg_replace("/[{$to}]+/", $to, trim($string, $to));
- }
- /**
- * Format version to semver formate.
- *
- * @param string $version
- * @static
- * @access public
- * @return string
- */
- public static function formatVersion($version)
- {
- return preg_replace_callback(
- '/([0-9]+)((?:\.[0-9]+)?)((?:\.[0-9]+)?)(?:[\s\-\+]?)((?:[a-z]+)?)((?:\.?[0-9]+)?)/i',
- function($matches)
- {
- $major = $matches[1];
- $minor = $matches[2];
- $patch = $matches[3];
- $preRelease = $matches[4];
- $build = $matches[5];
- $versionStrs = array($major, $minor ?: ".0", $patch ?: ".0");
- if($preRelease ?: $build) array_push($versionStrs, "-");
- if($preRelease) array_push($versionStrs, $preRelease);
- if($build)
- {
- if(!$preRelease) array_push($versionStrs, "build");
- if(mb_substr($build, 0, 1) !== ".") array_push($versionStrs, ".");
- array_push($versionStrs, $build);
- }
- return implode('', $versionStrs);
- },
- $version
- );
- }
- /**
- * Process traffic.
- *
- * @param float $traffic
- * @param int $precision
- * @access public
- * @return string
- */
- public static function formatKB($traffic, $precision = 2)
- {
- if(!$traffic) return 0;
- $base = log((float)$traffic, 1024);
- $suffixes = array('B', 'KB', 'MB', 'GB', 'TB');
- return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
- }
- /**
- * Trim version to xuanxuan version format.
- *
- * @param string $version
- * @access public
- * @return string
- */
- public function trimVersion($version)
- {
- return preg_replace_callback(
- '/([0-9]+)((?:\.[0-9]+)?)((?:\.[0-9]+)?)(?:[\s\-\+]?)((?:[a-z]+)?)((?:\.?[0-9]+)?)/i',
- function($matches)
- {
- $major = $matches[1];
- $minor = $matches[2];
- $patch = $matches[3];
- $preRelease = $matches[4];
- $build = $matches[5];
- $versionStrs = array($major, $minor ?: ".0");
- if($patch && $patch !== ".0" && $patch !== "0") array_push($versionStrs, $patch);
- if($preRelease ?: $build) array_push($versionStrs, " ");
- if($preRelease) array_push($versionStrs, $preRelease);
- if($build)
- {
- if(!$preRelease) array_push($versionStrs, "build");
- array_push($versionStrs, mb_substr($build, 0, 1) === "." ? substr($build, 1) : $build);
- }
- return implode('', $versionStrs);
- },
- $version
- );
- }
- /**
- * Request API.
- *
- * @param string $url
- * @static
- * @access public
- * @return string
- */
- public static function requestAPI($url)
- {
- global $config;
- $url .= (strpos($url, '?') !== false ? '&' : '?') . $config->sessionVar . '=' . session_id();
- if(isset($_SESSION['user'])) $url .= '&account=' . $_SESSION['user']->account;
- $response = common::http($url);
- $jsonDecode = json_decode((string) $response);
- if(empty($jsonDecode)) return $response;
- return $jsonDecode;
- }
- /**
- * Get date interval.
- *
- * @param string $format %Y-%m-%d %H:%i:%s
- * @static
- * @access public
- * @param string|int $begin
- * @param string|int $end
- * @return object|string
- */
- public static function getDateInterval($begin, $end = '', $format = '')
- {
- if(empty($end)) $end = time();
- if(is_int($begin)) $begin = date('Y-m-d H:i:s', $begin);
- if(is_int($end)) $end = date('Y-m-d H:i:s', $end);
- $begin = date_create($begin);
- $end = date_create($end);
- $interval = date_diff($begin, $end);
- if($format)
- {
- $dateInterval = $interval->format($format);
- }
- else
- {
- $dateInterval = new stdClass();
- $dateInterval->year = $interval->format('%y');
- $dateInterval->month = $interval->format('%m');
- $dateInterval->day = $interval->format('%d');
- $dateInterval->hour = $interval->format('%H');
- $dateInterval->minute = $interval->format('%i');
- $dateInterval->secound = $interval->format('%s');
- $dateInterval->year = $dateInterval->year == '00' ? 0 : ltrim($dateInterval->year, '0');
- $dateInterval->month = $dateInterval->month == '00' ? 0 : ltrim($dateInterval->month, '0');
- $dateInterval->day = $dateInterval->day == '00' ? 0 : ltrim($dateInterval->day, '0');
- $dateInterval->hour = $dateInterval->hour == '00' ? 0 : ltrim($dateInterval->hour, '0');
- $dateInterval->minute = $dateInterval->minute == '00' ? 0 : ltrim($dateInterval->minute, '0');
- $dateInterval->secound = $dateInterval->secound == '00' ? 0 : ltrim($dateInterval->secound, '0');
- }
- return $dateInterval;
- }
- /**
- * 是否是内网。
- * Check is intranet.
- *
- * @return bool
- */
- public static function isIntranet()
- {
- return !defined('USE_INTRANET') ? false : USE_INTRANET;
- }
- /**
- * 检查是否启用缓存。
- * Check is enable cache.
- *
- * @return bool
- */
- public static function isCacheEnabled()
- {
- if(isset($_GET['_nocache']) || isset($_SERVER['HTTP_X_ZT_REFRESH'])) return false;
- global $config;
- return $config->cache->enable;
- }
- /**
- * 检查是否启用APCu。
- * Check if APCu is enabled.
- *
- * @access public
- * @return bool
- */
- public static function isAPCuEnabled()
- {
- return extension_loaded('apcu') && ini_get('apc.enabled') == '1';
- }
- /**
- * 检查条件是否成立。
- *
- * @param mixed $value1
- * @param mixed $value2
- * @param string $operator
- * @static
- * @access public
- * @return bool
- */
- public static function checkCondition($value1, $value2, $operator)
- {
- $operatorList = array('=' => 'equal', '==' => 'equal', '!=' => 'notequal', '>' => 'gt', '>=' => 'ge', '<' => 'lt', '<=' => 'le');
- if(!isset($operatorList[$operator]) && !in_array($operator, $operatorList)) return false;
- $operator = isset($operatorList[$operator]) ? zget($operatorList, $operator) : $operator;
- $checkFunc = 'check' . $operator;
- return validater::$checkFunc($value1, $value2);
- }
- /**
- * 替换 Emoji 为指定字符串。
- * Replace Emoji to a specified string.
- *
- * @param string $subject
- * @param string $replace
- * @access public
- * @return string
- */
- public static function replaceEmoji($subject, $replace = '[Emoji]')
- {
- /* 匹配大部分常见 Emoji 范围(包括符号、旗帜、交通工具等)。 */
- $pattern = '/[\x{1F300}-\x{1F5FF}\x{1F600}-\x{1F64F}\x{1F680}-\x{1F6FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{1F900}-\x{1F9FF}]/u';
- return preg_replace($pattern, $replace, $subject);
- }
- }
- /**
- * 检查是否是onlybody模式。
- * Check exist onlybody param.
- *
- * @access public
- * @return bool
- */
- function isonlybody()
- {
- return helper::inOnlyBodyMode();
- }
- /**
- * 检查页面是否是弹窗中。
- * Check page is modal.
- *
- * @access public
- * @return bool
- */
- function isInModal()
- {
- return helper::isAjaxRequest('modal');
- }
- /**
- * Format time.
- *
- * @param string|null $time
- * @param string $format
- * @access public
- * @return string
- */
- function formatTime($time, $format = '')
- {
- if($time === null) return '';
- $time = str_replace('0000-00-00', '', $time);
- $time = str_replace('00:00:00', '', $time);
- if(trim($time) == '') return '';
- if($format) return date($format, strtotime($time));
- return trim($time);
- }
- /**
- * Init page title based on the module name and the method name.
- *
- * @access public
- * @return string
- */
- function initPageTitle()
- {
- global $app, $lang;
- $module = $app->rawModule;
- $method = $app->rawMethod;
- if(empty($lang->$module)) $app->loadLang($module);
- if(!empty($lang->$module->{$method . 'Action'})) return $lang->$module->{$method . 'Action'};
- if(!empty($lang->$module->$method)) return $lang->$module->$method;
- return zget($lang, $method);
- }
- /**
- * Init page entity based on configuration of objectNameFields.
- *
- * @param object $object
- * @access public
- * @return array
- */
- function initPageEntity($object)
- {
- if(empty($object)) return array();
- global $app, $config;
- $app->loadModuleConfig('action');
- $module = $app->getModuleName();
- $idField = isset($config->action->objectIdFields[$module]) ? $config->action->objectIdFields[$module] : 'id';
- $titleField = isset($config->action->objectNameFields[$module]) ? $config->action->objectNameFields[$module] : 'title';
- return array(zget($object, $titleField, ''), zget($object, $idField, 0));
- }
- /**
- * Init table data of zin.
- *
- * @param array $items
- * @param array $fieldList
- * @param object $model
- * @access public
- * @return array
- */
- function initTableData($items, &$fieldList, $model = null)
- {
- if(!empty($_GET['orderBy']) && strpos($_GET['orderBy'], '_') !== false) list($orderField, $orderValue) = explode('_', $_GET['orderBy']);
- if(!empty($orderField) && !empty($orderValue) && !empty($fieldList[$orderField]))
- {
- $sortType = false;
- $col = $fieldList[$orderField];
- if(empty($col['sortType']) && !empty($col['type']) && in_array($col['type'], array('id', 'title'))) $sortType = true;
- if(!empty($col['sortType'])) $sortType = $col['sortType'];
- if(is_bool($sortType)) $fieldList[$orderField]['sortType'] = $orderValue;
- }
- $items = setParent($items);
- if(empty($fieldList['actions'])) return $items;
- foreach($fieldList['actions']['menu'] as $actionMenu)
- {
- if(is_array($actionMenu))
- {
- foreach($actionMenu as $actionMenuKey => $actionName)
- {
- if($actionMenuKey === 'other')
- {
- foreach($actionName as $otherActionName) initTableActions($fieldList, $otherActionName);
- }
- else
- {
- initTableActions($fieldList, $actionName);
- }
- }
- }
- else
- {
- initTableActions($fieldList, $actionMenu);
- }
- }
- global $app, $lang;
- if(empty($model))
- {
- $module = $app->getModuleName();
- $model = $app->control->loadModel($module);
- }
- $maxActionCount = 0;
- foreach($items as $item)
- {
- $item->actions = array();
- $actionList = zget($fieldList['actions'], 'list', array());
- foreach($fieldList['actions']['menu'] as $actionKey => $actionMenu)
- {
- if(isset($actionMenu['other']))
- {
- $currentActionMenu = $actionMenu[0];
- initItemActions($item, $currentActionMenu, $actionList, $model);
- $otherActionMenus = $actionMenu['other'];
- $otherAction = '';
- foreach($otherActionMenus as $otherActionMenu)
- {
- $otherActions = explode('|', $otherActionMenu);
- foreach($otherActions as $otherActionName)
- {
- if(!checkOtherPriv(zget($actionList, $otherActionName, array()), $otherActionName, $item, $model)) continue;
- if(in_array($otherActionName, array_column($item->actions, 'name'))) continue;
- if(method_exists($model, 'isClickable') && !$model->isClickable($item, $otherActionName)) $otherAction .= '-';
- $otherAction .= $otherActionName . ',';
- }
- }
- if($otherAction) $item->actions[] = 'other:' . $otherAction;
- }
- elseif($actionKey === 'more')
- {
- $moreAction = '';
- foreach($actionMenu as $moreActionName)
- {
- if(!checkOtherPriv(zget($actionList, $moreActionName, array()), $moreActionName, $item, $model)) continue;
- if(method_exists($model, 'isClickable') && !$model->isClickable($item, $moreActionName)) $moreAction .= '-';
- $moreAction .= $moreActionName . ',';
- }
- if($moreAction) $item->actions[] = 'more:' . $moreAction;
- }
- elseif(is_array($actionMenu)) // Two or more grups.
- {
- /*
- * Menu可能会有多套,如果只有一套可以直接用一维数组。
- * There are maybe two or more groups of action menus.
- */
- $item->actions = array();
- $isClickable = false;
- foreach($actionMenu as $actionName) $isClickable |= initItemActions($item, $actionName, zget($fieldList['actions'], 'list', array()), $model);
- if($isClickable) break; // If the action is clickable, use this group.
- }
- else // Only one group of action menus.
- {
- initItemActions($item, $actionMenu, zget($fieldList['actions'], 'list', array()), $model);
- }
- }
- if(count($item->actions) > $maxActionCount) $maxActionCount = count($item->actions);
- }
- if(isset($fieldList['actions']))
- {
- $fieldList['actions']['minWidth'] = $maxActionCount * 24 + 24;
- if(empty($fieldList['actions']['title'])) $fieldList['actions']['title'] = $lang->actions;
- }
- if($fieldList['actions']['minWidth'] < 48) $fieldList['actions']['minWidth'] = 48;
- return array_values($items);
- }
- /**
- * Check other action priv.
- *
- * @param array $actionList
- * @param string $actionName
- * @param object $item
- * @param object $model
- * @access public
- * @return bool
- */
- function checkOtherPriv($actionConfig, $action, $item, $model)
- {
- global $app;
- $module = $model->getModuleName();
- if($module == 'flow') $module = $app->rawModule;
- if(!empty($actionConfig['url']['module']) && $module != $actionConfig['url']['module']) $module = $actionConfig['url']['module'];
- $method = $action;
- if(!empty($actionConfig['url']['method']) && $method != $actionConfig['url']['method']) $method = $actionConfig['url']['method'];
- return common::hasPriv($module, $method, $item);
- }
- /**
- * Set the parent property of the data.
- *
- * @param array $items
- * @access public
- * @return array
- */
- function setParent($items)
- {
- foreach($items as $item)
- {
- if(isset($item->isParent)) continue;
- /* Set parent attribute. */
- $item->isParent = false;
- if(isset($item->parent) && $item->parent == -1)
- {
- /* When the parent is -1, the hierarchical structure is displayed incorrectly. */
- $item->parent = 0;
- $item->isParent = true;
- }
- if(!empty($item->parent) && isset($items[$item->parent]) && isset($item->type) && $item->type == 'stage') $items[$item->parent]->isParent = true;
- }
- return $items;
- }
- /**
- * Init column actions of a table.
- *
- * @param array $fieldList
- * @param string $actionMenu
- * @access public
- * @return void
- */
- function initTableActions(&$fieldList, $actionMenu)
- {
- $actions = explode('|', $actionMenu);
- foreach($actions as $action)
- {
- if(!isset($fieldList['actions']['list'][$action])) continue;
- $actionConfig = $fieldList['actions']['list'][$action];
- if(!empty($actionConfig['icon'])) $actionConfig['text'] = '';
- if(!empty($actionConfig['url']['module']) && !empty($actionConfig['url']['method']))
- {
- $module = $actionConfig['url']['module'];
- $method = $actionConfig['url']['method'];
- $params = !empty($actionConfig['url']['params']) ? $actionConfig['url']['params'] : array();
- $actionConfig['url'] = helper::createLink($module, $method, $params, '', !empty($actionConfig['url']['onlybody']));
- }
- $fieldList['actions']['actionsMap'][$action] = $actionConfig;
- }
- }
- /**
- * Init row actions of a item.
- *
- * @param object $item
- * @param string $actionMenu
- * @param array $actionList
- * @param object $model
- * @access public
- * @return bool
- */
- function initItemActions(&$item, $actionMenu, $actionList, $model)
- {
- if($actionMenu == 'divider')
- {
- $item->actions[] = array('name' => 'divider', 'type' => 'divider');
- return true;
- }
- global $app;
- $module = $model->getModuleName();
- if($module == 'flow') $module = $app->rawModule;
- $method = '';
- $isClickable = false;
- $actions = explode('|', $actionMenu);
- foreach($actions as $action)
- {
- if(!isset($actionList[$action])) continue;
- $actionConfig = $actionList[$action];
- $notLoadModel = !empty($actionConfig['notLoadModel']) ? $actionConfig['notLoadModel'] : false;
- if(!empty($actionConfig['url']['module']) && $module != $actionConfig['url']['module'])
- {
- $module = $actionConfig['url']['module'];
- if(!$notLoadModel)
- {
- $rawModule = $module == 'projectbuild' ? 'build' : $module;
- $model = $app->control->loadModel($rawModule);
- }
- }
- $method = $action;
- if(!empty($actionConfig['url']['method']) && $method != $actionConfig['url']['method']) $method = $actionConfig['url']['method'];
- if(!method_exists($model, 'isClickable') || $model->isClickable($item, !$notLoadModel ? $method : $action))
- {
- $isClickable = true;
- break;
- }
- }
- if(!$method || !common::hasPriv($module, $method, $item)) return $isClickable;
- /* Check flow conditions for this object. */
- if($model->config->edition != 'open')
- {
- static $flowActions = [];
- if(empty($flowActions[$module])) $flowActions[$module] = $model->loadModel('workflowaction')->getList($module);
- $model->loadModel('flow');
- foreach($flowActions[$module] as $flowAction)
- {
- if($flowAction->action == $method && $flowAction->extensionType != 'none' && $flowAction->status == 'enable' && !empty($flowAction->conditions))
- {
- $isClickable = $model->flow->checkConditions($flowAction->conditions, $item);
- }
- }
- }
- $item->actions[] = array('name' => $action, 'disabled' => !$isClickable);
- return $isClickable;
- }
- /**
- * 生成随机数。
- * Generate random number.
- *
- * @access public
- * @return int
- */
- function updateSessionRandom()
- {
- $random = mt_rand();
- $_SESSION['rand'] = $random;
- return $random;
- }
- /**
- * 获取可用的界面列表。
- * Get available vision list.
- *
- * @access public
- * @return array
- */
- function getVisions()
- {
- global $config, $lang;
- $visions = array_flip(array_unique(array_filter(explode(',', trim($config->visions, ',')))));
- $visionList = $lang->visionList;
- return array_intersect_key($visionList, $visions);
- }
- /**
- * Save debug log to the php log file which prefix with 'debug.<today>'.
- *
- * @param mixed ...$messages
- * @return void
- */
- function debug(...$messages)
- {
- if(count($messages) > 1)
- {
- foreach($messages as $message) debug($message);
- return;
- }
- $message = current($messages);
- static $times = [];
- $time = microtime(true);
- $duration = $times ? $time - end($times) : 0;
- $times[] = $time;
- static $counts = [];
- $count = $counts ? end($counts) + 1 : 1;
- $counts[] = $count;
- $logFile = dirname(__FILE__, 2) . '/tmp/log/debug.' . date('Ymd') . '.log.php';
- $uid = $_SERVER['HTTP_X_ZIN_UID'] ?? '';
- $count = sprintf('%04d', $count);
- $time = date('H:i:s');
- $duration = round($duration, 3);
- if($duration < 0.001) $duration = 0.001;
- if(is_object($message) || is_array($message)) $message = json_encode($message, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
- file_put_contents($logFile, $count . ($uid ? " uid=$uid" : '') . " time=$time duration={$duration}s message=$message\n", FILE_APPEND);
- }
- /**
- * 为数组使用字母排序。
- * Use alphabetical sorting for arrays.
- *
- * @param array $data
- * @param string $fieldName
- * @param string $suffix
- * @return void
- */
- function addPrefixToField(&$data, $fieldName, $suffix = '. ')
- {
- $key = 0;
- foreach($data as &$item)
- {
- $prefix = '';
- $index = $key;
- while($index >= 0)
- {
- $prefix = chr(65 + ($index % 26)) . $prefix;
- $index = floor($index / 26) - 1;
- }
- if(is_array($item))
- {
- $item[$fieldName] = $prefix . $suffix . $item[$fieldName];
- }
- else
- {
- $item->{$fieldName} = $prefix . $suffix . $item->{$fieldName};
- }
- $key++;
- }
- }
|