PageRenderTime 30ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Ip/Internal/Design/Model.php

https://gitlab.com/x33n/ImpressPages
PHP | 323 lines | 215 code | 75 blank | 33 comment | 50 complexity | 50ff4b26874ffd3d72fca36764750f0e MD5 | raw file
  1. <?php
  2. /**
  3. * @package ImpressPages
  4. *
  5. */
  6. namespace Ip\Internal\Design;
  7. use \Ip\Form as Form;
  8. class Model
  9. {
  10. const INSTALL_DIR = 'setup/';
  11. const PARAMETERS_FILE = 'parameters.php';
  12. protected function __construct()
  13. {
  14. }
  15. /**
  16. * @return Model
  17. */
  18. public static function instance()
  19. {
  20. return new Model();
  21. }
  22. protected function getThemePluginDir()
  23. {
  24. return ipThemeFile('Plugin/');
  25. }
  26. public function getThemePlugins()
  27. {
  28. if (!is_dir($this->getThemePluginDir())) {
  29. return array();
  30. }
  31. $pluginConfigs = array();
  32. $plugins = scandir($this->getThemePluginDir());
  33. foreach ($plugins as $plugin) {
  34. $pluginDir = ipThemeFile('Plugin/' . $plugin);
  35. if (is_dir(
  36. $pluginDir
  37. ) && $plugin[0] != '.' && $plugin[0] != '..'
  38. ) { //don't add slash before is_dir check as it throws open basedir error
  39. $pluginDir .= '/';
  40. $pluginConfiguration = \Ip\Internal\Plugins\Service::parsePluginConfigFile($pluginDir);
  41. if ($pluginConfiguration) {
  42. $pluginConfigs[] = $pluginConfiguration;
  43. }
  44. }
  45. }
  46. return $pluginConfigs;
  47. }
  48. public function installThemePlugin($pluginName)
  49. {
  50. $toDir = ipFile('Plugin/' . $pluginName . '/');
  51. $fromDir = ipThemeFile('Plugin/' . $pluginName . '/');
  52. if (is_dir($toDir)) {
  53. throw new \Ip\Exception('This plugin has been already installed');
  54. }
  55. if (!is_dir($fromDir)) {
  56. throw new \Ip\Exception('Plugin is missing.');
  57. }
  58. $pluginConfiguration = \Ip\Internal\Plugins\Service::parsePluginConfigFile($fromDir);
  59. if (!$pluginConfiguration) {
  60. throw new \Ip\Exception('Can\'t read plugin configuration file.');
  61. }
  62. if (!is_writable(ipFile('Plugin/'))) {
  63. throw new \Ip\Exception('Please make plugin dir writable (' . esc($this->getThemePluginDir()) . ')');
  64. }
  65. $helper = Helper::instance();
  66. $helper->cpDir($fromDir, $toDir);
  67. \Ip\Internal\Plugins\Service::activatePlugin($pluginName);
  68. }
  69. /**
  70. * @return Theme[]
  71. */
  72. public function getAvailableThemes()
  73. {
  74. $themes = $this->getFolderThemes(ipFile('Theme/'));
  75. $themes = ipFilter('ipThemes', $themes);
  76. return $themes;
  77. }
  78. public function getThemeInstallDir()
  79. {
  80. return ipFile('Theme/');
  81. }
  82. /**
  83. * @param string $folder absolute path
  84. * @return array
  85. */
  86. protected function getFolderThemes($folder)
  87. {
  88. if (!is_dir($folder)) {
  89. return array();
  90. }
  91. $answer = array();
  92. if ($handle = opendir($folder)) {
  93. while (false !== ($file = readdir($handle))) {
  94. if (is_dir($folder . $file) && $file != '..' && $file != '.' && substr(
  95. $file,
  96. 0,
  97. 1
  98. ) != '.'
  99. ) {
  100. $answer[$file] = $this->getTheme($file, $folder);
  101. }
  102. }
  103. closedir($handle);
  104. }
  105. return $answer;
  106. }
  107. public function isThemeAvailable($name)
  108. {
  109. return is_dir(ipFile('Theme/' . $name . '/'));
  110. }
  111. public function installTheme($themeName)
  112. {
  113. $themes = $this->getAvailableThemes();
  114. if (!isset($themes[$themeName])) {
  115. throw new \Ip\Exception("Theme '" . esc($themeName) . "' does not exist.");
  116. }
  117. $theme = $themes[$themeName];
  118. ipEvent('ipBeforeThemeInstalled', array('themeName' => $themeName));
  119. \Ip\ServiceLocator::storage()->set('Ip', 'theme', $themeName);
  120. $service = Service::instance();
  121. $service->saveWidgetOptions($theme);
  122. //write down default theme options
  123. $options = $theme->getOptionsAsArray();
  124. foreach ($options as $option) {
  125. if (empty($option['name']) || empty($option['default'])) {
  126. continue;
  127. }
  128. $configModel = ConfigModel::instance();
  129. $newValue = $configModel->getConfigValue($themeName, $option['name'], $option['default']);
  130. $configModel->setConfigValue($themeName, $option['name'], $newValue);
  131. }
  132. ipEvent('ipThemeInstalled', array('themeName' => $themeName));
  133. }
  134. public function getMarketUrl()
  135. {
  136. if (ipGetOption('Ip.disableThemeMarket', 0)) {
  137. return '';
  138. }
  139. return ipConfig()->get('themeMarketUrl', 'http://market.impresspages.org/themes-v1/?version=4&cms=1');
  140. }
  141. /**
  142. * Read theme config and create theme entity
  143. * @param $name
  144. * @param null $dir
  145. * @param null $url
  146. * @return Theme
  147. * @throws \Exception
  148. */
  149. public function getTheme($name, $dir = null, $url = null)
  150. {
  151. if ($dir == null) {
  152. $dir = ipFile('Theme/');
  153. }
  154. $metadata = new ThemeMetadata();
  155. $metadata->setName($name);
  156. //new type config
  157. $themeJsonFile = $dir . $name . '/' . self::INSTALL_DIR . 'Theme.json';
  158. if (file_exists($themeJsonFile)) {
  159. $config = $this->parseThemeJson($themeJsonFile);
  160. } else {
  161. $themeJsonFile = $dir . $name . '/' . self::INSTALL_DIR . 'theme.json';
  162. if (file_exists($themeJsonFile)) {
  163. $config = $this->parseThemeJson($themeJsonFile);
  164. } else {
  165. $config = array();
  166. }
  167. }
  168. $config = ipFilter('ipThemeConfig', $config);
  169. $metadata->setTitle(!empty($config['title']) ? $config['title'] : $name);
  170. if (!empty($config['author'])) {
  171. $metadata->setAuthorTitle($config['author']);
  172. }
  173. if (!empty($config['version'])) {
  174. $metadata->setVersion($config['version']);
  175. }
  176. if (!empty($config['thumbnail'])) {
  177. $metadata->setThumbnail($config['thumbnail']);
  178. }
  179. if (!empty($url)) {
  180. $metadata->setUrl($url);
  181. }
  182. if (!empty($config['doctype']) && defined('\Ip\View::' . $config['doctype'])) {
  183. $metadata->setDoctype('DOCTYPE_' . $config['doctype']);
  184. } else {
  185. $metadata->setDoctype('DOCTYPE_HTML5');
  186. }
  187. if (!empty($config['options'])) {
  188. $metadata->setOptions($config['options']);
  189. }
  190. if (!empty($config['widget'])) {
  191. $metadata->setWidgetOptions($config['widget']);
  192. }
  193. $theme = new Theme($metadata);
  194. return $theme;
  195. }
  196. protected function parseThemeJson($file)
  197. {
  198. if (!file_exists($file) || !is_file($file)) {
  199. return array();
  200. }
  201. $configJson = file_get_contents($file);
  202. $config = Helper::instance()->json_clean_decode($configJson, true);
  203. if ($config) {
  204. return $config;
  205. } else {
  206. return array();
  207. }
  208. }
  209. /**
  210. * Parse old style theme.ini file for theme configuration values
  211. */
  212. protected function parseThemeIni($file)
  213. {
  214. $answer = array();
  215. if (file_exists($file)) {
  216. $config = file($file);
  217. foreach ($config as $configRow) {
  218. $configName = substr($configRow, 0, strpos($configRow, ':'));
  219. $value = substr($configRow, strpos($configRow, ':') + 1);
  220. $value = str_replace("\n", "", str_replace("\r", "", $value));
  221. $answer[$configName] = $value;
  222. }
  223. } else {
  224. return array();
  225. }
  226. return $answer;
  227. }
  228. /**
  229. * Returns possible layout pages.
  230. * files starting with underscore (for example, _layout.php) are considered hidden.
  231. * @return array layouts (e.g. ['main.php', 'home.php'])
  232. * @throws \Ip\Exception
  233. */
  234. public static function getThemeLayouts()
  235. {
  236. $themeDir = ipThemeFile('');
  237. $files = scandir($themeDir);
  238. $layouts = array();
  239. foreach ($files as $filename) {
  240. if ('php' == strtolower(pathinfo($filename, PATHINFO_EXTENSION))) {
  241. if ($filename[0] != '_') {
  242. $layouts[] = $filename;
  243. }
  244. }
  245. }
  246. return $layouts;
  247. }
  248. }