1<?php 2 3namespace ComboStrap; 4 5 6use action_plugin_combo_css; 7use ComboStrap\Api\ApiRouter; 8use ComboStrap\Meta\Field\PageTemplateName; 9use ComboStrap\Web\Url; 10use ComboStrap\Web\UrlEndpoint; 11 12/** 13 * 14 * This code permits to render a markup from a string passed as argument 15 * 16 * Technically, it's the same than {@link FetcherMarkup} 17 * but: 18 * * it outputs the HTML within a minimal HTML page (no layout as in {@link FetcherPage}) 19 * * it gets the input from the url query properties 20 * 21 * It's used primarily by {@link \syntax_plugin_combo_webcode} 22 * that's why it's called webcode. 23 * 24 */ 25class FetcherMarkupWebcode extends IFetcherAbs implements IFetcherString 26{ 27 28 const CANONICAL = "webcode"; 29 const NAME = "markup"; 30 31 public const MARKUP_PROPERTY = "markup"; 32 const TITLE_PROPERTY = "title"; 33 34 private string $requestedMarkup; 35 private string $requestedTitle = "ComboStrap WebCode - Markup Renderer"; 36 37 public static function createFetcherMarkup(string $markup): FetcherMarkupWebcode 38 { 39 return (new FetcherMarkupWebcode()) 40 ->setRequestedMarkup($markup); 41 } 42 43 /** 44 * @throws ExceptionBadState - the markup is mandatory 45 */ 46 function getFetchUrl(Url $url = null): Url 47 { 48 $url = UrlEndpoint::createAjaxUrl() 49 ->addQueryParameter(ApiRouter::AJAX_CALL_ATTRIBUTE, ApiRouter::AJAX_CALL_VALUE) 50 ->addQueryParameter(self::MARKUP_PROPERTY, $this->getRequestedMarkup()) 51 ->addQueryParameter(self::TITLE_PROPERTY, $this->getRequestedTitle()); 52 return parent::getFetchUrl($url); 53 } 54 55 56 function getBuster(): string 57 { 58 try { 59 return FileSystems::getCacheBuster(ClassUtility::getClassPath(FetcherMarkupWebcode::class)); 60 } catch (ExceptionNotFound|\ReflectionException $e) { 61 LogUtility::internalError("The cache buster should be good. Error:{$e->getMessage()}", self::NAME); 62 return ""; 63 } 64 } 65 66 public function buildFromTagAttributes(TagAttributes $tagAttributes): IFetcher 67 { 68 69 $markupProperty = self::MARKUP_PROPERTY; 70 $markup = $tagAttributes->getValueAndRemove($markupProperty); 71 if ($markup === null) { 72 throw new ExceptionBadArgument("The markup property ($markupProperty) is mandatory"); 73 } 74 $this->setRequestedMarkup($markup); 75 $title = $tagAttributes->getValueAndRemove(self::TITLE_PROPERTY); 76 if ($title !== null) { 77 $this->setRequestedTitle($title); 78 } 79 return parent::buildFromTagAttributes($tagAttributes); 80 } 81 82 83 public function getMime(): Mime 84 { 85 return Mime::getHtml(); 86 } 87 88 public function getFetcherName(): string 89 { 90 return self::NAME; 91 } 92 93 /** 94 * @return string 95 * @throws ExceptionBadState - if the markup was not defined 96 * @throws ExceptionCompile - if any error 97 */ 98 public function getFetchString(): string 99 { 100 101 /** 102 * Conf 103 */ 104 ExecutionContext::getActualOrCreateFromEnv() 105 ->getConfig() 106 ->setConf(action_plugin_combo_css::CONF_DISABLE_DOKUWIKI_STYLESHEET, true); 107 108 $fetcherCache = FetcherCache::createFrom($this); 109 if ($fetcherCache->isCacheUsable()) { 110 try { 111 return FileSystems::getContent($fetcherCache->getFile()); 112 } catch (ExceptionNotFound $e) { 113 $message = "The cache file should exists"; 114 if (PluginUtility::isDevOrTest()) { 115 throw new ExceptionRuntimeInternal($message); 116 } 117 LogUtility::internalError($message); 118 } 119 } 120 121 $requestedMarkup = $this->getRequestedMarkup(); 122 123 try { 124 $mainContent = FetcherMarkup::confRoot() 125 ->setRequestedMarkupString($requestedMarkup) 126 ->setDeleteRootBlockElement(true) 127 ->setRequestedMimeToXhtml() 128 ->setRequestedContextPathWithDefault() 129 ->setIsStandAloneCodeExecution(true) 130 ->build() 131 ->getFetchString(); 132 } catch (ExceptionNotExists|ExceptionCompile $e) { 133 throw new ExceptionRuntimeInternal("An error has occurred while transforming the markup fragment to HTML. Error: {$e->getMessage()}", self::CANONICAL, 1, $e); 134 } 135 136 $title = $this->getRequestedTitle(); 137 138 $html = TemplateForWebPage::create() 139 ->setRequestedTitle($title) 140 ->setRequestedTemplateName(PageTemplateName::BLANK_TEMPLATE_VALUE) 141 ->setRequestedEnableTaskRunner(false) 142 ->setIsIframe(true) 143 ->setMainContent($mainContent) 144 ->render(); 145 146 $fetcherCache->storeCache($html); 147 return $html; 148 149 } 150 151 public function setRequestedMarkup(string $markup): FetcherMarkupWebcode 152 { 153 $this->requestedMarkup = $markup; 154 return $this; 155 156 } 157 158 public function setRequestedTitle(string $title): FetcherMarkupWebcode 159 { 160 $this->requestedTitle = $title; 161 return $this; 162 } 163 164 /** 165 * @throws ExceptionBadState 166 */ 167 private function getRequestedMarkup(): string 168 { 169 if (!isset($this->requestedMarkup)) { 170 throw new ExceptionBadState("The markup was not defined.", self::CANONICAL); 171 } 172 return $this->requestedMarkup; 173 } 174 175 private function getRequestedTitle(): string 176 { 177 return $this->requestedTitle; 178 } 179 180 181 public function getLabel(): string 182 { 183 return self::CANONICAL; 184 } 185 186} 187