Guest User

Untitled

a guest
Jul 17th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.90 KB | None | 0 0
  1. <?php namespace System\Traits;
  2.  
  3. use File;
  4. use Lang;
  5. use Event;
  6. use Block;
  7. use SystemException;
  8. use Exception;
  9. use Throwable;
  10. use Symfony\Component\Debug\Exception\FatalThrowableError;
  11.  
  12. /**
  13. * View Maker Trait
  14. * Adds view based methods to a class
  15. *
  16. * @package october\system
  17. * @author Alexey Bobkov, Samuel Georges
  18. */
  19. trait ViewMaker
  20. {
  21. /**
  22. * @var array A list of variables to pass to the page.
  23. */
  24. public $vars = [];
  25.  
  26. /**
  27. * @var string|array Specifies a path to the views directory.
  28. */
  29. protected $viewPath;
  30.  
  31. /**
  32. * @var string Specifies a path to the layout directory.
  33. */
  34. protected $layoutPath;
  35.  
  36. /**
  37. * @var string Layout to use for the view.
  38. */
  39. public $layout;
  40.  
  41. /**
  42. * @var bool Prevents the use of a layout.
  43. */
  44. public $suppressLayout = false;
  45.  
  46. /**
  47. * Prepends a path on the available view path locations.
  48. * @param string|array $path
  49. * @return void
  50. */
  51. public function addViewPath($path)
  52. {
  53. $this->viewPath = (array) $this->viewPath;
  54.  
  55. if (is_array($path)) {
  56. $this->viewPath = array_merge($path, $this->viewPath);
  57. }
  58. else {
  59. array_unshift($this->viewPath, $path);
  60. }
  61. }
  62.  
  63. /**
  64. * Returns the active view path locations.
  65. * @return array
  66. */
  67. public function getViewPaths()
  68. {
  69. return (array) $this->viewPath;
  70. }
  71.  
  72. /**
  73. * Render a partial file contents located in the views folder.
  74. * @param string $partial The view to load.
  75. * @param array $params Parameter variables to pass to the view.
  76. * @param bool $throwException Throw an exception if the partial is not found.
  77. * @return mixed Partial contents or false if not throwing an exception.
  78. */
  79. public function makePartial($partial, $params = [], $throwException = true)
  80. {
  81. $notRealPath = realpath($partial) === false || is_dir($partial) === true;
  82. if (!File::isPathSymbol($partial) && $notRealPath) {
  83. $folder = strpos($partial, '/') !== false ? dirname($partial) . '/' : '';
  84. $partial = $folder . '_' . strtolower(basename($partial)).'.htm';
  85. }
  86.  
  87. $partialPath = $this->getViewPath($partial);
  88.  
  89. if (!File::exists($partialPath)) {
  90. if ($throwException) {
  91. throw new SystemException(Lang::get('backend::lang.partial.not_found_name', ['name' => $partialPath]));
  92. }
  93. else {
  94. return false;
  95. }
  96. }
  97.  
  98. return $this->makeFileContents($partialPath, $params);
  99. }
  100.  
  101. /**
  102. * Loads a view with the name specified. Applies layout if its name is provided by the parent object.
  103. * The view file must be situated in the views directory, and has the extension "htm".
  104. * @param string $view Specifies the view name, without extension. Eg: "index".
  105. * @return string
  106. */
  107. public function makeView($view)
  108. {
  109. $viewPath = $this->getViewPath(strtolower($view) . '.htm');
  110. $contents = $this->makeFileContents($viewPath);
  111. return $this->makeViewContent($contents);
  112. }
  113.  
  114. /**
  115. * Renders supplied contents inside a layout.
  116. * @param string $contents The inner contents as a string.
  117. * @param string $layout Specifies the layout name.
  118. * @return string
  119. */
  120. public function makeViewContent($contents, $layout = null)
  121. {
  122. if ($this->suppressLayout || $this->layout == '') {
  123. return $contents;
  124. }
  125.  
  126. // Append any undefined block content to the body block
  127. Block::set('undefinedBlock', $contents);
  128. Block::append('body', Block::get('undefinedBlock'));
  129. return $this->makeLayout($layout);
  130. }
  131.  
  132. /**
  133. * Render a layout.
  134. * @param string $name Specifies the layout name.
  135. * If this parameter is omitted, the $layout property will be used.
  136. * @param array $params Parameter variables to pass to the view.
  137. * @param bool $throwException Throw an exception if the layout is not found
  138. * @return mixed The layout contents, or false.
  139. */
  140. public function makeLayout($name = null, $params = [], $throwException = true)
  141. {
  142. $layout = $name === null ? $this->layout : $name;
  143. if ($layout == '') {
  144. return '';
  145. }
  146.  
  147. $layoutPath = $this->getViewPath($layout . '.htm', $this->layoutPath);
  148.  
  149. if (!File::exists($layoutPath)) {
  150. if ($throwException) {
  151. throw new SystemException(Lang::get('cms::lang.layout.not_found_name', ['name' => $layoutPath]));
  152. }
  153. else {
  154. return false;
  155. }
  156. }
  157.  
  158. return $this->makeFileContents($layoutPath, $params);
  159. }
  160.  
  161. /**
  162. * Renders a layout partial
  163. * @param string $partial The view to load.
  164. * @param array $params Parameter variables to pass to the view.
  165. * @return string The layout partial contents
  166. */
  167. public function makeLayoutPartial($partial, $params = [])
  168. {
  169. if (!File::isLocalPath($partial) && !File::isPathSymbol($partial)) {
  170. $folder = strpos($partial, '/') !== false ? dirname($partial) . '/' : '';
  171. $partial = $folder . '_' . strtolower(basename($partial));
  172. }
  173.  
  174. return $this->makeLayout($partial, $params);
  175. }
  176.  
  177. /**
  178. * Locates a file based on its definition. The file name can be prefixed with a
  179. * symbol (~|$) to return in context of the application or plugin base path,
  180. * otherwise it will be returned in context of this object view path.
  181. * @param string $fileName File to load.
  182. * @param mixed $viewPath Explicitly define a view path.
  183. * @return string Full path to the view file.
  184. */
  185. public function getViewPath($fileName, $viewPath = null)
  186. {
  187. if (!isset($this->viewPath)) {
  188. $this->viewPath = $this->guessViewPath();
  189. }
  190.  
  191. if (!$viewPath) {
  192. $viewPath = $this->viewPath;
  193. }
  194.  
  195. $fileName = File::symbolizePath($fileName);
  196.  
  197. if (File::isLocalPath($fileName)) {
  198. return $fileName;
  199. }
  200.  
  201. if (!is_array($viewPath)) {
  202. $viewPath = [$viewPath];
  203. }
  204.  
  205. foreach ($viewPath as $path) {
  206. $_fileName = File::symbolizePath($path) . '/' . $fileName;
  207. if (File::isFile($_fileName)) {
  208. return $_fileName;
  209. }
  210. }
  211.  
  212. return $fileName;
  213. }
  214.  
  215. /**
  216. * Includes a file path using output buffering.
  217. * Ensures that vars are available.
  218. * @param string $filePath Absolute path to the view file.
  219. * @param array $extraParams Parameters that should be available to the view.
  220. * @return string
  221. */
  222. public function makeFileContents($filePath, $extraParams = [])
  223. {
  224. if (!strlen($filePath) || !File::isFile($filePath) || !File::isLocalPath($filePath)) {
  225. return '';
  226. }
  227.  
  228. if (!is_array($extraParams)) {
  229. $extraParams = [];
  230. }
  231.  
  232. $vars = array_merge($this->vars, $extraParams);
  233.  
  234. $obLevel = ob_get_level();
  235.  
  236. ob_start();
  237.  
  238. extract($vars);
  239.  
  240. // We'll evaluate the contents of the view inside a try/catch block so we can
  241. // flush out any stray output that might get out before an error occurs or
  242. // an exception is thrown. This prevents any partial views from leaking.
  243. try {
  244. include $filePath;
  245. }
  246. catch (Exception $e) {
  247. $this->handleViewException($e, $obLevel);
  248. }
  249. catch (Throwable $e) {
  250. $this->handleViewException(new FatalThrowableError($e), $obLevel);
  251. }
  252.  
  253. return ob_get_clean();
  254. }
  255.  
  256. /**
  257. * Handle a view exception.
  258. *
  259. * @param \Exception $e
  260. * @param int $obLevel
  261. * @return void
  262. *
  263. */
  264. protected function handleViewException($e, $obLevel)
  265. {
  266. while (ob_get_level() > $obLevel) {
  267. ob_end_clean();
  268. }
  269.  
  270. throw $e;
  271. }
  272.  
  273. /**
  274. * Guess the package path for the called class.
  275. * @param string $suffix An extra path to attach to the end
  276. * @param bool $isPublic Returns public path instead of an absolute one
  277. * @return string
  278. */
  279. public function guessViewPath($suffix = '', $isPublic = false)
  280. {
  281. $class = get_called_class();
  282. return $this->guessViewPathFrom($class, $suffix, $isPublic);
  283. }
  284.  
  285. /**
  286. * Guess the package path from a specified class.
  287. * @param string $class Class to guess path from.
  288. * @param string $suffix An extra path to attach to the end
  289. * @param bool $isPublic Returns public path instead of an absolute one
  290. * @return string
  291. */
  292. public function guessViewPathFrom($class, $suffix = '', $isPublic = false)
  293. {
  294. $classFolder = strtolower(class_basename($class));
  295. $classFile = realpath(dirname(File::fromClass($class)));
  296. $guessedPath = $classFile ? $classFile . '/' . $classFolder . $suffix : null;
  297. return ($isPublic) ? File::localToPublic($guessedPath) : $guessedPath;
  298. }
  299. }
Add Comment
Please, Sign In to add comment