<?php
 namespace TCMS;
 class TCmsViewEngine {
 public function convertTCmsToPhpView($viewFile, $lastModifierTime, $tempPath, $tempFileName, $isLayoutPage, $mName, $isSaveSView) {
 $content = $this->convertToViewTemplate($viewFile, $isLayoutPage);
 if (\GlobalVars::$mViewClass->__injectViewSources) {
 foreach (\GlobalVars::$mViewClass->__injectViewSources as $k => $v) {
 if ($v && is_callable($v)) {
 $viewOptions = new \stdClass();
 $viewOptions->isLayout = $isLayoutPage;
 $viewOptions->viewFile = $viewFile;
 $viewOptions->moduleName = $mName;
 $a = call_user_func($v, $viewOptions, $content[0]);
 if ($a) $content[0] = $a;
 }
 }
 }
 $tempFile = $tempPath . $tempFileName;
 $fp = fopen($tempFile, 'w');
 if ($fp) {
 fwrite($fp, $content[0]);
 fclose($fp);
 }
 if ($isSaveSView && $isLayoutPage === false) {
 $smallTempFileName = str_replace(".php", ".s.php", $tempFileName);
 $f2 = fopen($tempPath . $smallTempFileName, 'w');
 fwrite($f2, $content[1]);
 fclose($f2);
 }
 return $tempFile;
 }
 private function convertToViewTemplate($viewFile, $isLayoutPage) {
 $content = '';
 $phpCodeContent = '';
 $isNeedGetEndPHP = false;
 $isNeedGetContentInSection = false;
 $isNeedGetComment = false;
 $fn = fopen($viewFile, "r");
 if (!$fn) {
 throw new TException("Không mở được file " . $viewFile . ", vui lòng kiểm tra quyền", 501);
 }
 $lineCode = 0;
 while (!feof($fn)) {
 $lineCode++;
 if (\GlobalVars::$minifyView) $line = rtrim(fgets($fn)) . ' ';
 else $line = fgets($fn);
 if ($isNeedGetComment) {
 if (strpos($line, "--}}") === false) {
 continue;
 }
 $isNeedGetComment = false;
 continue;
 }
 if (strpos($line, "//") !== false && \GlobalVars::$minifyView) {
 $line .= "\n";
 }
 if (strpos($line, "@") !== false) {
 $startCommentIndex = strpos($line, "@@");
 if ($startCommentIndex !== false) $line = str_replace("@@", "sa-dho2g-135t3", $line);
 $line = str_replace("@php", "<?php", $line);
 $line = str_replace("@endphp", "?>", $line);
 $line = $this->replacePHPCode($line, "@if(", "if(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@while(", "while(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@foreach(", "foreach(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@for(", "for(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@elseif(", "} else if(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@if (", "if(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@while (", "while(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@foreach (", "foreach(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@for (", "for(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@elseif (", "} else if(", $lineCode, true);
 $line = $this->replacePHPCode($line, "@body(", '$this->viewBody(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@modelBinding(", '$this->modelBinding(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@labelFor(", '$this->createHtmlLabelFor(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@inputFor(", '$this->createHtmlInputFor(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@input(", '$this->createHtmlInput(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@select(", '$this->createHtmlSelect(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@errorMessage(", '$this->showErrorMessage(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@model(", '$this->generalModel(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@error(", '$this->showError(', $lineCode, true, ';');
 if ($isLayoutPage) {
 $line = $this->replacePHPCode($line, "@section(", '$this->viewSection(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@lang(", 'echo $this->layoutLang(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@menu(", '$this->readerLayoutMenu(', $lineCode, true, ';');
 }
 else {
 $line = $this->replacePHPCode($line, "@section(", '$this->startViewSection(', $lineCode, $isLayoutPage, ';');
 $line = $this->replacePHPCode($line, "@lang(", 'echo $this->lang(', $lineCode, true, ';');
 }
 $line = $this->replacePHPCode($line, "@yield(", '$this->viewField(', $lineCode, $isLayoutPage, ';');
 $line = $this->replacePHPCode($line, "@extension(", '$this->callExtension(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@include(", '$this->includePartial(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@style(", '$this->renderStyles(', $lineCode, $isLayoutPage, ';');
 $line = $this->replacePHPCode($line, "@script(", '$this->renderScripts(', $lineCode, true, ';');
 $line = $this->replacePHPCode($line, "@beginForm(", '$this->beginForm(', $lineCode, true, ';');
 $line = str_replace("@csrf()", "<?php echo csrf_token() ?>", $line);
 $line = str_replace("@endForm", '<?php echo $this->endForm() ?>', $line);
 $line = str_replace("@endif", "<?php } ?>", $line);
 $line = str_replace("@endwhile", "<?php } ?>", $line);
 $line = str_replace("@endforeach", "<?php } ?>", $line);
 $line = str_replace("@endfor", "<?php } ?>", $line);
 $line = str_replace("@break", "<?php break; ?>", $line);
 $line = str_replace("@else", "<?php } else { ?>", $line);
 if ($isLayoutPage) $line = str_replace("@endsection", '<?php $this->endViewSection(); ?>', $line);
 else $line = str_replace("@endsection", '<~?~php $this->endViewSection(); ~~?~>', $line);
 if ($startCommentIndex !== false) {
 $line = str_replace("sa-dho2g-135t3", "@", $line);
 }
 }
 $str = '';
 if (strpos($line, "{") !== false || strpos($line, "}") !== false) {
 if (strpos($line, "{{--") !== false) {
 if (strpos($line, "--}}") === false) {
 $isNeedGetComment = true;
 }
 continue;
 }
 $line = str_replace("{{", "<?php echo ", $line);
 $line = str_replace("}}", " ?>", $line);
 $line = str_replace("{!!", "<?php echo htmlspecialchars_decode(", $line);
 $line = str_replace("!!}", "); ?>", $line);
 $line = str_replace("{-", "<?php echo \$this->", $line);
 $line = str_replace("-}", "; ?>", $line);
 }
 $str = $line;
 if ($isLayoutPage) $content .= $str;
 else {
 $startIndex = strpos($str, "<~?~php");
 if ($startIndex !== false) {
 $ct = $str;
 $startIndexSestion = strpos($ct, '<~?~php $this->endViewSection');
 if ($startIndexSestion !== false) {
 $ct = str_replace('<~?~php $this->endViewSection(); ~~?~>', "", $ct);
 }
 $startIndexSestion = strpos($ct, '<~?~php $this->startViewSection(');
 if ($startIndexSestion !== false) {
 $len = strlen($ct);
 while (true) {
 $endIndex = strpos($ct, "~~?~>", $startIndexSestion + 32);
 if ($endIndex === false) {
 break;
 }
 $rep = substr($ct, $startIndexSestion, ($endIndex + 5) - $startIndexSestion);
 $ct = str_replace($rep, "", $ct);
 $endIndex += 5;
 if ($endIndex >= $len) break;
 $startIndexSestion = strpos($str, '<~?~php $this->startViewSection(', $endIndex);
 if ($startIndexSestion === false) break;
 }
 }
 $ct = str_replace("~~?~>", "?>", $ct);
 $content .= str_replace("<~?~php", "<?php", $ct);
 $len = strlen($str);
 while (true) {
 if ($isNeedGetContentInSection) {
 if (strpos($str, '$this->endViewSection(); ~~?~>') !== false) {
 $isNeedGetContentInSection = false;
 }
 }
 if ($isNeedGetContentInSection) $phpCodeContent .= substr($str, $startIndex);
 $startIndex += 7;
 $endIndex = strpos($str, "~~?~>", $startIndex);
 if ($endIndex === false) {
 break;
 }
 $strS = '<?php' . substr($str, $startIndex, $endIndex - $startIndex) . '?>';
 if ($isNeedGetContentInSection === false) {
 if (strpos($strS, '<?php $this->startViewSection(') !== false) $isNeedGetContentInSection = true;
 }
 $phpCodeContent .= $strS;
 if ($isNeedGetContentInSection) {
 $phpCodeContent .= substr($str, $endIndex + 5);
 }
 $endIndex += 5;
 if ($endIndex >= $len) break;
 $startIndex = strpos($str, "<~?~php", $endIndex);
 if ($startIndex === false) break;
 }
 }
 else {
 if ($isNeedGetContentInSection) {
 $phpCodeContent .= $str;
 }
 else {
 $content .= $str;
 }
 }
 }
 }
 fclose($fn);
 return [$content, $phpCodeContent];
 }
 public function replacePHPCode($line, $str, $nStr, $lineCode, $isLayoutPage, $endWith = '{') {
 $strLen = strlen($str);
 $startIndex = strpos($line, $str, 0);
 if ($startIndex !== false) {
 $retVal = '';
 while (true) {
 $line2 = substr($line, $startIndex + $strLen);
 $nextCtIndex = strpos($line2, "@", 0);
 if ($nextCtIndex === false) {
 $nextCtIndex = strlen($line2);
 }
 $count = 1;
 $endMGIndex = 0;
 for ($i = 0;
 $i < $nextCtIndex;
 $i++) {
 $c = substr($line2, $i, 1);
 if ($c == "(") $count++;
 else if ($c == ")") $count--;
 $endMGIndex = $i;
 if ($count == 0) break;
 }
 if ($count > 0) throw new TException($str . ' Chưa có đóng ngoạc kết thúc tại dòng ' . $lineCode, 501);
 if ($isLayoutPage) $line = substr($line, 0, $startIndex) . '<?php ' . $nStr . substr($line2, 0, $endMGIndex + 1) . $endWith . ' ?>' . substr($line2, $endMGIndex + 1);
 else $line = substr($line, 0, $startIndex) . '<~?~php ' . $nStr . substr($line2, 0, $endMGIndex + 1) . $endWith . ' ~~?~>' . substr($line2, $endMGIndex + 1);
 $startIndex = strpos($line, $str, 0);
 if ($startIndex === false) {
 break;
 }
 }
 return $line;
 }
 return $line;
 }
 }
 