front.class.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. <?php
  2. /**
  3. * ZenTaoPHP的前端类。
  4. * The front class file of ZenTaoPHP framework.
  5. *
  6. * The author disclaims copyright to this source code. In place of
  7. * a legal notice, here is a blessing:
  8. *
  9. * May you do good and not evil.
  10. * May you find forgiveness for yourself and forgive others.
  11. * May you share freely, never taking more than you give.
  12. */
  13. helper::import(dirname(dirname(__FILE__)) . '/base/front/front.class.php');
  14. /**
  15. * html类,生成html标签。
  16. * The html class, to build html tags.
  17. *
  18. * @package framework
  19. */
  20. class html extends baseHTML
  21. {
  22. /**
  23. * 生成超链接。
  24. * Create tags like <a href="">text</a>
  25. *
  26. * @param string $href the link url.
  27. * @param string $title the link title.
  28. * @param string $misc other params.
  29. * @param string $newline
  30. * @static
  31. * @access public
  32. * @return string
  33. */
  34. static public function a($href = '', $title = '', $target = "_self", $misc = '', $newline = true)
  35. {
  36. if(empty($target)) $target = '_self';
  37. if($target != '_self') $misc .= " target='$target'";
  38. if($target == '_blank') $misc .= " rel='noopener noreferrer'";
  39. if(strpos($misc, 'disabled')) $href = '#';
  40. return parent::a($href, $title, $misc, $newline);
  41. }
  42. /**
  43. * 生成input输入标签。
  44. * Create tags like "<input type='text' />"
  45. *
  46. * @param string $name the name of the text input tag.
  47. * @param string $value the default value.
  48. * @param string $attrib other attribs.
  49. * @static
  50. * @access public
  51. * @return string
  52. */
  53. static public function input($name, $value = "", $attrib = "", $autocomplete = false)
  54. {
  55. $id = "id='$name'";
  56. $id = str_replace(array('[', ']'), "", $id);
  57. if(strpos($attrib, 'id=') !== false) $id = '';
  58. if(is_null($value)) $value = '';
  59. $value = str_replace("'", '&#039;', $value);
  60. $autocomplete = $autocomplete ? 'autocomplete="on"' : 'autocomplete="off"';
  61. return "<input type='text' name='$name' {$id} value='$value' $attrib $autocomplete />\n";
  62. }
  63. /**
  64. * 生成多选按钮。
  65. * Create tags like "<input type='checkbox' />"
  66. *
  67. * @param string $name the name of the checkbox tag.
  68. * @param array $options the array to create checkbox tag from.
  69. * @param string $checked the value to checked by default, can be item1,item2
  70. * @param string $attrib other attribs.
  71. * @param string $type inline or block
  72. * @static
  73. * @access public
  74. * @return string
  75. */
  76. static public function checkbox($name, $options, $checked = "", $attrib = "", $type = 'block')
  77. {
  78. $options = (array)($options);
  79. if(!is_array($options) or empty($options)) return false;
  80. if(is_array($checked)) $checked = implode(',', $checked);
  81. $string = '';
  82. $checked = ",$checked,";
  83. $isBlock = $type == 'block';
  84. foreach($options as $key => $value)
  85. {
  86. if($isBlock) $string .= "<div class='checkbox-primary'>";
  87. else $string .= "<div class='checkbox-primary checkbox-inline'>";
  88. $string .= "<input type='checkbox' name='{$name}[]' value='$key' ";
  89. $string .= (strpos($checked, ",$key,") !== false) ? " checked ='checked'" : "";
  90. $string .= $attrib;
  91. $string .= " id='$name$key' title='{$value}'/> ";
  92. $string .= "<label for='$name$key'>" . $value . '</label></div>';
  93. }
  94. return $string;
  95. }
  96. /**
  97. * 创建提交按钮。
  98. * Create submit button.
  99. *
  100. * @param string $label the label of the button
  101. * @param string $class the class of the button
  102. * @param string $misc other params
  103. * @static
  104. * @access public
  105. * @return string the submit button tag.
  106. */
  107. public static function submitButton($label = '', $misc = '', $class = 'btn btn-wide btn-primary')
  108. {
  109. return parent::submitButton($label, $class, $misc);
  110. }
  111. public static function commonButton($label = '', $misc = '', $class = 'btn', $icon = '')
  112. {
  113. return parent::commonButton($label, $class, $misc, $icon);
  114. }
  115. public static function linkButton($label = '', $link = '', $target = 'self', $misc = '', $class = 'btn')
  116. {
  117. return parent::linkButton($label, $link, $class, $misc, $target);
  118. }
  119. /**
  120. * 创建全选checkbox。
  121. * Create select buttons include 'selectAll' and 'selectReverse'.
  122. *
  123. * @param string $scope the scope of select reverse.
  124. * @param bool $asGroup
  125. * @param string $appendClass
  126. * @static
  127. * @access public
  128. * @return string
  129. */
  130. static public function selectButton($scope = "", $asGroup = true, $appendClass = 'btn')
  131. {
  132. global $lang;
  133. return "<div class='checkbox $appendClass'><label><input type='checkbox' data-scope='$scope' class='rows-selector'> $lang->select</label></div>";
  134. }
  135. /**
  136. * 生成select标签。
  137. * Create tags like "<select><option></option></select>"
  138. *
  139. * @param string $name the name of the select tag.
  140. * @param array $options the array to create select tag from.
  141. * @param string $selectedItems the item(s) to be selected, can like item1,item2.
  142. * @param string $attrib other params such as multiple, size and style.
  143. * @param string $append adjust if add options[$selectedItems].
  144. * @static
  145. * @access public
  146. * @return string
  147. */
  148. static public function select($name = '', $options = array(), $selectedItems = "", $attrib = "", $append = false)
  149. {
  150. $options = (array)($options);
  151. if($append and !isset($options[$selectedItems])) $options[$selectedItems] = $selectedItems;
  152. /* The begin. */
  153. $id = $name;
  154. if(strpos($name, '[') !== false) $id = trim(str_replace(']', '', str_replace('[', '', $name)));
  155. $id = "id='{$id}'";
  156. if(strpos($attrib, 'id=') !== false) $id = '';
  157. global $config;
  158. $convertedPinYin = (empty($config->isINT) and class_exists('common')) ? common::convert2Pinyin($options) : array();
  159. if(count($options) >= $config->maxCount or isset($config->moreLinks[$name]))
  160. {
  161. if(strpos($attrib, 'chosen') !== false)
  162. {
  163. $attrib = str_replace('chosen', 'picker-select', $attrib);
  164. $attrib = preg_replace('/data-drop[-_]?direction=([\'"]?)down([\'"]?)/i', 'data-drop-direction=$1bottom$2', $attrib);
  165. $attrib = preg_replace('/data-drop[-_]?direction=([\'"]?)up([\'"]?)/i', 'data-drop-direction=$1top$2', $attrib);
  166. }
  167. if(isset($config->moreLinks[$name]))
  168. {
  169. $link = $config->moreLinks[$name];
  170. $attrib .= " data-pickertype='remote' data-pickerremote='" . $link . "'";
  171. }
  172. }
  173. $string = "<select name='$name' {$id} $attrib>\n";
  174. /* The options. */
  175. if(is_array($selectedItems)) $selectedItems = implode(',', $selectedItems);
  176. $selectedItems = ",$selectedItems,";
  177. foreach($options as $key => $value)
  178. {
  179. $optionPinyin = zget($convertedPinYin, $value, '');
  180. $selected = strpos($selectedItems, ",$key,") !== false ? " selected='selected'" : '';
  181. $string .= "<option value='$key'$selected title='{$value}' data-keys='{$optionPinyin}'>$value</option>\n";
  182. }
  183. /* End. */
  184. return $string .= "</select>\n";
  185. }
  186. /**
  187. * Create input tag that type is number.
  188. *
  189. * @param string $name
  190. * @param string $value
  191. * @param string $attrib
  192. * @static
  193. * @access public
  194. * @return string
  195. */
  196. static public function number($name, $value = '', $attrib = '')
  197. {
  198. $id = "id='$name'";
  199. $id = str_replace(array('[', ']'), "", $id);
  200. if(strpos($attrib, 'id=') !== false) $id = '';
  201. $value = str_replace("'", '&#039;', $value);
  202. return "<input type='number' name='$name' {$id} value='$value' $attrib />\n";
  203. }
  204. /**
  205. * Convert a string to a uni code
  206. *
  207. * @param string $string
  208. * @return int
  209. */
  210. static public function stringToCode($string)
  211. {
  212. $stringLength = strlen($string);
  213. if($stringLength == 0) return 0;
  214. $code = 0;
  215. for($i = 0; $i < $stringLength; ++ $i) $code += ($i + 1) * ord($string[$i]);
  216. return $code;
  217. }
  218. /**
  219. * Create user avatar.
  220. *
  221. * @param string|object|array $user User object or user account
  222. * @param string|int $size Avatar size, can be a number or preset sizes: "xs", "sm", "", "lg", "xl", default is ""
  223. * @param string $className Avatar element class name, default is "avatar-circle"
  224. * @param string $attrib Extra attributes on avatar element
  225. * @param string $tag Avatar element tag name, default is "div"
  226. * @param string $hueDistance Hue distance used as background color for default avatar
  227. * @param string $saturation Saturation used as background color for default avatar
  228. * @param string $lightness Lightness used as background color for default avatar
  229. * @static
  230. * @access public
  231. * @return string
  232. */
  233. static public function avatar($user, $size = '', $className = 'avatar-circle', $attrib = '', $tag = 'div', $hueDistance = 43, $saturation = '40%', $lightness = '60%')
  234. {
  235. $userObj = new stdClass();
  236. if(is_string($user))
  237. {
  238. $userObj->account = $user;
  239. $user = $userObj;
  240. }
  241. elseif(is_array($user))
  242. {
  243. $userObj->avatar = $user['avatar'];
  244. $userObj->account = $user['account'];
  245. $userObj->name = isset($user['name']) ? $user['name'] : (isset($user['realname']) ? $user['realname'] : $user['account']);
  246. $user = $userObj;
  247. }
  248. elseif(is_object($user))
  249. {
  250. $userObj->avatar = isset($user->avatar) ? $user->avatar : '';
  251. $userObj->account = $user->account;
  252. $userObj->name = isset($user->name) ? $user->name : (isset($user->realname) ? $user->realname : $user->account);
  253. $user = $userObj;
  254. }
  255. $hasImage = !empty($user->avatar);
  256. $extraClassName = $hasImage ? ' has-img' : ' has-text';
  257. $style = '';
  258. if($size)
  259. {
  260. if(is_numeric($size)) $style .= "width: $size" . "px; height: $size" . "px; line-height: $size" . 'px;';
  261. $extraClassName .= " avatar-$size";
  262. }
  263. if(!$hasImage)
  264. {
  265. $colorHue = (html::stringToCode($user->account) * $hueDistance) % 360;
  266. $style .= "background: hsl($colorHue, $saturation, $lightness);";
  267. if(is_numeric($size)) $style .= 'font-size: ' . round($size / 2) . 'px;';
  268. }
  269. if(!empty($style)) $style = "style='$style'";
  270. $html = "<$tag class='avatar$extraClassName $className' $attrib $style>";
  271. if($hasImage)
  272. {
  273. $html .= html::image($user->avatar);
  274. }
  275. else
  276. {
  277. $mbLength = mb_strlen($user->name, 'utf-8');
  278. $strLength = strlen($user->name);
  279. $text = '';
  280. if($strLength === $mbLength)
  281. {
  282. /* Pure alphabet or numbers 纯英文情况 */
  283. $text .= strtoupper($user->name[0]);
  284. }
  285. else if($strLength % $mbLength == 0 && $strLength % 3 == 0)
  286. {
  287. /* Pure chinese characters 纯中文的情况 */
  288. $text .= $mbLength <= 2 ? $user->name : mb_substr($user->name, $mbLength - 2, $mbLength, 'utf-8');
  289. }
  290. else
  291. {
  292. /* Mix of Chinese and English 中英文混合的情况 */
  293. $text .= $mbLength <= 2 ? $user->name : mb_substr($user->name, 0, 2, 'utf-8');
  294. }
  295. $textLength = mb_strlen($text, 'utf-8');
  296. $html .= "<span class='text text-len-$textLength'>$text</span>";
  297. }
  298. $html .= "</$tag>";
  299. return $html;
  300. }
  301. /**
  302. * Create a small user avatar.
  303. *
  304. * @param string|object $user User object or user avatar url or user account
  305. * @param string $className Avatar element class name, default is "avatar-circle"
  306. * @param string $attrib Extra attributes on avatar element
  307. * @param string $tag Avatar element tag name, default is "div"
  308. * @static
  309. * @access public
  310. * @return string
  311. */
  312. static public function smallAvatar($user, $className = 'avatar-circle', $attrib = '', $tag = 'div')
  313. {
  314. return html::avatar($user, 'sm', $className, $attrib, $tag);
  315. }
  316. /**
  317. * Create a middle size user avatar.
  318. *
  319. * @param string|object $user User object or user avatar url or user account
  320. * @param string $className Avatar element class name, default is "avatar-circle"
  321. * @param string $attrib Extra attributes on avatar element
  322. * @param string $tag Avatar element tag name, default is "div"
  323. * @static
  324. * @access public
  325. * @return string
  326. */
  327. static public function middleAvatar($user, $className = 'avatar-circle', $attrib = '', $tag = 'div')
  328. {
  329. return html::avatar($user, 'md', $className, $attrib, $tag);
  330. }
  331. /**
  332. * Create a large user avatar.
  333. *
  334. * @param string|object $user User object or user avatar url or user account
  335. * @param string $className Avatar element class name, default is "avatar-circle"
  336. * @param string $attrib Extra attributes on avatar element
  337. * @param string $tag Avatar element tag name, default is "div"
  338. * @static
  339. * @access public
  340. * @return string
  341. */
  342. static public function largeAvatar($user, $className = 'avatar-circle', $attrib = '', $tag = 'div')
  343. {
  344. return html::avatar($user, 'lg', $className, $attrib, $tag);
  345. }
  346. /**
  347. * Create a progress ring.
  348. *
  349. * @param int progress Progress value, 0 ~ 100
  350. * @static
  351. * @access public
  352. * @return string
  353. */
  354. static public function ring($progress)
  355. {
  356. $progressVal = max(0, min(100, round($progress)));
  357. $ringPosition = ceil($progressVal / 2) * 24;
  358. return "<div class='ring' style='background-position-x: -{$ringPosition}px'><span>{$progressVal}</span></div>";
  359. }
  360. }
  361. /**
  362. * JS类。
  363. * JS class.
  364. *
  365. * @package front
  366. */
  367. class js extends baseJS
  368. {
  369. /**
  370. * Open a new app window.
  371. *
  372. * @param string $app
  373. * @param string $url
  374. * @static
  375. * @access public
  376. * @return string
  377. */
  378. static public function openEntry($app, $url)
  379. {
  380. return static::start() . "$.apps.open('$url', '$app')" . static::end();
  381. }
  382. /**
  383. * Generate the start of a js block, injects code for zentao client.
  384. *
  385. * @param bool $full
  386. * @static
  387. * @access public
  388. * @return string
  389. */
  390. static public function start($full = true)
  391. {
  392. if($full)
  393. {
  394. $document = "<html><meta charset='utf-8'/><style>body{background:white}</style><script>";
  395. if(isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'xuanxuan') != false)
  396. {
  397. /* Inject handler for confirm, prompt and alert. */
  398. $document .= <<<EOT
  399. window.confirm = function() {
  400. console.warn('\"window.confirm\" is disabled in webview.');
  401. return true;
  402. };
  403. window.prompt = function() {
  404. console.warn('\"window.prompt\" is disabled in webview.');
  405. };
  406. window.alert = function(msg) {
  407. const win = window.parent ? window.parent : window;
  408. win.open(`xxc://webview/alert/\${encodeURIComponent(msg)}`, '_blank');
  409. };
  410. EOT;
  411. }
  412. return $document;
  413. }
  414. return '<script>';
  415. }
  416. }
  417. /**
  418. * css类。
  419. * css class.
  420. *
  421. * @package front
  422. */
  423. class css extends baseCSS
  424. {
  425. }