PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/install/engine/step_7.php

http://github.com/forkcms/forkcms
PHP | 469 lines | 262 code | 69 blank | 138 comment | 23 complexity | 9ec709ef277eee3b0e5f1e7b96e2369d MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, MIT, AGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /*
  3. * This file is part of Fork CMS.
  4. *
  5. * For the full copyright and license information, please view the license
  6. * file that was distributed with this source code.
  7. */
  8. /**
  9. * Step 7 of the Fork installer
  10. *
  11. * @author Davy Hellemans <davy@netlash.com>
  12. * @author Tijs Verkoyen <tijs@sumocoders.be>
  13. * @author Matthias Mullie <matthias@mullie.eu>
  14. * @author Dieter Vanden Eynde <dieter@netlash.com>
  15. * @author Annelies Van Extergem <annelies.vanextergem@netlash.com>
  16. */
  17. class InstallerStep7 extends InstallerStep
  18. {
  19. /**
  20. * Database connection, needed for installation
  21. *
  22. * @var SpoonDatabases
  23. */
  24. private $db;
  25. /**
  26. * Build the language files
  27. *
  28. * @param SpoonDatabase $db The database connection instance.
  29. * @param string $language The language to build the locale-file for.
  30. * @param string $application The application to build the locale-file for.
  31. */
  32. public function buildCache(SpoonDatabase $db, $language, $application)
  33. {
  34. // get types
  35. $types = $db->getEnumValues('locale', 'type');
  36. // get locale for backend
  37. $locale = (array) $db->getRecords('SELECT type, module, name, value
  38. FROM locale
  39. WHERE language = ? AND application = ?
  40. ORDER BY type ASC, name ASC, module ASC',
  41. array((string) $language, (string) $application));
  42. // start generating PHP
  43. $value = '<?php' . "\n";
  44. $value .= '/**' . "\n";
  45. $value .= ' *' . "\n";
  46. $value .= ' * This file is generated by the Installer, it contains' . "\n";
  47. $value .= ' * more information about the locale. Do NOT edit.' . "\n";
  48. $value .= ' * ' . "\n";
  49. $value .= ' * @author Installer' . "\n";
  50. $value .= ' * @generated ' . date('Y-m-d H:i:s') . "\n";
  51. $value .= ' */' . "\n";
  52. $value .= "\n";
  53. // loop types
  54. foreach($types as $type)
  55. {
  56. // default module
  57. $modules = array('core');
  58. // continue output
  59. $value .= "\n";
  60. $value .= '// init var' . "\n";
  61. $value .= '$' . $type . ' = array();' . "\n";
  62. $value .= '$' . $type . '[\'core\'] = array();' . "\n";
  63. // loop locale
  64. foreach($locale as $i => $item)
  65. {
  66. // types match
  67. if($item['type'] == $type)
  68. {
  69. // new module
  70. if(!in_array($item['module'], $modules))
  71. {
  72. $value .= '$' . $type . '[\'' . $item['module'] . '\'] = array();' . "\n";
  73. $modules[] = $item['module'];
  74. }
  75. // parse
  76. if($application == 'backend') $value .= '$' . $type . '[\'' . $item['module'] . '\'][\'' . $item['name'] . '\'] = \'' . str_replace('\"', '"', addslashes($item['value'])) . '\';' . "\n";
  77. else $value .= '$' . $type . '[\'' . $item['name'] . '\'] = \'' . str_replace('\"', '"', addslashes($item['value'])) . '\';' . "\n";
  78. // unset
  79. unset($locale[$i]);
  80. }
  81. }
  82. }
  83. $value .= "\n";
  84. $value .= '?>';
  85. // store
  86. SpoonFile::setContent(PATH_WWW . '/' . $application . '/cache/locale/' . $language . '.php', $value);
  87. }
  88. /**
  89. * Creates the configuration files
  90. */
  91. private function createConfigurationFiles()
  92. {
  93. // build variables
  94. $variables = array();
  95. $variables['\'<debug-mode>\''] = SpoonSession::get('debug_mode') ? 'true' : 'false';
  96. $variables['<spoon-debug-email>'] = SpoonSession::get('email');
  97. $variables['<database-name>'] = SpoonSession::get('db_database');
  98. $variables['<database-hostname>'] = addslashes(SpoonSession::get('db_hostname'));
  99. $variables['<database-username>'] = addslashes(SpoonSession::get('db_username'));
  100. $variables['<database-password>'] = addslashes(SpoonSession::get('db_password'));
  101. $variables['<database-port>'] = (SpoonSession::exists('db_port') && SpoonSession::get('db_port') != '') ? addslashes(SpoonSession::get('db_port')) : 3306;
  102. $variables['<site-domain>'] = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'fork.local';
  103. $variables['<site-default-title>'] = 'Fork CMS';
  104. $variables['\'<site-multilanguage>\''] = SpoonSession::get('multiple_languages') ? 'true' : 'false';
  105. $variables['<path-www>'] = PATH_WWW;
  106. $variables['<path-library>'] = PATH_LIBRARY;
  107. $variables['<site-default-language>'] = SpoonSession::get('default_language');
  108. $variables['<action-group-tag>'] = '@actiongroup';
  109. $variables['<action-rights-level>'] = 7;
  110. // globals files
  111. $configurationFiles = array(
  112. 'globals.base.php' => 'globals.php',
  113. 'globals_frontend.base.php' => 'globals_frontend.php',
  114. 'globals_backend.base.php' => 'globals_backend.php'
  115. );
  116. // loop files
  117. foreach($configurationFiles as $sourceFilename => $destinationFilename)
  118. {
  119. // grab content
  120. $globalsContent = SpoonFile::getContent(PATH_LIBRARY . '/' . $sourceFilename);
  121. // assign the variables
  122. $globalsContent = str_replace(array_keys($variables), array_values($variables), $globalsContent);
  123. // write the file
  124. SpoonFile::setContent(PATH_LIBRARY . '/' . $destinationFilename, $globalsContent);
  125. }
  126. // general configuration file
  127. $globalsContent = SpoonFile::getContent(PATH_LIBRARY . '/config.base.php');
  128. // assign the variables
  129. $globalsContent = str_replace(array_keys($variables), array_values($variables), $globalsContent);
  130. // write the file
  131. SpoonFile::setContent(PATH_WWW . '/backend/cache/config/config.php', $globalsContent);
  132. SpoonFile::setContent(PATH_WWW . '/frontend/cache/config/config.php', $globalsContent);
  133. }
  134. /**
  135. * Create locale cache files
  136. */
  137. private function createLocaleFiles()
  138. {
  139. // all available languages
  140. $languages = array_unique(array_merge(SpoonSession::get('languages'), SpoonSession::get('interface_languages')));
  141. // loop all the languages
  142. foreach($languages as $language)
  143. {
  144. // get applications
  145. $applications = $this->db->getColumn(
  146. 'SELECT DISTINCT application
  147. FROM locale
  148. WHERE language = ?',
  149. array((string) $language)
  150. );
  151. // loop applications
  152. foreach((array) $applications as $application)
  153. {
  154. // build application locale cache
  155. $this->buildCache($this->db, $language, $application);
  156. }
  157. }
  158. }
  159. /**
  160. * Define paths also used in frontend/backend, to be used in installer.
  161. */
  162. private function definePaths()
  163. {
  164. // general paths
  165. define('BACKEND_PATH', PATH_WWW . '/backend');
  166. define('BACKEND_CACHE_PATH', BACKEND_PATH . '/cache');
  167. define('BACKEND_CORE_PATH', BACKEND_PATH . '/core');
  168. define('BACKEND_MODULES_PATH', BACKEND_PATH . '/modules');
  169. define('FRONTEND_PATH', PATH_WWW . '/frontend');
  170. define('FRONTEND_CACHE_PATH', FRONTEND_PATH . '/cache');
  171. define('FRONTEND_CORE_PATH', FRONTEND_PATH . '/core');
  172. define('FRONTEND_MODULES_PATH', FRONTEND_PATH . '/modules');
  173. define('FRONTEND_FILES_PATH', FRONTEND_PATH . '/files');
  174. }
  175. /**
  176. * Delete the cached data
  177. */
  178. private function deleteCachedData()
  179. {
  180. // init some vars
  181. $foldersToLoop = array('/backend/cache', '/frontend/cache');
  182. $foldersToIgnore = array('/backend/cache/navigation');
  183. $filesToIgnore = array('.gitignore');
  184. $filesToDelete = array();
  185. // loop folders
  186. foreach($foldersToLoop as $folder)
  187. {
  188. // get folderlisting
  189. $subfolders = (array) SpoonDirectory::getList(PATH_WWW . $folder, false, array('.svn', '.gitignore'));
  190. // loop folders
  191. foreach($subfolders as $subfolder)
  192. {
  193. // not in ignore list?
  194. if(!in_array($folder . '/' . $subfolder, $foldersToIgnore))
  195. {
  196. // get the filelisting
  197. $files = (array) SpoonFile::getList(PATH_WWW . $folder . '/' . $subfolder);
  198. // loop the files
  199. foreach($files as $file)
  200. {
  201. if(!in_array($file, $filesToIgnore))
  202. {
  203. $filesToDelete[] = PATH_WWW . $folder . '/' . $subfolder . '/' . $file;
  204. }
  205. }
  206. }
  207. }
  208. }
  209. // delete cached files
  210. if(!empty($filesToDelete))
  211. {
  212. // loop files and delete them
  213. foreach($filesToDelete as $file) SpoonFile::delete($file);
  214. }
  215. }
  216. /**
  217. * Executes this step.
  218. */
  219. public function execute()
  220. {
  221. // extend execution limit
  222. set_time_limit(0);
  223. // validate all previous steps
  224. if(!$this->validateForm()) SpoonHTTP::redirect('index.php?step=1');
  225. // delete cached data
  226. $this->deleteCachedData();
  227. // create configuration files
  228. $this->createConfigurationFiles();
  229. // init database
  230. $this->initDatabase();
  231. // define paths
  232. $this->definePaths();
  233. // install modules
  234. $this->installModules();
  235. // create locale cache
  236. $this->createLocaleFiles();
  237. // already installed
  238. SpoonFile::setContent(dirname(__FILE__) . '/../cache/installed.txt', date('Y-m-d H:i:s'));
  239. // show success message
  240. $this->showSuccess();
  241. // clear session
  242. SpoonSession::destroy();
  243. // show output
  244. $this->tpl->display('layout/templates/step_7.tpl');
  245. }
  246. /**
  247. * Init database.
  248. */
  249. public function initDatabase()
  250. {
  251. // get port
  252. $port = (SpoonSession::exists('db_port') && SpoonSession::get('db_port') != '') ? SpoonSession::get('db_port') : 3306;
  253. // database instance
  254. $this->db = new SpoonDatabase('mysql', SpoonSession::get('db_hostname'), SpoonSession::get('db_username'), SpoonSession::get('db_password'), SpoonSession::get('db_database'), $port);
  255. // utf8 compliance & MySQL-timezone
  256. $this->db->execute('SET CHARACTER SET utf8, NAMES utf8, time_zone = "+0:00"');
  257. // store
  258. Spoon::set('database', $this->db);
  259. }
  260. /**
  261. * Installs the required and optional modules
  262. */
  263. private function installModules()
  264. {
  265. // The default extras to add to every page after installation of all modules and to add to the default templates.
  266. $defaultExtras = array();
  267. // init var
  268. $warnings = array();
  269. /**
  270. * First we need to install the core. All the linked modules, settings and sql tables are
  271. * being installed.
  272. */
  273. require_once PATH_WWW . '/backend/core/installer/installer.php';
  274. // create the core installer
  275. $installer = new CoreInstaller(
  276. $this->db,
  277. SpoonSession::get('languages'),
  278. SpoonSession::get('interface_languages'),
  279. SpoonSession::get('example_data'),
  280. array(
  281. 'default_language' => SpoonSession::get('default_language'),
  282. 'default_interface_language' => SpoonSession::get('default_interface_language'),
  283. 'spoon_debug_email' => SpoonSession::get('email'),
  284. 'api_email' => SpoonSession::get('email'),
  285. 'site_domain' => (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'fork.local',
  286. 'site_title' => 'Fork CMS',
  287. 'smtp_server' => '',
  288. 'smtp_port' => '',
  289. 'smtp_username' => '',
  290. 'smtp_password' => ''
  291. )
  292. );
  293. // install the core
  294. $installer->install();
  295. // add the warnings
  296. $moduleWarnings = $installer->getWarnings();
  297. if(!empty($moduleWarnings)) $warnings[] = array('module' => 'core', 'warnings' => $moduleWarnings);
  298. // add the default extras
  299. $moduleDefaultExtras = $installer->getDefaultExtras();
  300. if(!empty($moduleDefaultExtras)) array_merge($defaultExtras, $moduleDefaultExtras);
  301. // variables passed to module installers
  302. $variables = array();
  303. $variables['email'] = SpoonSession::get('email');
  304. $variables['default_interface_language'] = SpoonSession::get('default_interface_language');
  305. // modules to install (required + selected)
  306. $modules = array_unique(array_merge($this->modules['required'], SpoonSession::get('modules')));
  307. // loop required modules
  308. foreach($modules as $module)
  309. {
  310. // install exists
  311. if(SpoonFile::exists(PATH_WWW . '/backend/modules/' . $module . '/installer/installer.php'))
  312. {
  313. // users module needs custom variables
  314. if($module == 'users')
  315. {
  316. $variables['password'] = SpoonSession::get('password');
  317. }
  318. // load installer file
  319. require_once PATH_WWW . '/backend/modules/' . $module . '/installer/installer.php';
  320. // build installer class name
  321. $class = SpoonFilter::toCamelCase($module) . 'Installer';
  322. // create installer
  323. $installer = new $class(
  324. $this->db,
  325. SpoonSession::get('languages'),
  326. SpoonSession::get('interface_languages'),
  327. SpoonSession::get('example_data'),
  328. $variables
  329. );
  330. // install the module
  331. $installer->install();
  332. // add the warnings
  333. $moduleWarnings = $installer->getWarnings();
  334. if(!empty($moduleWarnings)) $warnings[] = array('module' => $module, 'warnings' => $moduleWarnings);
  335. // add the default extras
  336. $moduleDefaultExtras = $installer->getDefaultExtras();
  337. if(!empty($moduleDefaultExtras)) $defaultExtras = array_merge($defaultExtras, $moduleDefaultExtras);
  338. }
  339. }
  340. // loop default extras
  341. foreach($defaultExtras as $extra)
  342. {
  343. // get pages without this extra
  344. $revisionIds = $this->db->getColumn(
  345. 'SELECT i.revision_id
  346. FROM pages AS i
  347. WHERE i.revision_id NOT IN (
  348. SELECT DISTINCT b.revision_id
  349. FROM pages_blocks AS b
  350. WHERE b.extra_id = ?
  351. GROUP BY b.revision_id
  352. )',
  353. array($extra['id'])
  354. );
  355. // build insert array for this extra
  356. $insertExtras = array();
  357. foreach($revisionIds as $revisionId)
  358. {
  359. $insertExtras[] = array(
  360. 'revision_id' => $revisionId,
  361. 'position' => $extra['position'],
  362. 'extra_id' => $extra['id'],
  363. 'created_on' => gmdate('Y-m-d H:i:s'),
  364. 'edited_on' => gmdate('Y-m-d H:i:s'),
  365. 'visible' => 'Y'
  366. );
  367. }
  368. // insert block
  369. $this->db->insert('pages_blocks', $insertExtras);
  370. }
  371. // parse the warnings
  372. $this->tpl->assign('warnings', $warnings);
  373. }
  374. /**
  375. * Is this step allowed.
  376. *
  377. * @return bool
  378. */
  379. public static function isAllowed()
  380. {
  381. return InstallerStep6::isAllowed() && isset($_SESSION['email']) && isset($_SESSION['password']);
  382. }
  383. /**
  384. * Show the success message
  385. */
  386. private function showSuccess()
  387. {
  388. // assign variables
  389. $this->tpl->assign('url', (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : 'fork.local');
  390. $this->tpl->assign('email', SpoonSession::get('email'));
  391. $this->tpl->assign('password', SpoonSession::get('password'));
  392. }
  393. /**
  394. * Validates the previous steps
  395. */
  396. private function validateForm()
  397. {
  398. return InstallerStep6::isAllowed();
  399. }
  400. }