PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Plugin/CoreCompiler/Model.php

https://gitlab.com/x33n/ImpressPages
PHP | 313 lines | 224 code | 58 blank | 31 comment | 26 complexity | d93e96704f6f3471e0e2d36c98c774b3 MD5 | raw file
  1. <?php
  2. namespace Plugin\CoreCompiler;
  3. class Model
  4. {
  5. public function generateAdminJS()
  6. {
  7. // source:
  8. // - root/Ip/Internal/Core/assets/admin/
  9. // output:
  10. // - assets/admin.min.js
  11. $items = array();
  12. $items[] = ipFile('Ip/Internal/Core/assets/admin/managementMode.js');
  13. $items[] = ipFile('Ip/Internal/Core/assets/admin/functions.js');
  14. $items[] = ipFile('Ip/Internal/Core/assets/admin/validator.js');
  15. $items[] = ipFile('Ip/Internal/Core/assets/admin/bootstrap/bootstrap.js');
  16. $items[] = ipFile('Ip/Internal/Core/assets/admin/bootstrap-switch/bootstrap-switch.js');
  17. $jsFile = ipFile('Ip/Internal/Core/assets/admin.min.js');
  18. $this->minifyJS($items, $jsFile);
  19. }
  20. public function generateIpCoreJS()
  21. {
  22. // source:
  23. // - root/Ip/Internal/Core/assets/ipCoreJs/
  24. // output:
  25. // - assets/ipCoreJs.min.js
  26. $items = array();
  27. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/jquery.js'); // default, global jQuery
  28. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/console.log.js');
  29. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/functions.js');
  30. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/jquery.tools.form.js');
  31. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/form/color.js');
  32. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/form/file.js');
  33. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/form/richtext.js');
  34. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/form/repositoryFile.js');
  35. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/form/url.js');
  36. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/form.js');
  37. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/validator.js');
  38. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/widgets.js');
  39. $items[] = ipFile('Ip/Internal/Core/assets/ipCore/ipCore.js');
  40. $jsFile = ipFile('Ip/Internal/Core/assets/ipCore.min.js');
  41. $this->minifyJS($items, $jsFile);
  42. }
  43. public function generateManagementJS()
  44. {
  45. // source:
  46. // - root/Ip/Internal/Content/assets/management/
  47. // - root/Ip/Internal/Content/Widget/*/assets/
  48. // output:
  49. // - assets/management.min.js
  50. $items[] = ipFile('Ip/Internal/Content/assets/management/ipContentManagementInit.js');
  51. $items[] = ipFile('Ip/Internal/Content/assets/management/content.js');
  52. $items[] = ipFile('Ip/Internal/Content/assets/management/jquery.ip.contentManagement.js');
  53. $items[] = ipFile('Ip/Internal/Content/assets/management/jquery.ip.widgetbutton.js');
  54. $items[] = ipFile('Ip/Internal/Content/assets/management/jquery.ip.layoutModal.js');
  55. $items[] = ipFile('Ip/Internal/Content/assets/management/jquery.ip.block.js');
  56. $items[] = ipFile('Ip/Internal/Content/assets/management/jquery.ip.widget.js');
  57. $items[] = ipFile('Ip/Internal/Content/assets/management/exampleContent.js');
  58. $items[] = ipFile('Ip/Internal/Content/assets/management/drag.js');
  59. $items[] = ipFile('Ip/Internal/Content/Widget/Columns/assets/Columns.js');
  60. $items[] = ipFile('Ip/Internal/Content/Widget/File/assets/File.js');
  61. $items[] = ipFile('Ip/Internal/Content/Widget/File/assets/jquery.ipWidgetFile.js');
  62. $items[] = ipFile('Ip/Internal/Content/Widget/File/assets/jquery.ipWidgetFileContainer.js');
  63. $items[] = ipFile('Ip/Internal/Content/Widget/Form/assets/Form.js');
  64. $items[] = ipFile('Ip/Internal/Content/Widget/Form/assets/FormContainer.js');
  65. $items[] = ipFile('Ip/Internal/Content/Widget/Form/assets/FormField.js');
  66. $items[] = ipFile('Ip/Internal/Content/Widget/Form/assets/FormOptions.js');
  67. $items[] = ipFile('Ip/Internal/Content/Widget/Html/assets/Html.js');
  68. $items[] = ipFile('Ip/Internal/Content/Widget/Video/assets/Video.js');
  69. $items[] = ipFile('Ip/Internal/Content/Widget/Image/assets/Image.js');
  70. $items[] = ipFile('Ip/Internal/Content/Widget/Gallery/assets/Gallery.js');
  71. $items[] = ipFile('Ip/Internal/Content/Widget/Text/assets/Text.js');
  72. $items[] = ipFile('Ip/Internal/Content/Widget/Heading/assets/Heading.js');
  73. $items[] = ipFile('Ip/Internal/Content/Widget/Heading/assets/HeadingModal.js');
  74. $items[] = ipFile('Ip/Internal/Content/Widget/Map/assets/Map.js');
  75. $jsFile = ipFile('Ip/Internal/Content/assets/management.min.js');
  76. $this->minifyJS($items, $jsFile);
  77. }
  78. public function generateInlineManagementJS()
  79. {
  80. // source:
  81. // - root/Ip/Internal/InlineManagement/assets/src/
  82. // output:
  83. // - assets/inlineManagement.min.js
  84. $items = $this->globRecursive(ipFile('Ip/Internal/InlineManagement/assets/src/') . '*.js');
  85. if (!$items) {
  86. return false;
  87. }
  88. $jsFile = ipFile('Ip/Internal/InlineManagement/assets/inlineManagement.min.js');
  89. $this->minifyJS($items, $jsFile);
  90. }
  91. /**
  92. * Generate default content styles
  93. *
  94. * @return none
  95. */
  96. public function generateIpContent()
  97. {
  98. $items = $this->globRecursive(ipFile('Ip/Internal/Core/assets/ipContent/less/') . '*.less');
  99. if (!$items) {
  100. return false;
  101. }
  102. $lessFile = ipFile('Ip/Internal/Core/assets/ipContent/ipContent.less');
  103. $cssFile = ipFile('Ip/Internal/Core/assets/ipContent/ipContent.css');
  104. $lastBuildTime = file_exists($cssFile) ? filemtime($cssFile) : 0;
  105. $hasChanged = false;
  106. foreach ($items as $path) {
  107. if (filemtime($path) > $lastBuildTime) {
  108. $hasChanged = true;
  109. break;
  110. }
  111. }
  112. if (!$hasChanged) {
  113. return;
  114. }
  115. try {
  116. require_once ipFile('Ip/Lib/less.php/Less.php');
  117. $parserOptions = array(
  118. 'cache_dir' => ipFile('file/tmp/less/'),
  119. 'relativeUrls' => false
  120. );
  121. $parser = new \Less_Parser($parserOptions);
  122. $parser->parseFile($lessFile);
  123. $css = $parser->getCss();
  124. file_put_contents($cssFile, $css);
  125. } catch(Exception $e) {
  126. ipLog()->error('Less compilation error: IpContent - ' . $e->getMessage());
  127. }
  128. }
  129. /**
  130. * Generate core Bootstrap styles
  131. *
  132. * @return none
  133. */
  134. public function generateCoreBootstrap()
  135. {
  136. $items = $this->globRecursive(ipFile('Ip/Internal/Core/assets/admin/ip/') . '*.less');
  137. if (!$items) {
  138. return false;
  139. }
  140. $lessTempFile = ipFile('Ip/Internal/Core/assets/admin/admin.tmp.less');
  141. $cssTempFile = ipFile('Ip/Internal/Core/assets/admin/admin.tmp.css');
  142. $lessFile = ipFile('Ip/Internal/Core/assets/admin/admin.less');
  143. $cssFile = ipFile('Ip/Internal/Core/assets/admin/admin.css');
  144. $lastBuildTimeTemp = file_exists($cssTempFile) ? filemtime($cssTempFile) : 0;
  145. $lastBuildTime = file_exists($cssFile) ? filemtime($cssFile) : 0;
  146. $hasChangedTemp = false;
  147. $hasChanged = false;
  148. foreach ($items as $path) {
  149. if (filemtime($path) > $lastBuildTimeTemp) {
  150. $hasChangedTemp = true;
  151. break;
  152. }
  153. }
  154. if ($lastBuildTimeTemp > $lastBuildTime) {
  155. $hasChanged = true;
  156. }
  157. if (!$hasChangedTemp && !$hasChanged) {
  158. return;
  159. }
  160. try {
  161. set_time_limit(300); // Compiling might take some time
  162. require_once ipFile('Ip/Lib/less.php/Less.php');
  163. $parserOptions = array(
  164. 'cache_dir' => ipFile('file/tmp/less/'),
  165. 'relativeUrls' => false
  166. );
  167. if ($hasChangedTemp) { // skipping temp compilation if only main file is missing
  168. $parserTemp = new \Less_Parser($parserOptions);
  169. $parserTemp->parseFile($lessTempFile);
  170. $cssTemp = $parserTemp->getCss();
  171. file_put_contents($cssTempFile, $cssTemp);
  172. }
  173. $parser = new \Less_Parser($parserOptions);
  174. $parser->parseFile($lessFile);
  175. $css = $parser->getCss();
  176. file_put_contents($cssFile, $css);
  177. } catch(Exception $e) {
  178. ipLog()->error('Less compilation error: Core Bootstrap - ' . $e->getMessage());
  179. }
  180. }
  181. protected function minifyJS($filesToMinify, $fileForOutput, $force = false)
  182. {
  183. $items = $filesToMinify;
  184. $jsFile = $fileForOutput;
  185. $lastBuildTime = file_exists($jsFile) ? filemtime($jsFile) : 0;
  186. $hasChanged = false;
  187. foreach ($items as $path) {
  188. if (is_file($path) && filemtime($path) > $lastBuildTime) {
  189. $hasChanged = true;
  190. break;
  191. }
  192. }
  193. if (!$hasChanged && !$force) {
  194. return;
  195. }
  196. $js = '';
  197. foreach ($items as $path) {
  198. if (is_file($path) && is_readable($path)) {
  199. $js .= file_get_contents($path);
  200. } else {
  201. ipLog()->error('Cannot read file to minify it: '. $path);
  202. }
  203. }
  204. require_once 'lib/JSMin.php';
  205. $minJS = \JSMin::minify($js);
  206. file_put_contents($jsFile, $minJS);
  207. }
  208. protected function minifyCSS($filesToMinify, $fileForOutput, $force = false)
  209. {
  210. $items = $filesToMinify;
  211. $cssFile = $fileForOutput;
  212. $lastBuildTime = file_exists($cssFile) ? filemtime($cssFile) : 0;
  213. $hasChanged = false;
  214. foreach ($items as $path) {
  215. if (is_file($path) && filemtime($path) > $lastBuildTime) {
  216. $hasChanged = true;
  217. break;
  218. }
  219. }
  220. if (!$hasChanged && !$force) {
  221. return;
  222. }
  223. $css = '';
  224. foreach ($items as $path) {
  225. if (is_file($path) && is_readable($path)) {
  226. $css .= file_get_contents($path);
  227. } else {
  228. ipLog()->error('Cannot read file to minify it: '. $path);
  229. }
  230. }
  231. require_once 'lib/CSSMin.php';
  232. $cssmin = new \CSSmin();
  233. $minCSS = trim($cssmin->run($css));
  234. file_put_contents($cssFile, $minCSS);
  235. }
  236. /**
  237. * Recursive glob function from PHP manual (http://php.net/manual/en/function.glob.php)
  238. */
  239. protected function globRecursive($pattern, $flags = 0)
  240. {
  241. //some systems return false instead of empty array if no matches found in glob function
  242. $files = glob($pattern, $flags);
  243. if (!is_array($files)) {
  244. return array();
  245. }
  246. $dirs = glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT);
  247. if (!is_array($dirs)) {
  248. return $files;
  249. }
  250. foreach ($dirs as $dir) {
  251. $files = array_merge($files, $this->globRecursive($dir . '/' . basename($pattern), $flags));
  252. }
  253. return $files;
  254. }
  255. }