国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1116 lines
46KB

  1. <?php
  2. if (!defined('DEDEINC')) exit("Request Error!");
  3. /**
  4. * 文档类
  5. *
  6. * @version $Id: arc.archives.class.php 4 15:13 2010年7月7日Z tianya $
  7. * @package DedeBIZ.Libraries
  8. * @copyright Copyright (c) 2020, DedeBIZ.COM
  9. * @license https://www.dedebiz.com/license
  10. * @link https://www.dedebiz.com
  11. */
  12. require_once(DEDEINC . "/typelink.class.php");
  13. require_once(DEDEINC . "/channelunit.class.php");
  14. require_once(DEDEINC . "/downmix.inc.php");
  15. require_once(DEDEINC . '/ftp.class.php');
  16. @set_time_limit(0);
  17. /**
  18. * 主文档类(Archives类)
  19. *
  20. * @package TypeLink
  21. * @subpackage DedeBIZ.Libraries
  22. * @link https://www.dedebiz.com
  23. */
  24. class Archives
  25. {
  26. var $TypeLink;
  27. var $ChannelUnit;
  28. var $dsql;
  29. var $Fields;
  30. var $dtp;
  31. var $ArcID;
  32. var $SplitPageField;
  33. var $SplitFields;
  34. var $NowPage;
  35. var $TotalPage;
  36. var $NameFirst;
  37. var $ShortName;
  38. var $FixedValues;
  39. var $TempSource;
  40. var $IsError;
  41. var $SplitTitles;
  42. var $PreNext;
  43. var $addTableRow;
  44. var $ftp;
  45. var $remoteDir;
  46. /**
  47. * php5构造函数
  48. *
  49. * @access public
  50. * @param int $aid 文档ID
  51. * @return string
  52. */
  53. function __construct($aid)
  54. {
  55. global $dsql, $ftp;
  56. $this->IsError = FALSE;
  57. $this->ArcID = $aid;
  58. $this->PreNext = array();
  59. $this->dsql = $dsql;
  60. $query = "SELECT channel,typeid FROM `#@__arctiny` WHERE id='$aid' ";
  61. $arr = $this->dsql->GetOne($query);
  62. if (!is_array($arr)) {
  63. $this->IsError = TRUE;
  64. } else {
  65. if ($arr['channel'] == 0) $arr['channel'] = 1;
  66. $this->ChannelUnit = new ChannelUnit($arr['channel'], $aid);
  67. $this->TypeLink = new TypeLink($arr['typeid']);
  68. if ($this->ChannelUnit->ChannelInfos['issystem'] != -1) {
  69. // 如果当前文档不是系统模型,为单表模型
  70. $query = "SELECT arc.*,tp.reid,tp.typedir,ch.addtable
  71. FROM `#@__archives` arc
  72. LEFT JOIN #@__arctype tp on tp.id=arc.typeid
  73. LEFT JOIN #@__channeltype as ch on arc.channel = ch.id
  74. WHERE arc.id='$aid' ";
  75. $this->Fields = $this->dsql->GetOne($query);
  76. } else {
  77. $this->Fields['title'] = '';
  78. $this->Fields['money'] = $this->Fields['arcrank'] = 0;
  79. $this->Fields['senddate'] = $this->Fields['pubdate'] = $this->Fields['mid'] = $this->Fields['adminid'] = 0;
  80. $this->Fields['ismake'] = 1;
  81. $this->Fields['filename'] = '';
  82. }
  83. if ($this->TypeLink->TypeInfos['corank'] > 0 && $this->Fields['arcrank'] == 0) {
  84. $this->Fields['arcrank'] = $this->TypeLink->TypeInfos['corank'];
  85. }
  86. $this->Fields['tags'] = GetTags($aid);
  87. $this->dtp = new DedeTagParse();
  88. $this->dtp->SetRefObj($this);
  89. $this->SplitPageField = $this->ChannelUnit->SplitPageField;
  90. $this->SplitFields = '';
  91. $this->TotalPage = 1;
  92. $this->NameFirst = '';
  93. $this->ShortName = 'html';
  94. $this->FixedValues = '';
  95. $this->TempSource = '';
  96. $this->ftp = &$ftp;
  97. $this->remoteDir = '';
  98. if (empty($GLOBALS['pageno'])) {
  99. $this->NowPage = 1;
  100. } else {
  101. $this->NowPage = $GLOBALS['pageno'];
  102. }
  103. //特殊的字段数据处理
  104. $this->Fields['aid'] = $aid;
  105. $this->Fields['id'] = $aid;
  106. $this->Fields['position'] = $this->TypeLink->GetPositionLink(TRUE);
  107. $this->Fields['typeid'] = $arr['typeid'];
  108. //设置一些全局参数的值
  109. foreach ($GLOBALS['PubFields'] as $k => $v) {
  110. $this->Fields[$k] = $v;
  111. }
  112. //为了减少重复查询,这里直接把附加表查询记录放在 $this->addTableRow 中,在 ParAddTable() 不再查询
  113. if ($this->ChannelUnit->ChannelInfos['addtable'] != '') {
  114. $query = "SELECT * FROM `{$this->ChannelUnit->ChannelInfos['addtable']}` WHERE `aid` = '$aid'";
  115. $this->addTableRow = $this->dsql->GetOne($query);
  116. }
  117. //issystem==-1 表示单表模型,单表模型不支持redirecturl这类参数,因此限定内容普通模型才进行下面查询
  118. if ($this->ChannelUnit->ChannelInfos['addtable'] != '' && $this->ChannelUnit->ChannelInfos['issystem'] != -1) {
  119. if (is_array($this->addTableRow)) {
  120. $this->Fields['redirecturl'] = $this->addTableRow['redirecturl'];
  121. $this->Fields['templet'] = $this->addTableRow['templet'];
  122. $this->Fields['userip'] = $this->addTableRow['userip'];
  123. }
  124. $this->Fields['templet'] = (empty($this->Fields['templet']) ? '' : trim($this->Fields['templet']));
  125. $this->Fields['redirecturl'] = (empty($this->Fields['redirecturl']) ? '' : trim($this->Fields['redirecturl']));
  126. $this->Fields['userip'] = (empty($this->Fields['userip']) ? '' : trim($this->Fields['userip']));
  127. } else {
  128. $this->Fields['templet'] = $this->Fields['redirecturl'] = '';
  129. }
  130. } //!error
  131. }
  132. //php4构造函数
  133. function Archives($aid)
  134. {
  135. $this->__construct($aid);
  136. }
  137. /**
  138. * 解析附加表的内容
  139. *
  140. * @access public
  141. * @return void
  142. */
  143. function ParAddTable()
  144. {
  145. //读取附加表信息,并把附加表的资料经过编译处理后导入到$this->Fields中,以方便在模板中用 {dede:field name='fieldname' /} 标记统一调用
  146. if ($this->ChannelUnit->ChannelInfos['addtable'] != '') {
  147. $row = $this->addTableRow;
  148. if ($this->ChannelUnit->ChannelInfos['issystem'] == -1) {
  149. $this->Fields['title'] = $row['title'];
  150. $this->Fields['senddate'] = $this->Fields['pubdate'] = $row['senddate'];
  151. $this->Fields['mid'] = $this->Fields['adminid'] = $row['mid'];
  152. $this->Fields['ismake'] = 1;
  153. $this->Fields['arcrank'] = 0;
  154. $this->Fields['money'] = 0;
  155. $this->Fields['filename'] = '';
  156. }
  157. if (is_array($row)) {
  158. foreach ($row as $k => $v) $row[strtolower($k)] = $v;
  159. }
  160. if (is_array($this->ChannelUnit->ChannelFields) && !empty($this->ChannelUnit->ChannelFields)) {
  161. foreach ($this->ChannelUnit->ChannelFields as $k => $arr) {
  162. if (isset($row[$k])) {
  163. if (!empty($arr['rename'])) {
  164. $nk = $arr['rename'];
  165. } else {
  166. $nk = $k;
  167. }
  168. $cobj = $this->GetCurTag($k);
  169. if (is_object($cobj)) {
  170. foreach ($this->dtp->CTags as $ctag) {
  171. if ($ctag->GetTagName() == 'field' && $ctag->GetAtt('name') == $k) {
  172. //带标识的专题节点
  173. if ($ctag->GetAtt('noteid') != '') {
  174. $this->Fields[$k . '_' . $ctag->GetAtt('noteid')] = $this->ChannelUnit->MakeField($k, $row[$k], $ctag);
  175. }
  176. //带类型的字段节点
  177. else if ($ctag->GetAtt('type') != '') {
  178. $this->Fields[$k . '_' . $ctag->GetAtt('type')] = $this->ChannelUnit->MakeField($k, $row[$k], $ctag);
  179. }
  180. //其它字段
  181. else {
  182. $this->Fields[$nk] = $this->ChannelUnit->MakeField($k, $row[$k], $ctag);
  183. }
  184. }
  185. }
  186. } else {
  187. $this->Fields[$nk] = $row[$k];
  188. }
  189. if ($arr['type'] == 'htmltext' && $GLOBALS['cfg_keyword_replace'] == 'Y' && !empty($this->Fields['keywords'])) {
  190. $this->Fields[$nk] = $this->ReplaceKeyword($this->Fields['keywords'], $this->Fields[$nk]);
  191. }
  192. }
  193. } //End foreach
  194. }
  195. //设置全局环境变量
  196. $this->Fields['typename'] = $this->TypeLink->TypeInfos['typename'];
  197. @SetSysEnv($this->Fields['typeid'], $this->Fields['typename'], $this->Fields['id'], $this->Fields['title'], 'archives');
  198. }
  199. //完成附加表信息读取
  200. unset($row);
  201. //处理要分页显示的字段
  202. $this->SplitTitles = array();
  203. if ($this->SplitPageField != '' && $GLOBALS['cfg_arcsptitle'] = 'Y'
  204. && isset($this->Fields[$this->SplitPageField])
  205. ) {
  206. $this->SplitFields = explode("#p#", $this->Fields[$this->SplitPageField]);
  207. $i = 1;
  208. foreach ($this->SplitFields as $k => $v) {
  209. $tmpv = cn_substr($v, 50);
  210. $pos = strpos($tmpv, '#e#');
  211. if ($pos > 0) {
  212. $st = trim(cn_substr($tmpv, $pos));
  213. if ($st == "" || $st == "副标题" || $st == "分页标题") {
  214. $this->SplitFields[$k] = preg_replace("/^(.*)#e#/is", "", $v);
  215. continue;
  216. } else {
  217. $this->SplitFields[$k] = preg_replace("/^(.*)#e#/is", "", $v);
  218. $this->SplitTitles[$k] = $st;
  219. }
  220. } else {
  221. continue;
  222. }
  223. $i++;
  224. }
  225. $this->TotalPage = count($this->SplitFields);
  226. $this->Fields['totalpage'] = $this->TotalPage;
  227. }
  228. //处理默认缩略图等
  229. if (isset($this->Fields['litpic'])) {
  230. if ($this->Fields['litpic'] == '-' || $this->Fields['litpic'] == '') {
  231. $this->Fields['litpic'] = $GLOBALS['cfg_cmspath'] . '/static/defaultpic.jpg';
  232. }
  233. if (!preg_match("#^http:\/\/#i", $this->Fields['litpic']) && $GLOBALS['cfg_multi_site'] == 'Y') {
  234. $this->Fields['litpic'] = $GLOBALS['cfg_mainsite'] . $this->Fields['litpic'];
  235. }
  236. $this->Fields['picname'] = $this->Fields['litpic'];
  237. //模板里直接使用{dede:field name='image'/}获取缩略图
  238. $this->Fields['image'] = (!preg_match('/jpg|gif|png/i', $this->Fields['picname']) ? '' : "<img src='{$this->Fields['picname']}' />");
  239. }
  240. // 处理投票选项
  241. if (isset($this->Fields['voteid']) && !empty($this->Fields['voteid'])) {
  242. $this->Fields['vote'] = '';
  243. $voteid = $this->Fields['voteid'];
  244. $this->Fields['vote'] = "<script language='javascript' src='{$GLOBALS['cfg_cmspath']}/data/vote/vote_{$voteid}.js'></script>";
  245. if ($GLOBALS['cfg_multi_site'] == 'Y') {
  246. $this->Fields['vote'] = "<script language='javascript' src='{$GLOBALS['cfg_mainsite']}/data/vote/vote_{$voteid}.js'></script>";
  247. }
  248. }
  249. if (isset($this->Fields['goodpost']) && isset($this->Fields['badpost'])) {
  250. //digg
  251. if ($this->Fields['goodpost'] + $this->Fields['badpost'] == 0) {
  252. $this->Fields['goodper'] = $this->Fields['badper'] = 0;
  253. } else {
  254. $this->Fields['goodper'] = number_format($this->Fields['goodpost'] / ($this->Fields['goodpost'] + $this->Fields['badpost']), 3) * 100;
  255. $this->Fields['badper'] = 100 - $this->Fields['goodper'];
  256. }
  257. }
  258. }
  259. //获得当前字段参数
  260. function GetCurTag($fieldname)
  261. {
  262. if (!isset($this->dtp->CTags)) {
  263. return '';
  264. }
  265. foreach ($this->dtp->CTags as $ctag) {
  266. if ($ctag->GetTagName() == 'field' && $ctag->GetAtt('name') == $fieldname) {
  267. return $ctag;
  268. } else {
  269. continue;
  270. }
  271. }
  272. return '';
  273. }
  274. /**
  275. * 生成静态HTML
  276. *
  277. * @access public
  278. * @param int $isremote 是否远程
  279. * @return string
  280. */
  281. function MakeHtml($isremote = 0)
  282. {
  283. global $fileFirst, $baidu_seo, $cfg_basehost;
  284. if ($this->IsError) {
  285. return '';
  286. }
  287. $this->Fields["displaytype"] = "st";
  288. //预编译$th
  289. $this->LoadTemplet();
  290. $this->ParAddTable();
  291. $this->ParseTempletsFirst();
  292. $this->Fields['senddate'] = empty($this->Fields['senddate']) ? '' : $this->Fields['senddate'];
  293. $this->Fields['title'] = empty($this->Fields['title']) ? '' : $this->Fields['title'];
  294. $this->Fields['arcrank'] = empty($this->Fields['arcrank']) ? 0 : $this->Fields['arcrank'];
  295. $this->Fields['ismake'] = empty($this->Fields['ismake']) ? 0 : $this->Fields['ismake'];
  296. $this->Fields['money'] = empty($this->Fields['money']) ? 0 : $this->Fields['money'];
  297. $this->Fields['filename'] = empty($this->Fields['filename']) ? '' : $this->Fields['filename'];
  298. //分析要创建的文件名称
  299. $filename = GetFileNewName(
  300. $this->ArcID,
  301. $this->Fields['typeid'],
  302. $this->Fields['senddate'],
  303. $this->Fields['title'],
  304. $this->Fields['ismake'],
  305. $this->Fields['arcrank'],
  306. $this->TypeLink->TypeInfos['namerule'],
  307. $this->TypeLink->TypeInfos['typedir'],
  308. $this->Fields['money'],
  309. $this->Fields['filename']
  310. );
  311. $filenames = explode(".", $filename);
  312. $this->ShortName = $filenames[count($filenames) - 1];
  313. if ($this->ShortName == '') $this->ShortName = 'html';
  314. $fileFirst = preg_replace("/\." . $this->ShortName . "$/i", "", $filename);
  315. $this->Fields['namehand'] = basename($fileFirst);
  316. $filenames = explode("/", $filename);
  317. $this->NameFirst = preg_replace("/\." . $this->ShortName . "$/i", "", $filenames[count($filenames) - 1]);
  318. if ($this->NameFirst == '') {
  319. $this->NameFirst = $this->arcID;
  320. }
  321. //获得当前文档的全名
  322. $filenameFull = GetFileUrl(
  323. $this->ArcID,
  324. $this->Fields['typeid'],
  325. $this->Fields["senddate"],
  326. $this->Fields["title"],
  327. $this->Fields["ismake"],
  328. $this->Fields["arcrank"],
  329. $this->TypeLink->TypeInfos['namerule'],
  330. $this->TypeLink->TypeInfos['typedir'],
  331. $this->Fields["money"],
  332. $this->Fields['filename'],
  333. $this->TypeLink->TypeInfos['moresite'],
  334. $this->TypeLink->TypeInfos['siteurl'],
  335. $this->TypeLink->TypeInfos['sitepath']
  336. );
  337. $this->Fields['arcurl'] = $this->Fields['fullname'] = $filenameFull;
  338. //对于已设置不生成HTML的文章直接返回网址
  339. if (
  340. $this->Fields['ismake'] == -1 || $this->Fields['arcrank'] != 0 || $this->Fields['money'] > 0
  341. || ($this->Fields['typeid'] == 0 && $this->Fields['channel'] != -1)
  342. ) {
  343. return $this->GetTrueUrl($filename);
  344. }
  345. //循环生成HTML文件
  346. else {
  347. $seoUrls = array();
  348. for ($i = 1; $i <= $this->TotalPage; $i++) {
  349. if ($this->TotalPage > 1) {
  350. $this->Fields['tmptitle'] = (empty($this->Fields['tmptitle']) ? $this->Fields['title'] : $this->Fields['tmptitle']);
  351. if ($i > 1) $this->Fields['title'] = $this->Fields['tmptitle'] . "($i)";
  352. }
  353. if ($i > 1) {
  354. $TRUEfilename = $this->GetTruePath() . $fileFirst . "_" . $i . "." . $this->ShortName;
  355. $URLFilename = $fileFirst . "_" . $i . "." . $this->ShortName;
  356. } else {
  357. $TRUEfilename = $this->GetTruePath() . $filename;
  358. $URLFilename = $filename;
  359. }
  360. $seoUrls = array_merge($seoUrls, array($cfg_basehost . $URLFilename));
  361. $this->ParseDMFields($i, 1);
  362. $this->dtp->SaveTo($TRUEfilename);
  363. }
  364. if ($baidu_seo == true) {
  365. $api = 'http://data.zz.baidu.com/urls?site=https://www.zixue.cn&token=vXkBb4Ot0yhOFcmP';
  366. $ch = curl_init();
  367. $options = array(
  368. CURLOPT_URL => $api,
  369. CURLOPT_POST => true,
  370. CURLOPT_RETURNTRANSFER => true,
  371. CURLOPT_POSTFIELDS => implode("\n", $seoUrls),
  372. CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
  373. );
  374. curl_setopt_array($ch, $options);
  375. $result = curl_exec($ch);
  376. $rs = json_decode($result, true);
  377. if ($rs["success"] == 1) {
  378. echo "百度搜索引擎提交成功,剩余次数:" . $rs["remain"] . "<br/>\r\n";
  379. }
  380. }
  381. }
  382. $this->dsql->ExecuteNoneQuery("Update `#@__archives` SET ismake=1 WHERE id='" . $this->ArcID . "'");
  383. return $this->GetTrueUrl($filename);
  384. }
  385. /**
  386. * 获得真实连接路径
  387. *
  388. * @access public
  389. * @param string $nurl 连接
  390. * @return string
  391. */
  392. function GetTrueUrl($nurl)
  393. {
  394. return GetFileUrl(
  395. $this->Fields['id'],
  396. $this->Fields['typeid'],
  397. $this->Fields['senddate'],
  398. $this->Fields['title'],
  399. $this->Fields['ismake'],
  400. $this->Fields['arcrank'],
  401. $this->TypeLink->TypeInfos['namerule'],
  402. $this->TypeLink->TypeInfos['typedir'],
  403. $this->Fields['money'],
  404. $this->Fields['filename'],
  405. $this->TypeLink->TypeInfos['moresite'],
  406. $this->TypeLink->TypeInfos['siteurl'],
  407. $this->TypeLink->TypeInfos['sitepath']
  408. );
  409. }
  410. /**
  411. * 获得站点的真实根路径
  412. *
  413. * @access public
  414. * @return string
  415. */
  416. function GetTruePath()
  417. {
  418. $TRUEpath = $GLOBALS["cfg_basedir"];
  419. return $TRUEpath;
  420. }
  421. /**
  422. * 获得指定键值的字段
  423. *
  424. * @access public
  425. * @param string $fname 键名称
  426. * @param string $ctag 标记
  427. * @return string
  428. */
  429. function GetField($fname, $ctag)
  430. {
  431. //所有Field数组 OR 普通Field
  432. if ($fname == 'array') {
  433. return $this->Fields;
  434. }
  435. //指定了ID的节点
  436. else if ($ctag->GetAtt('noteid') != '') {
  437. if (isset($this->Fields[$fname . '_' . $ctag->GetAtt('noteid')])) {
  438. return $this->Fields[$fname . '_' . $ctag->GetAtt('noteid')];
  439. }
  440. }
  441. //指定了type的节点
  442. else if ($ctag->GetAtt('type') != '') {
  443. if (isset($this->Fields[$fname . '_' . $ctag->GetAtt('type')])) {
  444. return $this->Fields[$fname . '_' . $ctag->GetAtt('type')];
  445. }
  446. } else if (isset($this->Fields[$fname])) {
  447. return $this->Fields[$fname];
  448. }
  449. return '';
  450. }
  451. /**
  452. * 获得模板文件位置
  453. *
  454. * @access public
  455. * @return string
  456. */
  457. function GetTempletFile()
  458. {
  459. global $cfg_basedir, $cfg_templets_dir, $cfg_df_style;
  460. $cid = $this->ChannelUnit->ChannelInfos['nid'];
  461. if (!empty($this->Fields['templet'])) {
  462. $filetag = MfTemplet($this->Fields['templet']);
  463. if (!preg_match("#\/#", $filetag)) $filetag = $GLOBALS['cfg_df_style'] . '/' . $filetag;
  464. } else {
  465. $filetag = MfTemplet($this->TypeLink->TypeInfos["temparticle"]);
  466. }
  467. $tid = $this->Fields['typeid'];
  468. $filetag = str_replace('{cid}', $cid, $filetag);
  469. $filetag = str_replace('{tid}', $tid, $filetag);
  470. $tmpfile = $cfg_basedir . $cfg_templets_dir . '/' . $filetag;
  471. if ($cid == 'spec') {
  472. if (!empty($this->Fields['templet'])) {
  473. $tmpfile = $cfg_basedir . $cfg_templets_dir . '/' . $filetag;
  474. } else {
  475. $tmpfile = $cfg_basedir . $cfg_templets_dir . "/{$cfg_df_style}/article_spec.htm";
  476. }
  477. }
  478. if (defined('DEDEMOB')) {
  479. $tmpfile = str_replace('.htm', '_m.htm', $tmpfile);
  480. }
  481. if (!file_exists($tmpfile)) {
  482. $tmpfile = $cfg_basedir . $cfg_templets_dir . "/{$cfg_df_style}/" . ($cid == 'spec' ? 'article_spec.htm' : 'article_default.htm');
  483. if (defined('DEDEMOB')) {
  484. $tmpfile = str_replace('.htm', '_m.htm', $tmpfile);
  485. }
  486. }
  487. if (!preg_match("#.htm$#", $tmpfile)) return FALSE;
  488. return $tmpfile;
  489. }
  490. /**
  491. * 动态输出结果
  492. *
  493. * @access public
  494. * @return void
  495. */
  496. function display()
  497. {
  498. global $htmltype;
  499. if ($this->IsError) {
  500. return '';
  501. }
  502. $this->Fields["displaytype"] = "dm";
  503. if ($this->NowPage > 1) $this->Fields["title"] = $this->Fields["title"] . "({$this->NowPage})";
  504. //预编译
  505. $this->LoadTemplet();
  506. $this->ParAddTable();
  507. $this->ParseTempletsFirst();
  508. //跳转网址
  509. $this->Fields['flag'] = empty($this->Fields['flag']) ? "" : $this->Fields['flag'];
  510. if (preg_match("#j#", $this->Fields['flag']) && $this->Fields['redirecturl'] != '') {
  511. if ($GLOBALS['cfg_jump_once'] == 'N') {
  512. $pageHtml = "<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" . $GLOBALS['cfg_soft_lang'] . "\">\r\n<title>" . $this->Fields['title'] . "</title>\r\n";
  513. $pageHtml .= "<meta http-equiv=\"refresh\" content=\"3;URL=" . $this->Fields['redirecturl'] . "\">\r\n</head>\r\n<body>\r\n";
  514. $pageHtml .= "现在正在转向:" . $this->Fields['title'] . ",请稍候...<br/><br/>\r\n转向内容简介:" . $this->Fields['description'] . "\r\n</body>\r\n</html>\r\n";
  515. echo $pageHtml;
  516. } else {
  517. header("location:{$this->Fields['redirecturl']}");
  518. }
  519. exit();
  520. }
  521. $pageCount = $this->NowPage;
  522. $this->ParseDMFields($pageCount, 0);
  523. $this->dtp->display();
  524. }
  525. /**
  526. * 载入模板
  527. *
  528. * @access public
  529. * @return void
  530. */
  531. function LoadTemplet()
  532. {
  533. if ($this->TempSource == '') {
  534. $tempfile = $this->GetTempletFile();
  535. if (!file_exists($tempfile) || !is_file($tempfile)) {
  536. echo "文档ID:{$this->Fields['id']} - {$this->TypeLink->TypeInfos['typename']} - {$this->Fields['title']}<br />";
  537. echo "模板文件不存在,无法解析文档!";
  538. exit();
  539. }
  540. $this->dtp->LoadTemplate($tempfile);
  541. $this->TempSource = $this->dtp->SourceString;
  542. } else {
  543. $this->dtp->LoadSource($this->TempSource);
  544. }
  545. }
  546. /**
  547. * 解析模板,对固定的标记进行初始给值
  548. *
  549. * @access public
  550. * @return void
  551. */
  552. function ParseTempletsFirst()
  553. {
  554. if (empty($this->Fields['keywords'])) {
  555. $this->Fields['keywords'] = '';
  556. }
  557. if (empty($this->Fields['reid'])) {
  558. $this->Fields['reid'] = 0;
  559. }
  560. $GLOBALS['envs']['tags'] = $this->Fields['tags'];
  561. if (isset($this->TypeLink->TypeInfos['reid'])) {
  562. $GLOBALS['envs']['reid'] = $this->TypeLink->TypeInfos['reid'];
  563. }
  564. $GLOBALS['envs']['keyword'] = $this->Fields['keywords'];
  565. $GLOBALS['envs']['typeid'] = $this->Fields['typeid'];
  566. $GLOBALS['envs']['topid'] = GetTopid($this->Fields['typeid']);
  567. $GLOBALS['envs']['aid'] = $GLOBALS['envs']['id'] = $this->Fields['id'];
  568. $GLOBALS['envs']['adminid'] = $GLOBALS['envs']['mid'] = isset($this->Fields['mid']) ? $this->Fields['mid'] : 1;
  569. $GLOBALS['envs']['channelid'] = $this->TypeLink->TypeInfos['channeltype'];
  570. if ($this->Fields['reid'] > 0) {
  571. $GLOBALS['envs']['typeid'] = $this->Fields['reid'];
  572. }
  573. MakeOneTag($this->dtp, $this, 'N');
  574. }
  575. /**
  576. * 解析模板,对内容里的变动进行赋值
  577. *
  578. * @access public
  579. * @param string $pageNo 页码数
  580. * @param string $ismake 是否生成
  581. * @return string
  582. */
  583. function ParseDMFields($pageNo, $ismake = 1)
  584. {
  585. $this->NowPage = $pageNo;
  586. $this->Fields['nowpage'] = $this->NowPage;
  587. if ($this->SplitPageField != '' && isset($this->Fields[$this->SplitPageField])) {
  588. $this->Fields[$this->SplitPageField] = $this->SplitFields[$pageNo - 1];
  589. if ($pageNo > 1) $this->Fields['description'] = trim(preg_replace("/[\r\n\t]/", ' ', cn_substr(html2text($this->Fields[$this->SplitPageField]), 200)));
  590. }
  591. //解析模板
  592. if (is_array($this->dtp->CTags)) {
  593. foreach ($this->dtp->CTags as $i => $ctag) {
  594. if ($ctag->GetName() == 'field') {
  595. $this->dtp->Assign($i, $this->GetField($ctag->GetAtt('name'), $ctag));
  596. } else if ($ctag->GetName() == 'pagebreak') {
  597. if ($ismake == 0) {
  598. $this->dtp->Assign($i, $this->GetPagebreakDM($this->TotalPage, $this->NowPage, $this->ArcID));
  599. } else {
  600. $this->dtp->Assign($i, $this->GetPagebreak($this->TotalPage, $this->NowPage, $this->ArcID));
  601. }
  602. } else if ($ctag->GetName() == 'pagetitle') {
  603. if ($ismake == 0) {
  604. $this->dtp->Assign($i, $this->GetPageTitlesDM($ctag->GetAtt("style"), $pageNo));
  605. } else {
  606. $this->dtp->Assign($i, $this->GetPageTitlesST($ctag->GetAtt("style"), $pageNo));
  607. }
  608. } else if ($ctag->GetName() == 'prenext') {
  609. $this->dtp->Assign($i, $this->GetPreNext($ctag->GetAtt('get')));
  610. } else if ($ctag->GetName() == 'fieldlist') {
  611. $innertext = trim($ctag->GetInnerText());
  612. if ($innertext == '') $innertext = GetSysTemplets('tag_fieldlist.htm');
  613. $dtp2 = new DedeTagParse();
  614. $dtp2->SetNameSpace('field', '[', ']');
  615. $dtp2->LoadSource($innertext);
  616. $oldSource = $dtp2->SourceString;
  617. $oldCtags = $dtp2->CTags;
  618. $res = '';
  619. if (is_array($this->ChannelUnit->ChannelFields) && is_array($dtp2->CTags)) {
  620. foreach ($this->ChannelUnit->ChannelFields as $k => $v) {
  621. if (isset($v['autofield']) && empty($v['autofield'])) {
  622. continue;
  623. }
  624. $dtp2->SourceString = $oldSource;
  625. $dtp2->CTags = $oldCtags;
  626. $fname = $v['itemname'];
  627. foreach ($dtp2->CTags as $tid => $ctag2) {
  628. if ($ctag2->GetName() == 'name') {
  629. $dtp2->Assign($tid, $fname);
  630. } else if ($ctag2->GetName() == 'tagname') {
  631. $dtp2->Assign($tid, $k);
  632. } else if ($ctag2->GetName() == 'value') {
  633. $this->Fields[$k] = $this->ChannelUnit->MakeField($k, $this->Fields[$k], $ctag2);
  634. @$dtp2->Assign($tid, $this->Fields[$k]);
  635. }
  636. }
  637. $res .= $dtp2->GetResult();
  638. }
  639. }
  640. $this->dtp->Assign($i, $res);
  641. } //end case
  642. } //结束模板循环
  643. }
  644. }
  645. /**
  646. * 关闭所占用的资源
  647. *
  648. * @access public
  649. * @return void
  650. */
  651. function Close()
  652. {
  653. $this->FixedValues = '';
  654. $this->Fields = '';
  655. }
  656. /**
  657. * 获取上一篇,下一篇链接
  658. *
  659. * @access public
  660. * @param string $gtype 获取类型
  661. * pre:上一篇 preimg:上一篇图片 next:下一篇 nextimg:下一篇图片
  662. * @return string
  663. */
  664. function GetPreNext($gtype = '')
  665. {
  666. $rs = '';
  667. if (count($this->PreNext) < 2) {
  668. $aid = $this->ArcID;
  669. $preR = $this->dsql->GetOne("Select id From `#@__arctiny` where id<$aid And arcrank>-1 And typeid='{$this->Fields['typeid']}' order by id desc");
  670. $nextR = $this->dsql->GetOne("Select id From `#@__arctiny` where id>$aid And arcrank>-1 And typeid='{$this->Fields['typeid']}' order by id asc");
  671. $next = (is_array($nextR) ? " where arc.id={$nextR['id']} " : ' where 1>2 ');
  672. $pre = (is_array($preR) ? " where arc.id={$preR['id']} " : ' where 1>2 ');
  673. $query = "Select arc.id,arc.title,arc.shorttitle,arc.typeid,arc.ismake,arc.senddate,arc.arcrank,arc.money,arc.filename,arc.litpic,
  674. t.typedir,t.typename,t.namerule,t.namerule2,t.ispart,t.moresite,t.siteurl,t.sitepath
  675. from `#@__archives` arc left join #@__arctype t on arc.typeid=t.id ";
  676. $nextRow = $this->dsql->GetOne($query . $next);
  677. $preRow = $this->dsql->GetOne($query . $pre);
  678. if (is_array($preRow)) {
  679. if (defined('DEDEMOB')) {
  680. $mlink = 'view.php?aid=' . $preRow['id'];
  681. } else {
  682. $mlink = GetFileUrl(
  683. $preRow['id'],
  684. $preRow['typeid'],
  685. $preRow['senddate'],
  686. $preRow['title'],
  687. $preRow['ismake'],
  688. $preRow['arcrank'],
  689. $preRow['namerule'],
  690. $preRow['typedir'],
  691. $preRow['money'],
  692. $preRow['filename'],
  693. $preRow['moresite'],
  694. $preRow['siteurl'],
  695. $preRow['sitepath']
  696. );
  697. }
  698. $this->PreNext['pre'] = "上一篇:<a href='$mlink'>{$preRow['title']}</a> ";
  699. $this->PreNext['preimg'] = "<a href='$mlink'><img src=\"{$preRow['litpic']}\" alt=\"{$preRow['title']}\"/></a> ";
  700. } else {
  701. $this->PreNext['pre'] = "上一篇:没有了 ";
  702. $this->PreNext['preimg'] = "<img src=\"/templets/default/images/nophoto.jpg\" alt=\"对不起,没有上一图集了!\"/>";
  703. }
  704. if (is_array($nextRow)) {
  705. if (defined('DEDEMOB')) {
  706. $mlink = 'view.php?aid=' . $preRow['id'];
  707. } else {
  708. $mlink = GetFileUrl(
  709. $nextRow['id'],
  710. $nextRow['typeid'],
  711. $nextRow['senddate'],
  712. $nextRow['title'],
  713. $nextRow['ismake'],
  714. $nextRow['arcrank'],
  715. $nextRow['namerule'],
  716. $nextRow['typedir'],
  717. $nextRow['money'],
  718. $nextRow['filename'],
  719. $nextRow['moresite'],
  720. $nextRow['siteurl'],
  721. $nextRow['sitepath']
  722. );
  723. }
  724. $this->PreNext['next'] = "下一篇:<a href='$mlink'>{$nextRow['title']}</a> ";
  725. $this->PreNext['nextimg'] = "<a href='$mlink'><img src=\"{$nextRow['litpic']}\" alt=\"{$nextRow['title']}\"/></a> ";
  726. } else {
  727. $this->PreNext['next'] = "下一篇:没有了 ";
  728. $this->PreNext['nextimg'] = "<a href='javascript:void(0)' alt=\"\"><img src=\"/templets/default/images/nophoto.jpg\" alt=\"对不起,没有下一图集了!\"/></a>";
  729. }
  730. }
  731. if ($gtype == 'pre') {
  732. $rs = $this->PreNext['pre'];
  733. } else if ($gtype == 'preimg') {
  734. $rs = $this->PreNext['preimg'];
  735. } else if ($gtype == 'next') {
  736. $rs = $this->PreNext['next'];
  737. } else if ($gtype == 'nextimg') {
  738. $rs = $this->PreNext['nextimg'];
  739. } else {
  740. $rs = $this->PreNext['pre'] . " &nbsp; " . $this->PreNext['next'];
  741. }
  742. return $rs;
  743. }
  744. /**
  745. * 获得动态页面分页列表
  746. *
  747. * @access public
  748. * @param int $totalPage 总页数
  749. * @param int $nowPage 当前页数
  750. * @param int $aid 文档id
  751. * @return string
  752. */
  753. function GetPagebreakDM($totalPage, $nowPage, $aid)
  754. {
  755. global $cfg_rewrite;
  756. if ($totalPage == 1) {
  757. return "";
  758. }
  759. $PageList = "<li class='page-item d-none d-sm-block disabled'><span class=\"page-link\">共" . $totalPage . "页: </span></li>";
  760. $nPage = $nowPage - 1;
  761. $lPage = $nowPage + 1;
  762. if ($nowPage == 1) {
  763. $PageList .= "<li class='page-item d-none d-sm-block disabled'><a class='page-link' href='#'>上一页</a></li>";
  764. } else {
  765. if ($nPage == 1) {
  766. $PageList .= "<li class='page-item'><a class='page-link' href='view.php?aid=$aid'>上一页</a></li>";
  767. if ($cfg_rewrite == 'Y') {
  768. $PageList = preg_replace("#.php\?aid=(\d+)#i", '-\\1-1.html', $PageList);
  769. }
  770. } else {
  771. $PageList .= "<li class='page-item'><a class='page-link' href='view.php?aid=$aid&pageno=$nPage'>上一页</a></li>";
  772. if ($cfg_rewrite == 'Y') {
  773. $PageList = str_replace(".php?aid=", "-", $PageList);
  774. $PageList = preg_replace("#&pageno=(\d+)#i", '-\\1.html', $PageList);
  775. }
  776. }
  777. }
  778. for ($i = 1; $i <= $totalPage; $i++) {
  779. if ($i == 1) {
  780. if ($nowPage != 1) {
  781. $PageList .= "<li class='page-item'><a class='page-link' href='view.php?aid=$aid'>1</a></li>";
  782. if ($cfg_rewrite == 'Y') {
  783. $PageList = preg_replace("#.php\?aid=(\d+)#i", '-\\1-1.html', $PageList);
  784. }
  785. } else {
  786. $PageList .= "<li class=\"page-item active\"><a class='page-link'>1</a></li>";
  787. }
  788. } else {
  789. $n = $i;
  790. if ($nowPage != $i) {
  791. $PageList .= "<li class='page-item'><a class='page-link' href='view.php?aid=$aid&pageno=$i'>" . $n . "</a></li>";
  792. if ($cfg_rewrite == 'Y') {
  793. $PageList = str_replace(".php?aid=", "-", $PageList);
  794. $PageList = preg_replace("#&pageno=(\d+)#i", '-\\1.html', $PageList);
  795. }
  796. } else {
  797. $PageList .= "<li class=\"page-item active\"><span class='page-link'>{$n}</span></li>";
  798. }
  799. }
  800. }
  801. if ($lPage <= $totalPage) {
  802. $PageList .= "<li class='page-item'><a class='page-link' href='view.php?aid=$aid&pageno=$lPage'>下一页</a></li>";
  803. if ($cfg_rewrite == 'Y') {
  804. $PageList = str_replace(".php?aid=", "-", $PageList);
  805. $PageList = preg_replace("#&pageno=(\d+)#i", '-\\1.html', $PageList);
  806. }
  807. } else {
  808. $PageList .= "<li class='page-item'><span class='page-link'>下一页</span></li>";
  809. }
  810. return $PageList;
  811. }
  812. /**
  813. * 获得静态页面分页列表
  814. *
  815. * @access public
  816. * @param int $totalPage 总页数
  817. * @param int $nowPage 当前页数
  818. * @param int $aid 文档id
  819. * @return string
  820. */
  821. function GetPagebreak($totalPage, $nowPage, $aid)
  822. {
  823. if ($totalPage == 1) {
  824. return "";
  825. }
  826. $PageList = "<li class='page-item d-none d-sm-block disabled'><span class=\"page-link\">共" . $totalPage . "页: </span></li>";
  827. $nPage = $nowPage - 1;
  828. $lPage = $nowPage + 1;
  829. if ($nowPage == 1) {
  830. $PageList .= "<li class='page-item d-none d-sm-block disabled'><a class='page-link' href='#'>上一页</a></li>";
  831. } else {
  832. if ($nPage == 1) {
  833. $PageList .= "<li class='page-item'><a class='page-link' href='" . $this->NameFirst . "." . $this->ShortName . "'>上一页</a></li>";
  834. } else {
  835. $PageList .= "<li class='page-item'><a class='page-link' href='" . $this->NameFirst . "_" . $nPage . "." . $this->ShortName . "'>上一页</a></li>";
  836. }
  837. }
  838. for ($i = 1; $i <= $totalPage; $i++) {
  839. if ($i == 1) {
  840. if ($nowPage != 1) {
  841. $PageList .= "<li class='page-item'><a class='page-link' href='" . $this->NameFirst . "." . $this->ShortName . "'>1</a></li>";
  842. } else {
  843. $PageList .= "<li class=\"page-item active\"><span class='page-link'>1</span></li>";
  844. }
  845. } else {
  846. $n = $i;
  847. if ($nowPage != $i) {
  848. $PageList .= "<li class='page-item'><a class='page-link' href='" . $this->NameFirst . "_" . $i . "." . $this->ShortName . "'>" . $n . "</a></li>";
  849. } else {
  850. $PageList .= "<li class=\"page-item active\"><span class='page-link'>{$n}</span></li>";
  851. }
  852. }
  853. }
  854. if ($lPage <= $totalPage) {
  855. $PageList .= "<li class='page-item'><a class='page-link' href='" . $this->NameFirst . "_" . $lPage . "." . $this->ShortName . "'>下一页</a></li>";
  856. } else {
  857. $PageList .= "<li class='page-item'><span class='page-link'>下一页</span></li>";
  858. }
  859. return $PageList;
  860. }
  861. /**
  862. * 获得动态页面小标题
  863. *
  864. * @access public
  865. * @param string $styleName 类型名称
  866. * @param string $pageNo 页码数
  867. * @return string
  868. */
  869. function GetPageTitlesDM($styleName, $pageNo)
  870. {
  871. if ($this->TotalPage == 1) {
  872. return "";
  873. }
  874. if (count($this->SplitTitles) == 0) {
  875. return "";
  876. }
  877. $i = 1;
  878. $aid = $this->ArcID;
  879. if ($styleName == 'link') {
  880. $revalue = "";
  881. foreach ($this->SplitTitles as $k => $v) {
  882. if ($i == 1) {
  883. $revalue .= "<a href='view.php?aid=$aid&pageno=$i'>$v</a> \r\n";
  884. } else {
  885. if ($pageNo == $i) {
  886. $revalue .= " $v \r\n";
  887. } else {
  888. $revalue .= "<a href='view.php?aid=$aid&pageno=$i'>$v</a> \r\n";
  889. }
  890. }
  891. $i++;
  892. }
  893. } else {
  894. $revalue = "<select id='dedepagetitles' onchange='location.href=this.options[this.selectedIndex].value;'>\r\n";
  895. foreach ($this->SplitTitles as $k => $v) {
  896. if ($i == 1) {
  897. $revalue .= "<option value='" . $this->Fields['phpurl'] . "/view.php?aid=$aid&pageno=$i'>{$i}、{$v}</option>\r\n";
  898. } else {
  899. if ($pageNo == $i) {
  900. $revalue .= "<option value='" . $this->Fields['phpurl'] . "/view.php?aid=$aid&pageno=$i' selected>{$i}、{$v}</option>\r\n";
  901. } else {
  902. $revalue .= "<option value='" . $this->Fields['phpurl'] . "/view.php?aid=$aid&pageno=$i'>{$i}、{$v}</option>\r\n";
  903. }
  904. }
  905. $i++;
  906. }
  907. $revalue .= "</select>\r\n";
  908. }
  909. return $revalue;
  910. }
  911. /**
  912. * 获得静态页面小标题
  913. *
  914. * @access public
  915. * @param string $styleName 类型名称
  916. * @param string $pageNo 页码数
  917. * @return string
  918. */
  919. function GetPageTitlesST($styleName, $pageNo)
  920. {
  921. if ($this->TotalPage == 1) {
  922. return "";
  923. }
  924. if (count($this->SplitTitles) == 0) {
  925. return "";
  926. }
  927. $i = 1;
  928. if ($styleName == 'link') {
  929. $revalue = "";
  930. foreach ($this->SplitTitles as $k => $v) {
  931. if ($i == 1) {
  932. $revalue .= "<a href='" . $this->NameFirst . "." . $this->ShortName . "'>$v</a> \r\n";
  933. } else {
  934. if ($pageNo == $i) {
  935. $revalue .= " $v \r\n";
  936. } else {
  937. $revalue .= "<a href='" . $this->NameFirst . "_" . $i . "." . $this->ShortName . "'>$v</a> \r\n";
  938. }
  939. }
  940. $i++;
  941. }
  942. } else {
  943. $revalue = "<select id='dedepagetitles' onchange='location.href=this.options[this.selectedIndex].value;'>\r\n";
  944. foreach ($this->SplitTitles as $k => $v) {
  945. if ($i == 1) {
  946. $revalue .= "<option value='" . $this->NameFirst . "." . $this->ShortName . "'>{$i}、{$v}</option>\r\n";
  947. } else {
  948. if ($pageNo == $i) {
  949. $revalue .= "<option value='" . $this->NameFirst . "_" . $i . "." . $this->ShortName . "' selected>{$i}、{$v}</option>\r\n";
  950. } else {
  951. $revalue .= "<option value='" . $this->NameFirst . "_" . $i . "." . $this->ShortName . "'>{$i}、{$v}</option>\r\n";
  952. }
  953. }
  954. $i++;
  955. }
  956. $revalue .= "</select>\r\n";
  957. }
  958. return $revalue;
  959. }
  960. /**
  961. * 高亮问题修正, 排除alt title <a></a>直接的字符替换
  962. *
  963. * @param string $kw
  964. * @param string $body
  965. * @return string
  966. */
  967. function ReplaceKeyword($kw, &$body)
  968. {
  969. global $cfg_cmspath;
  970. $maxkey = 5;
  971. $kws = explode(",", trim($kw)); //以分好为间隔符
  972. $i = 0;
  973. $karr = $kaarr = $GLOBALS['replaced'] = array();
  974. //暂时屏蔽超链接
  975. $body = preg_replace("#(<a(.*))(>)(.*)(<)(\/a>)#isU", '\\1-]-\\4-[-\\6', $body);
  976. /*
  977. foreach($kws as $k)
  978. {
  979. $k = trim($k);
  980. if($k!="")
  981. {
  982. if($i > $maxkey)
  983. {
  984. break;
  985. }
  986. $myrow = $this->dsql->GetOne("SELECT * FROM #@__keywords WHERE keyword='$k' AND rpurl<>'' ");
  987. if(is_array($myrow))
  988. {
  989. $karr[] = $k;
  990. $GLOBALS['replaced'][$k] = 0;
  991. $kaarr[] = "<a href='{$myrow['rpurl']}'><u>$k</u></a>";
  992. }
  993. $i++;
  994. }
  995. }
  996. */
  997. $query = "SELECT * FROM #@__keywords WHERE rpurl<>'' ORDER BY rank DESC";
  998. $this->dsql->SetQuery($query);
  999. $this->dsql->Execute();
  1000. while ($row = $this->dsql->GetArray()) {
  1001. $key = trim($row['keyword']);
  1002. $key_url = trim($row['rpurl']);
  1003. $karr[] = $key;
  1004. $kaarr[] = "<a href='$key_url' target='_blank'><u>$key</u></a>";
  1005. }
  1006. $GLOBALS['_dd_karr'] = $karr;
  1007. $GLOBALS['_dd_kaarr'] = $kaarr;
  1008. // 这里可能会有错误
  1009. if (version_compare(PHP_VERSION, '8.0.0', '>=')) {
  1010. $body = @preg_replace_callback("#(^|>)([^<]+)(?=<|$)#sU", "_highlight8", $body);
  1011. } else if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
  1012. $body = @preg_replace_callback("#(^|>)([^<]+)(?=<|$)#sU", "_highlight('\\2', \$karr, \$kaarr, '\\1')", $body);
  1013. } else {
  1014. $body = @preg_replace("#(^|>)([^<]+)(?=<|$)#sUe", "_highlight('\\2', \$karr, \$kaarr, '\\1')", $body);
  1015. }
  1016. //恢复超链接
  1017. $body = preg_replace("#(<a(.*))-\]-(.*)-\[-(\/a>)#isU", '\\1>\\3<\\4', $body);
  1018. return $body;
  1019. }
  1020. } //End Archives
  1021. function _highlight8($matches){
  1022. return _highlight($matches[2], $GLOBALS['_dd_karr'], $GLOBALS['_dd_kaarr'], $matches[1]);
  1023. }
  1024. //高亮专用, 替换多次是可能不能达到最多次
  1025. function _highlight($string, $words, $result, $pre)
  1026. {
  1027. global $cfg_replace_num;
  1028. if (version_compare(PHP_VERSION, '5.5.0', '>=') && version_compare(PHP_VERSION, '8.0.0', '<')) {
  1029. $string = $string[0];
  1030. $pre = $pre[0];
  1031. }
  1032. $string = str_replace('\"', '"', $string);
  1033. if ($cfg_replace_num > 0) {
  1034. foreach ($words as $key => $word) {
  1035. if ($GLOBALS['replaced'][$word] == 1) {
  1036. continue;
  1037. }
  1038. $string = preg_replace("#" . preg_quote($word) . "#", $result[$key], $string, $cfg_replace_num);
  1039. if (strpos($string, $word) !== FALSE) {
  1040. $GLOBALS['replaced'][$word] = 1;
  1041. }
  1042. }
  1043. } else {
  1044. $string = str_replace($words, $result, $string);
  1045. }
  1046. return $pre . $string;
  1047. }