UI.class.php (7774B)
1 <?php 2 3 namespace cms_ui; 4 5 use BadMethodCallException; 6 use cms\action\RequestParams; 7 use cms\Dispatcher; 8 use DomainException; 9 use Exception; 10 use Http; 11 use Less_Parser; 12 use Logger; 13 use LogicException; 14 use ObjectNotFoundException; 15 use OpenRatException; 16 use SecurityException; 17 use template_engine\TemplateEngine; 18 use template_engine\TemplateEngineInfo; 19 20 21 class UI 22 { 23 /** 24 * Shows the complete UI. 25 */ 26 public static function execute() 27 { 28 $request = new RequestParams(); 29 30 try 31 { 32 define('COOKIE_PATH',dirname($_SERVER['SCRIPT_NAME'])); 33 34 // Everything is UTF-8. 35 header('Content-Type: text/html; charset=UTF-8'); 36 37 // Sending the Content-Security-Policy. 38 self::setContentSecurityPolicy(); 39 40 if (empty($request->action)) 41 $request->action = 'index'; 42 43 if (empty($request->method)) 44 $request->method = 'show'; 45 46 UI::executeAction($request); 47 48 } catch (BadMethodCallException $e) { 49 // Action-Method does not exist. 50 Logger::warn( $e->__toString() ); 51 Http::noContent(); 52 } catch (ObjectNotFoundException $e) { 53 Logger::debug("Object not found: " . $e->__toString()); // Nur Debug, da dies bei gelöschten Objekten vorkommen kann. 54 Http::noContent(); 55 } catch (OpenRatException $e) { 56 Logger::warn( $e->__toString() ); 57 throw new LogicException(lang($e->key),0, $e); 58 } catch (SecurityException $e) { 59 Logger::info($e->getMessage()); 60 Http::noContent(); 61 62 // this is not good at all, because the user may have signed off. 63 //Http::notAuthorized("You are not allowed to execute this action."); 64 } catch (Exception $e) { 65 Logger::warn( $e->__toString() ); 66 throw new LogicException("Internal CMS error: ".$e->__toString(),0, $e); 67 } 68 } 69 70 71 private static function executeAction($request) 72 { 73 $dispatcher = new Dispatcher(); 74 $dispatcher->request = $request; 75 76 $data = $dispatcher->doAction(); 77 78 79 // The action is able to change its method and action name. 80 $subaction = $dispatcher->request->method; 81 $action = $dispatcher->request->action; 82 83 $tplName = $action . '/' . $subaction; 84 85 UI::outputTemplate($request,$tplName, $data['output']); 86 } 87 88 89 /** 90 * Executes and outputs a HTML template. 91 * 92 * @param $templateName string Name of template 93 * @param $outputData array Output data 94 */ 95 private static function outputTemplate($request, $templateName, $outputData) 96 { 97 $templateFile = __DIR__.'/themes/default/html/views/' . $templateName . '.tpl.src.xml'; 98 99 if ( DEVELOPMENT ) 100 header('X-OR-Template: '.$templateFile); 101 102 $engine = new TemplateEngine(); 103 $engine->request = $request; 104 $engine->executeTemplate( $templateFile, $outputData ); 105 } 106 107 108 /** 109 * Content-Security-Policy. 110 */ 111 private static function setContentSecurityPolicy() 112 { 113 //if (config('security','content-security-policy')) // config is not loaded yet. 114 $contentSecurityPolicyEntries = array( 115 'default-src \'none\'', 116 'script-src \'self\'', 117 // No <object>, <embed> or <applet>. 118 'object-src \'none\'', 119 // no external CSS 120 'style-src \'self\'', 121 // no external images. 122 'img-src \'self\'', 123 // No <audio>, <video> elements 124 'media-src \'none\'', 125 // For preview of urls we need to show every url in an iframe. 126 'frame-src *', 127 'worker-src \'self\'', 128 'form-action \'self\'', 129 'font-src \'self\'', 130 // Ajax-Calls 131 'connect-src \'self\''); 132 header('Content-Security-Policy: ' . implode(';', $contentSecurityPolicyEntries)); 133 } 134 135 136 public static function updateProduction() 137 { 138 self::updateProductionCSS(); 139 self::updateProductionJS(); 140 } 141 142 private static function updateProductionCSS() 143 { 144 $productionCSSFile = __DIR__ . 'cms-ui/themes/default/production/combined.min.css'; 145 146 $css = self::getCSSFiles(); 147 //$css[] = OR_HTML_MODULES_DIR . 'editor/codemirror/lib/codemirror'; 148 149 // Komponentenbasiertes CSS 150 151 $modified = false; 152 foreach ($css as $cssF) 153 { 154 $lessFile = $cssF . '.less'; 155 $cssFile = $cssF . '.css'; 156 $cssMinFile = $cssF . '.min.css'; 157 158 if (! is_file($lessFile)) 159 { 160 Logger::warn("Stylesheet not found: $lessFile"); 161 continue; 162 } 163 elseif (! is_file($cssFile) || ! is_writable($cssFile)) 164 { 165 Logger::warn("Stylesheet output file not found or not writable: $cssFile"); 166 continue; 167 } 168 elseif (! is_file($cssMinFile) || ! is_writable($cssMinFile)) 169 { 170 Logger::warn("Stylesheet output file not found or not writable: $cssMinFile"); 171 continue; 172 } 173 else 174 { 175 if (filemtime($lessFile) > filemtime($cssMinFile)) 176 { 177 // LESS-Source wurde geändert, CSS-Version muss aktualisiert werden. 178 $modified = true; 179 180 // Den absoluten Pfad zur LESS-Datei ermitteln. Dieser wird vom LESS-Parser für den korrekten Link 181 // auf die LESS-Datei in der Sourcemap benötigt. 182 $pfx = substr(realpath($lessFile),0,0-strlen(basename($lessFile))); 183 184 $parser = new Less_Parser(array( 185 'sourceMap' => true, 186 'indentation' => ' ', 187 'outputSourceFiles' => false, 188 'sourceMapBasepath' => $pfx 189 )); 190 191 192 $parser->parseFile( ltrim($lessFile,'./') ); 193 $source = $parser->getCss(); 194 195 file_put_contents($cssFile, $source); 196 197 $parser = new Less_Parser(array( 198 'compress' => true, 199 'sourceMap' => false, 200 'indentation' => '' 201 )); 202 $parser->parseFile($lessFile); 203 $source = $parser->getCss(); 204 205 206 file_put_contents($cssMinFile, $source); 207 } 208 209 $outFiles[] = $cssFile; 210 } 211 } 212 213 if ($modified) 214 { 215 if ( !is_writable($productionCSSFile)) 216 { 217 Logger::warn('not writable: '.$productionCSSFile); 218 } 219 else 220 { 221 file_put_contents($productionCSSFile,''); 222 foreach ($css as $cssF) 223 { 224 $cssMinFile = $cssF . '.min.css'; 225 if ( is_file($cssMinFile)) 226 file_put_contents($productionCSSFile,file_get_contents($cssMinFile),FILE_APPEND); 227 } 228 } 229 } 230 231 } 232 233 private static function updateProductionJS() 234 { 235 } 236 237 /** 238 * @return array 239 */ 240 private static function getCSSFiles() 241 { 242 $css = array(); 243 $css[] = OR_THEMES_DIR . 'default/css/openrat-ui'; 244 $css[] = OR_THEMES_DIR . 'default/css/openrat-workbench'; 245 246 foreach (TemplateEngineInfo::getLESSFiles() as $lessFile) 247 { 248 $css[] = OR_HTML_MODULES_DIR . 'template-engine/components/html/' . $lessFile . '/' . $lessFile; 249 } 250 251 return $css; 252 } 253 }