TemplateRender.php 33 KB

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