TemplateRender.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. <?php
  2. namespace App\Http\Api;
  3. use Illuminate\Support\Facades\Cache;
  4. use Illuminate\Support\Facades\Log;
  5. use Illuminate\Support\Str;
  6. use Illuminate\Support\Facades\Http;
  7. use App\Models\DhammaTerm;
  8. use App\Models\PaliText;
  9. use App\Models\Channel;
  10. use App\Models\PageNumber;
  11. use App\Http\Controllers\CorpusController;
  12. use App\Tools\RedisClusters;
  13. use App\Http\Api\ChannelApi;
  14. use App\Http\Api\MdRender;
  15. use App\Http\Api\PaliTextApi;
  16. class TemplateRender{
  17. protected $param = [];
  18. protected $mode = "read";
  19. protected $channel_id = [];
  20. protected $debug = [];
  21. protected $format = 'react';
  22. protected $studioId = null;
  23. /**
  24. * Create a new command instance.
  25. * string $mode 'read' | 'edit'
  26. * string $format 'react' | 'text' | 'tex' | 'unity'
  27. * @return void
  28. */
  29. public function __construct($param, $channelInfo, $mode,$format='react',$studioId,$debug=[])
  30. {
  31. $this->param = $param;
  32. foreach ($channelInfo as $value) {
  33. $this->channel_id[] = $value->uid;
  34. }
  35. $this->channelInfo = $channelInfo;
  36. $this->mode = $mode;
  37. $this->format = $format;
  38. $this->studioId = $studioId;
  39. $this->debug = $debug;
  40. }
  41. private function info($message,$debug){
  42. if(in_array($debug,$this->debug)){
  43. Log::info($message);
  44. }
  45. }
  46. private function error($message,$debug){
  47. if(in_array($debug,$this->debug)){
  48. Log::error($message);
  49. }
  50. }
  51. public function render($tpl_name){
  52. switch ($tpl_name) {
  53. case 'term':
  54. # 术语
  55. $result = $this->render_term();
  56. break;
  57. case 'note':
  58. $result = $this->render_note();
  59. break;
  60. case 'sent':
  61. $result = $this->render_sent();
  62. break;
  63. case 'quote':
  64. $result = $this->render_quote();
  65. break;
  66. case 'ql':
  67. $result = $this->render_quote_link();
  68. break;
  69. case 'exercise':
  70. $result = $this->render_exercise();
  71. break;
  72. case 'article':
  73. $result = $this->render_article();
  74. break;
  75. case 'nissaya':
  76. $result = $this->render_nissaya();
  77. break;
  78. case 'mermaid':
  79. $result = $this->render_mermaid();
  80. break;
  81. default:
  82. # code...
  83. $result = [
  84. 'props'=>base64_encode(\json_encode([])),
  85. 'html'=>'',
  86. 'tag'=>'span',
  87. 'tpl'=>'unknown',
  88. ];
  89. break;
  90. }
  91. return $result;
  92. }
  93. public function getTermProps($word,$tag){
  94. if(count($this->channel_id)>0){
  95. $channelId = $this->channel_id[0];
  96. }else{
  97. $channelId = null;
  98. }
  99. if(count($this->channelInfo)===0){
  100. Log::error('channel is null');
  101. $output = [
  102. "word" => $word,
  103. 'innerHtml' => '',
  104. ];
  105. return $output;
  106. }
  107. $channelInfo = $this->channelInfo[0];
  108. if(Str::isUuid($channelId)){
  109. $lang = Channel::where('uid',$channelId)->value('lang');
  110. if(!empty($lang)){
  111. $langFamily = explode('-',$lang)[0];
  112. }else{
  113. $langFamily = 'zh';
  114. }
  115. $this->info("term:{$word} 先查属于这个channel 的",'term');
  116. $this->info('channel id'.$channelId,'term');
  117. $table = DhammaTerm::where("word",$word)
  118. ->where('channal',$channelId);
  119. if(!empty($tag)){
  120. $table = $table->where('tag',$tag);
  121. }
  122. $tplParam = $table->orderBy('updated_at','desc')
  123. ->first();
  124. $studioId = $channelInfo->owner_uid;
  125. }else{
  126. $tplParam = false;
  127. $lang = '';
  128. $langFamily = '';
  129. $studioId = $this->studioId;
  130. }
  131. if(!$tplParam){
  132. if(Str::isUuid($studioId)){
  133. /**
  134. * 没有,再查这个studio的
  135. * 按照语言过滤
  136. * 完全匹配的优先
  137. * 语族匹配也行
  138. */
  139. $this->info("没有-再查这个studio的",'term');
  140. $table = DhammaTerm::where("word",$word);
  141. if(!empty($tag)){
  142. $table = $table->where('tag',$tag);
  143. }
  144. $termsInStudio = $table->where('owner',$channelInfo->owner_uid)
  145. ->orderBy('updated_at','desc')
  146. ->get();
  147. if(count($termsInStudio)>0){
  148. $list = array();
  149. foreach ($termsInStudio as $key=>$term) {
  150. if(empty($term->channal)){
  151. if($term->language===$lang){
  152. $list[$term->guid]=2;
  153. }else if(strpos($term->language,$langFamily) !== false){
  154. $list[$term->guid]=1;
  155. }
  156. }
  157. }
  158. if(count($list)>0){
  159. arsort($list);
  160. foreach ($list as $key => $one) {
  161. foreach ($termsInStudio as $term) {
  162. if($term->guid===$key){
  163. $tplParam = $term;
  164. break;
  165. }
  166. }
  167. break;
  168. }
  169. }
  170. }
  171. }
  172. }
  173. if(!$tplParam){
  174. $this->info("没有,再查社区",'term');
  175. $community_channel = ChannelApi::getSysChannel("_community_term_zh-hans_");
  176. $table = DhammaTerm::where("word",$word);
  177. if(!empty($tag)){
  178. $table = $table->where('tag',$tag);
  179. }
  180. $tplParam = $table->where('channal',$community_channel)
  181. ->first();
  182. if($tplParam){
  183. $isCommunity = true;
  184. }else{
  185. $this->info("查社区没有",'term');
  186. }
  187. }
  188. $output = [
  189. "word" => $word,
  190. "parentChannelId" => $channelId,
  191. "parentStudioId" => $channelInfo->owner_uid,
  192. ];
  193. $innerString = $output["word"];
  194. if($tplParam){
  195. $output["id"] = $tplParam->guid;
  196. $output["meaning"] = $tplParam->meaning;
  197. $output["channel"] = $tplParam->channal;
  198. if(isset($isCommunity)){
  199. $output["isCommunity"] = true;
  200. }
  201. $innerString = "{$output["meaning"]}({$output["word"]})";
  202. if(!empty($tplParam->other_meaning)){
  203. $output["meaning2"] = $tplParam->other_meaning;
  204. }
  205. }
  206. $output['innerHtml'] = $innerString;
  207. return $output;
  208. }
  209. private function render_term(){
  210. $word = $this->get_param($this->param,"word",1);
  211. $props = $this->getTermProps($word,'');
  212. //$key = "/term/{$channelId}/{$word}";
  213. $output = $props['word'];
  214. switch ($this->format) {
  215. case 'react':
  216. $output=[
  217. 'props'=>base64_encode(\json_encode($props)),
  218. 'html'=>$props['innerHtml'],
  219. 'tag'=>'span',
  220. 'tpl'=>'term',
  221. ];
  222. break;
  223. case 'unity':
  224. $output=[
  225. 'props'=>base64_encode(\json_encode($props)),
  226. 'tpl'=>'term',
  227. ];
  228. break;
  229. case 'html':
  230. if(isset($props["meaning"])){
  231. $key = 'term-'.$props["word"];
  232. $termHead = "<a href='#'>".$props['meaning']."</a>";
  233. if(isset($GLOBALS[$key])){
  234. $output = $termHead;
  235. }else{
  236. $GLOBALS[$key] = 1;
  237. $output = $termHead.'(<em>'.$props["word"].'</em>)';
  238. }
  239. }else{
  240. $output = $props["word"];
  241. }
  242. break;
  243. case 'text':
  244. if(isset($props["meaning"])){
  245. $key = 'term-'.$props["word"];
  246. if(isset($GLOBALS[$key])){
  247. $output = $props["meaning"];
  248. }else{
  249. $GLOBALS[$key] = 1;
  250. $output = $props["meaning"].'('.$props["word"].')';
  251. }
  252. }else{
  253. $output = $props["word"];
  254. }
  255. break;
  256. case 'tex':
  257. if(isset($props["meaning"])){
  258. $key = 'term-'.$props["word"];
  259. if(isset($GLOBALS[$key])){
  260. $output = $props["meaning"];
  261. }else{
  262. $GLOBALS[$key] = 1;
  263. $output = $props["meaning"].'('.$props["word"].')';
  264. }
  265. }else{
  266. $output = $props["word"];
  267. }
  268. break;
  269. case 'simple':
  270. if(isset($props["meaning"])){
  271. $output = $props["meaning"];
  272. }else{
  273. $output = $props["word"];
  274. }
  275. break;
  276. default:
  277. if(isset($props["meaning"])){
  278. $output = $props["meaning"];
  279. }else{
  280. $output = $props["word"];
  281. }
  282. break;
  283. }
  284. return $output;
  285. }
  286. private function render_note(){
  287. $note = $this->get_param($this->param,"text",1);
  288. $trigger = $this->get_param($this->param,"trigger",2);
  289. $props = ["note" => $note ];
  290. $innerString = "";
  291. if(!empty($trigger)){
  292. $props["trigger"] = $trigger;
  293. $innerString = $props["trigger"];
  294. }
  295. if($this->format==='unity'){
  296. $props["note"] = MdRender::render($props["note"],
  297. $this->channel_id,
  298. null,
  299. 'read',
  300. 'translation',
  301. 'markdown',
  302. 'unity'
  303. );
  304. }
  305. $output = $note;
  306. switch ($this->format) {
  307. case 'react':
  308. $output=[
  309. 'props'=>base64_encode(\json_encode($props)),
  310. 'html'=>$innerString,
  311. 'tag'=>'span',
  312. 'tpl'=>'note',
  313. ];
  314. break;
  315. case 'unity':
  316. $output=[
  317. 'props'=>base64_encode(\json_encode($props)),
  318. 'tpl'=>'note',
  319. ];
  320. break;
  321. case 'html':
  322. if(isset($GLOBALS['note_sn'])){
  323. $GLOBALS['note_sn']++;
  324. }else{
  325. $GLOBALS['note_sn'] = 1;
  326. $GLOBALS['note'] = array();
  327. }
  328. $GLOBALS['note'][] = [
  329. 'sn' => 1,
  330. 'trigger' => $trigger,
  331. 'content' => MdRender::render($props["note"],
  332. $this->channel_id,
  333. null,
  334. 'read',
  335. 'translation',
  336. 'markdown',
  337. 'html'
  338. ),
  339. ];
  340. $link="<a href='#footnote-".$GLOBALS['note_sn']."' name='note-".$GLOBALS['note_sn']."'>";
  341. if(empty($trigger)){
  342. $output = $link. "<sup>[" . $GLOBALS['note_sn'] . "]</sup></a>";
  343. }else{
  344. $output = $link . $trigger . "</a>";
  345. }
  346. break;
  347. case 'text':
  348. $output = $trigger;
  349. break;
  350. case 'tex':
  351. $output = $trigger;
  352. break;
  353. case 'simple':
  354. $output = '';
  355. break;
  356. default:
  357. $output = '';
  358. break;
  359. }
  360. return $output;
  361. }
  362. private function render_nissaya(){
  363. $pali = $this->get_param($this->param,"pali",1);
  364. $meaning = $this->get_param($this->param,"meaning",2);
  365. $innerString = "";
  366. $props = [
  367. "pali" => $pali,
  368. "meaning" => $meaning,
  369. ];
  370. switch ($this->format) {
  371. case 'react':
  372. $output = [
  373. 'props'=>base64_encode(\json_encode($props)),
  374. 'html'=>$innerString,
  375. 'tag'=>'span',
  376. 'tpl'=>'nissaya',
  377. ];
  378. break;
  379. case 'unity':
  380. $output = [
  381. 'props'=>base64_encode(\json_encode($props)),
  382. 'tpl'=>'nissaya',
  383. ];
  384. break;
  385. case 'text':
  386. $output = $pali.'၊'.$meaning;
  387. break;
  388. case 'tex':
  389. $output = $pali.'၊'.$meaning;
  390. break;
  391. case 'simple':
  392. $output = $pali.'၊'.$meaning;
  393. break;
  394. default:
  395. $output = $pali.'၊'.$meaning;
  396. break;
  397. }
  398. return $output;
  399. }
  400. private function render_exercise(){
  401. $id = $this->get_param($this->param,"id",1);
  402. $title = $this->get_param($this->param,"title",1);
  403. $props = [
  404. "id" => $id,
  405. "title" => $title,
  406. "channel" => $this->channel_id[0],
  407. ];
  408. switch ($this->format) {
  409. case 'react':
  410. $output = [
  411. 'props'=>base64_encode(\json_encode($props)),
  412. 'html'=>"",
  413. 'tag'=>'span',
  414. 'tpl'=>'exercise',
  415. ];
  416. break;
  417. case 'unity':
  418. $output = [
  419. 'props'=>base64_encode(\json_encode($props)),
  420. 'tpl'=>'exercise',
  421. ];
  422. break;
  423. case 'text':
  424. $output = $title;
  425. break;
  426. case 'tex':
  427. $output = $title;
  428. break;
  429. case 'simple':
  430. $output = $title;
  431. break;
  432. default:
  433. $output = '';
  434. break;
  435. }
  436. return $output;
  437. }
  438. private function render_article(){
  439. $type = $this->get_param($this->param,"type",1);
  440. $id = $this->get_param($this->param,"id",2);
  441. $title = $this->get_param($this->param,"title",3);
  442. $channel = $this->get_param($this->param,"channel",4,$this->channel_id[0]);
  443. $style = $this->get_param($this->param,"style",5);
  444. $book = $this->get_param($this->param,"book",6);
  445. $paragraphs = $this->get_param($this->param,"paragraphs",7);
  446. $props = [
  447. "type" => $type,
  448. "id" => $id,
  449. "channel" => $channel,
  450. 'style' => $style,
  451. ];
  452. if(!empty($title)){
  453. $props['title'] = $title;
  454. }
  455. if(!empty($book)){
  456. $props['book'] = $book;
  457. }
  458. if(!empty($paragraphs)){
  459. $props['paragraphs'] = $paragraphs;
  460. }
  461. switch ($this->format) {
  462. case 'react':
  463. $output = [
  464. 'props'=>base64_encode(\json_encode($props)),
  465. 'html'=>"",
  466. 'text'=>$title,
  467. 'tag'=>'span',
  468. 'tpl'=>'article',
  469. ];
  470. break;
  471. case 'unity':
  472. $output = [
  473. 'props'=>base64_encode(\json_encode($props)),
  474. 'tpl'=>'article',
  475. ];
  476. break;
  477. case 'text':
  478. $output = $title;
  479. break;
  480. case 'tex':
  481. $output = $title;
  482. break;
  483. case 'simple':
  484. $output = $title;
  485. break;
  486. default:
  487. $output = '';
  488. break;
  489. }
  490. return $output;
  491. }
  492. private function render_quote(){
  493. $paraId = $this->get_param($this->param,"para",1);
  494. $channelId = $this->channel_id[0];
  495. $props = RedisClusters::remember("/quote/{$channelId}/{$paraId}",
  496. config('mint.cache.expire'),
  497. function() use($paraId,$channelId){
  498. $para = \explode('-',$paraId);
  499. $output = [
  500. "paraId" => $paraId,
  501. "channel" => $channelId,
  502. "innerString" => $paraId,
  503. ];
  504. if(count($para)<2){
  505. return $output;
  506. }
  507. $PaliText = PaliText::where("book",$para[0])
  508. ->where("paragraph",$para[1])
  509. ->select(['toc','path'])
  510. ->first();
  511. if($PaliText){
  512. $output["pali"] = $PaliText->toc;
  513. $output["paliPath"] = \json_decode($PaliText->path);
  514. $output["innerString"]= $PaliText->toc;
  515. }
  516. return $output;
  517. });
  518. switch ($this->format) {
  519. case 'react':
  520. $output = [
  521. 'props'=>base64_encode(\json_encode($props)),
  522. 'html'=>$props["innerString"],
  523. 'tag'=>'span',
  524. 'tpl'=>'quote',
  525. ];
  526. break;
  527. case 'unity':
  528. $output = [
  529. 'props'=>base64_encode(\json_encode($props)),
  530. 'tpl'=>'quote',
  531. ];
  532. break;
  533. case 'text':
  534. $output = $props["innerString"];
  535. break;
  536. case 'tex':
  537. $output = $props["innerString"];
  538. break;
  539. case 'simple':
  540. $output = $props["innerString"];
  541. break;
  542. default:
  543. $output = $props["innerString"];
  544. break;
  545. }
  546. return $output;
  547. }
  548. private function render_quote_link(){
  549. $type = $this->get_param($this->param,"type",1);
  550. $title = $this->get_param($this->param,"title",6,'');
  551. $bookName = $this->get_param($this->param,"bookname",2,'');
  552. $volume = $this->get_param($this->param,"volume",3);
  553. $page = $this->get_param($this->param,"page",4,'');
  554. $style = $this->get_param($this->param,"style",5,'modal');
  555. $book = $this->get_param($this->param,"book",7,false);
  556. $para = $this->get_param($this->param,"para",8,false);
  557. $props = [
  558. 'type' => $type,
  559. 'style' => $style,
  560. 'found' => true,
  561. ];
  562. if(!empty($bookName) && $volume !== '' && !empty($page)){
  563. $props['bookName'] = $bookName;
  564. $props['volume'] = (int)$volume;
  565. $props['page'] = $page;
  566. $props['found'] = true;
  567. }else if($book && $para){
  568. /**
  569. * 没有指定书名,根据book para 查询
  570. */
  571. if($type==='c'){
  572. //按照章节名称显示
  573. $path = PaliTextApi::getChapterPath($book,$para);
  574. if($path){
  575. $path = json_decode($path,true);
  576. }
  577. if($path && is_array($path) && count($path)>2){
  578. $props['bookName'] = strtolower($path[0]['title']) ;
  579. $props['chapter'] = strtolower(end($path)['title']);
  580. $props['found'] = true;
  581. }else{
  582. $props['found'] = false;
  583. }
  584. }else{
  585. $pageInfo = $this->pageInfoByPara($type,$book,$para);
  586. if($pageInfo['found']){
  587. $props['bookName'] = $pageInfo['bookName'];
  588. $props['volume'] = $pageInfo['volume'];
  589. $props['page'] = $pageInfo['page'];
  590. $props['found'] = true;
  591. }else{
  592. $props['found'] = false;
  593. }
  594. }
  595. }else if($title){
  596. //没有书号用title查询
  597. $tmpTitle = explode('။',$title);
  598. if(count($tmpTitle)>1){
  599. $tmpBookTitle = $tmpTitle[0];
  600. $tmpBookPage = $tmpTitle[1];
  601. $tmpBookPage = (int)str_replace(
  602. ['၁','၂','၃','၄','၅','၆','၇','၈','၉','၀'],
  603. ['1','2','3','4','5','6','7','8','9','0'],
  604. $tmpBookPage);
  605. $found_key = array_search($tmpBookTitle, array_column(BookTitle::my(), 'title2'));
  606. if($found_key !== false){
  607. $props['bookName'] = BookTitle::my()[$found_key]['bookname'];
  608. $props['volume'] = BookTitle::my()[$found_key]['volume'];
  609. $props['page'] = $tmpBookPage;
  610. if(!empty($props['bookName'])){
  611. $found_title = array_search($props['bookName'], array_column(BookTitle::my(), 'bookname'));
  612. if($found_title === false){
  613. $props['found'] = false;
  614. }
  615. }
  616. }else{
  617. //没找到,返回术语和页码
  618. $props['found'] = false;
  619. $props['bookName'] = $tmpBookTitle;
  620. $props['page'] = $tmpBookPage;
  621. $props['volume'] = 0;
  622. }
  623. }
  624. }else{
  625. $props['found'] = false;
  626. }
  627. if($book && $para){
  628. $props['book'] = $book;
  629. $props['para'] = $para;
  630. }
  631. if($title){
  632. $props['title'] = $title;
  633. }
  634. $text = '';
  635. if(isset($props['bookName'])){
  636. $term = $this->getTermProps($props['bookName'],':quote:');
  637. $props['term'] = $term;
  638. if(isset($term['id'])){
  639. $props['bookNameLocal'] = $term['meaning'];
  640. $text .= $term['meaning'];
  641. }else{
  642. $text .= $bookName;
  643. }
  644. }
  645. if(isset($props['volume']) && isset($props['page'])){
  646. $text .= " {$volume}.{$page}";
  647. }
  648. switch ($this->format) {
  649. case 'react':
  650. $output = [
  651. 'props'=>base64_encode(\json_encode($props)),
  652. 'html'=>'',
  653. 'tag'=>'span',
  654. 'tpl'=>'quote-link',
  655. ];
  656. break;
  657. case 'unity':
  658. $output = [
  659. 'props'=>base64_encode(\json_encode($props)),
  660. 'tpl'=>'quote-link',
  661. ];
  662. break;
  663. default:
  664. $output = $text;
  665. break;
  666. }
  667. return $output;
  668. }
  669. private function pageInfoByPara($type,$book,$para){
  670. $output = array();
  671. $pageInfo = PageNumber::where('type',strtoupper($type))
  672. ->where('book',$book)
  673. ->where('paragraph','<=',$para)
  674. ->orderBy('paragraph','desc')
  675. ->first();
  676. if($pageInfo){
  677. foreach (BookTitle::get() as $value) {
  678. if($value['id']===$pageInfo->pcd_book_id){
  679. switch (strtoupper($type)) {
  680. case 'M':
  681. $key = 'm_title';
  682. break;
  683. case 'P':
  684. $key = 'p_title';
  685. break;
  686. case 'V':
  687. $key = 'v_title';
  688. break;
  689. default:
  690. $key = 'term';
  691. break;
  692. }
  693. $output['bookName'] = $value[$key];
  694. break;
  695. }
  696. }
  697. $output['volume'] = $pageInfo->volume;
  698. $output['page'] = $pageInfo->page;
  699. $output['found'] = true;
  700. }else{
  701. $output['found'] = false;
  702. }
  703. return $output;
  704. }
  705. private function render_sent(){
  706. $sid = $this->get_param($this->param,"sid",1);
  707. $channel = $this->get_param($this->param,"channel",2);
  708. if(!empty($channel)){
  709. $channels = explode(',',$channel);
  710. }else{
  711. $channels = $this->channel_id;
  712. }
  713. $sentInfo = explode('@',trim($sid));
  714. $sentId = $sentInfo[0];
  715. if(isset($sentInfo[1])){
  716. $channels = [$sentInfo[1]];
  717. }
  718. $Sent = new CorpusController();
  719. $props = $Sent->getSentTpl($sentId,$channels,
  720. $this->mode,true,
  721. $this->format);
  722. if($props === false){
  723. $props['error']="句子模版渲染错误。句子参数个数不符。应该是四个。";
  724. }
  725. if($this->mode==='read'){
  726. $tpl = "sentread";
  727. }else{
  728. $tpl = "sentedit";
  729. }
  730. switch ($this->format) {
  731. case 'react':
  732. $output = [
  733. 'props'=>base64_encode(\json_encode($props)),
  734. 'html'=>"",
  735. 'tag'=>'span',
  736. 'tpl'=>$tpl,
  737. ];
  738. break;
  739. case 'unity':
  740. $output = [
  741. 'props'=>base64_encode(\json_encode($props)),
  742. 'tpl'=>$tpl,
  743. ];
  744. break;
  745. case 'text':
  746. $output = '';
  747. if(isset($props['translation']) && is_array($props['translation'])){
  748. foreach ($props['translation'] as $key => $value) {
  749. $output .= $value['html'];
  750. }
  751. }
  752. break;
  753. case 'html':
  754. $output = '';
  755. if(isset($props['translation']) && is_array($props['translation'])){
  756. foreach ($props['translation'] as $key => $value) {
  757. $output .= '<span class="sentence">'.$value['html'].'</span>';
  758. }
  759. }
  760. break;
  761. case 'tex':
  762. $output = '';
  763. if(isset($props['translation']) && is_array($props['translation'])){
  764. foreach ($props['translation'] as $key => $value) {
  765. $output .= $value['html'];
  766. }
  767. }
  768. break;
  769. case 'simple':
  770. $output = '';
  771. if(isset($props['translation']) &&
  772. is_array($props['translation']) &&
  773. count($props['translation']) > 0
  774. ){
  775. $sentences = $props['translation'];
  776. foreach ($sentences as $key => $value) {
  777. $output .= $value['html'];
  778. }
  779. }
  780. if(empty($output)){
  781. if(isset($props['origin']) &&
  782. is_array($props['origin']) &&
  783. count($props['origin']) > 0
  784. ){
  785. $sentences = $props['origin'];
  786. foreach ($sentences as $key => $value) {
  787. $output .= $value['html'];
  788. }
  789. }
  790. }
  791. break;
  792. default:
  793. $output = '';
  794. break;
  795. }
  796. return $output;
  797. }
  798. private function render_mermaid(){
  799. $text = json_decode(base64_decode($this->get_param($this->param,"text",1)));
  800. $props = ["text" => implode("\n",$text)];
  801. switch ($this->format) {
  802. case 'react':
  803. $output = [
  804. 'props'=>base64_encode(\json_encode($props)),
  805. 'html'=>"mermaid",
  806. 'tag'=>'div',
  807. 'tpl'=>'mermaid',
  808. ];
  809. break;
  810. case 'unity':
  811. $output = [
  812. 'props'=>base64_encode(\json_encode($props)),
  813. 'tpl'=>'mermaid',
  814. ];
  815. break;
  816. case 'text':
  817. $output = 'mermaid';
  818. break;
  819. case 'tex':
  820. $output = 'mermaid';
  821. break;
  822. case 'simple':
  823. $output = 'mermaid';
  824. break;
  825. default:
  826. $output = 'mermaid';
  827. break;
  828. }
  829. return $output;
  830. }
  831. private function get_param(array $param,string $name,int $id,string $default=''){
  832. if(isset($param[$name])){
  833. return trim($param[$name]);
  834. }else if(isset($param["{$id}"])){
  835. return trim($param["{$id}"]);
  836. }else{
  837. return $default;
  838. }
  839. }
  840. }