PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/setup.php

https://github.com/bernard357/yacs
PHP | 353 lines | 167 code | 73 blank | 113 comment | 26 complexity | 6e0ee70295d7fed66b0b8889fbb02994 MD5 | raw file
  1. <?php
  2. /**
  3. * the main setup script
  4. *
  5. * This page is used for the very first installation of the server
  6. *
  7. * This script looks for following items:
  8. * - [code]parameters/control.include.php[/code]
  9. * - [code]parameters/hooks.include.php[/code]
  10. * - [code]parameters/skins.include.php[/code]
  11. *
  12. * If all of these items are absent, the script assumes this is a first installation,
  13. * welcomes the surfer, and offers to jump to [script]control/configure.php[/script].
  14. *
  15. * Also, the script performs several test to ensure:
  16. * - that the version of PHP is greater or equal than 4.3
  17. * - that the MySQL PHP extension is available
  18. * - that the XML parser of PHP is available
  19. * - that it can write to local files (configuration and log files)
  20. *
  21. * If one of these tests fails, the script advises the user on the right thing to do.
  22. * For example, it will offer to chmod the YACS installation directory is necessary.
  23. *
  24. * On first installation this script will behave like a setup assistant,
  25. * and the user will have to pass through successive screens:
  26. * - the configuration panel ([script]control/configure.php[/script]), to record database and other essential parameters
  27. * - the extension scanner ([script]control/scan.php[/script]), to load all hooks
  28. * - the database setup ([script]control/setup.php[/script]), to create tables in the database
  29. * - the populate screen ([script]control/populate.php[/script]), to create a basic set of records in the database
  30. * - the configuration panel for skins ([script]scripts/configure.php[/script]), to set rendering parameters
  31. *
  32. * @see control/configure.php
  33. * @see control/scan.php
  34. * @see control/setup.php
  35. * @see control/populate.php
  36. * @see scripts/configure.php
  37. *
  38. * If at least one file is missing, the script assumes there is an on-going installation,
  39. * and proposes to jump to the control panel at [script]control/index.php[/script].
  40. * In this case the control panel will redirect to the adequate script depending of the missing element.
  41. *
  42. * If all files are present, but there is no [code]parameters/switch.on[/code] nor [code]parameters/switch.off[/code] file, the script
  43. * assumes the installation ends correctly, creates [code]parameters/switch.on[/code], and offers to jump to the
  44. * control panel at [script]control/index.php[/script].
  45. * Also, if there is no index page at the upper directory level, the script will silently attempt
  46. * to duplicate index.php there.
  47. *
  48. * Else the script assumes there is no need for an installation,
  49. * and offers to jump to the control panel at [script]control/index.php[/script].
  50. *
  51. * @see control/index.php
  52. *
  53. * @author Bernard Paques
  54. * @reference
  55. * @license http://www.gnu.org/copyleft/lesser.txt GNU Lesser General Public License
  56. */
  57. // include explicitly some libraries
  58. if(!is_readable('shared/global.php'))
  59. exit('No shared library. Please copy the entire set of files in the provided archive.');
  60. include_once 'shared/global.php';
  61. // load localized strings
  62. i18n::bind('root');
  63. // load the skin
  64. load_skin('setup');
  65. // check key files
  66. $missing = 0;
  67. if(!file_exists('parameters/control.include.php'))
  68. $missing++;
  69. if(!file_exists('parameters/hooks.include.php'))
  70. $missing++;
  71. if(!file_exists('parameters/skins.include.php'))
  72. $missing++;
  73. // title
  74. $context['page_title'] = i18n::s('Setup assistant');
  75. // stop crawlers
  76. if(Surfer::is_crawler()) {
  77. Safe::header('Status: 401 Unauthorized', TRUE, 401);
  78. Logger::error(i18n::s('You are not allowed to perform this operation.'));
  79. // first installation
  80. } elseif($missing == 3) {
  81. // to report on checks
  82. $checks = array();
  83. // ensure we have a minimum version of PHP
  84. if(version_compare(phpversion(),'5.3','<')) {
  85. // provide instructions
  86. Logger::error(sprintf(i18n::s('ERROR: YACS requires at least PHP version 5.3. The server runs version %s.'), phpversion()));
  87. $context['text'] .= '<p class="details"><a href="setup.php">'.i18n::s('Check PHP version again')."</a></p>\n";
  88. // check
  89. $check = i18n::s('ERROR');
  90. } else
  91. $check = i18n::s('OK');
  92. // check
  93. $checks[] = array(i18n::s('PHP'), phpversion(), $check);
  94. // ensure we have MySQL
  95. if(!SQL::check()) {
  96. // provide instructions
  97. Logger::error(i18n::s('ERROR: YACS requires the MySQL PHP extension.'));
  98. $context['text'] .= '<p class="details"><a href="setup.php">'.i18n::s('Check the MySQL PHP extension again')."</a></p>\n";
  99. // check
  100. $value = i18n::s('Absent');
  101. $check = i18n::s('ERROR');
  102. } else {
  103. $value = i18n::s('Present');
  104. $check = i18n::s('OK');
  105. }
  106. // check
  107. $checks[] = array(i18n::s('MySQL'), $value, $check);
  108. // ensure we can handle XML
  109. if(!is_callable('xml_parser_create')) {
  110. // provide instructions
  111. Logger::error(i18n::s('ERROR: YACS requires the XML PHP extension.'));
  112. $context['text'] .= '<p class="details"><a href="setup.php">'.i18n::s('Check the XML PHP extension again')."</a></p>\n";
  113. // check
  114. $value = i18n::s('Absent');
  115. $check = i18n::s('ERROR');
  116. } else {
  117. $value = i18n::s('Present');
  118. $check = i18n::s('OK');
  119. }
  120. // check
  121. $checks[] = array(i18n::s('XML'), $value, $check);
  122. // ensure we can handle ZIP files
  123. if(!is_callable('zip_open')) {
  124. $context['text'] .= '<p>'.i18n::s('WARNING: You will not be able to upload zip files.')."</p>\n";
  125. $context['text'] .= '<p class="details"><a href="setup.php">'.i18n::s('Check the ZIP PHP extension again')."</a></p>\n";
  126. // check
  127. $value = i18n::s('Absent');
  128. $check = i18n::s('WARNING');
  129. } else {
  130. $value = i18n::s('Present');
  131. $check = i18n::s('OK');
  132. }
  133. // check
  134. $checks[] = array(i18n::s('zip'), $value, $check);
  135. // show evidence of safe mode
  136. if(Safe::ini_get('safe_mode')) {
  137. $context['text'] .= '<p>'.i18n::s('WARNING: This server runs in safe mode, and YACS may be prevented to perform a number of key operations.')."</p>\n";
  138. // check
  139. $value = i18n::s('Yes');
  140. $check = i18n::s('WARNING');
  141. } else {
  142. $value = i18n::s('No');
  143. $check = i18n::s('OK');
  144. }
  145. // check
  146. $checks[] = array(i18n::s('Safe mode'), $value, $check);
  147. // test our ability to write to files
  148. $can_write = TRUE;
  149. // actual attempt to write to representative files
  150. $files = array();
  151. $files[] = './parameters/agents.include.php';
  152. $files[] = './parameters/control.include.php';
  153. $files[] = './parameters/feeds.include.php';
  154. $files[] = './parameters/files.include.php';
  155. $files[] = './parameters/hooks.include.php';
  156. $files[] = './parameters/hooks.xml';
  157. $files[] = './parameters/letters.include.php';
  158. $files[] = './parameters/scripts.include.php';
  159. $files[] = './parameters/servers.include.php';
  160. $files[] = './parameters/services.include.php';
  161. $files[] = './parameters/skins.include.php';
  162. $files[] = './parameters/switch.on';
  163. $files[] = './parameters/users.include.php';
  164. $files[] = './temporary/debug.txt';
  165. $files[] = './temporary/log.txt';
  166. foreach($files as $file) {
  167. // test one file at a time
  168. if(!Safe::is_writable($file)) {
  169. $context['text'] .= sprintf(i18n::s('Impossible to write to %s.'), $file).BR;
  170. $can_write = FALSE;
  171. }
  172. }
  173. // please chmod or chown files
  174. if(!$can_write) {
  175. // provide instructions
  176. $context['text'] .= '<p>'.i18n::s('WARNING: YACS cannot write to files. If you are running some Unix, please ensure that permissions have been properly set. This issue can also be due to server running in safe mode.')."</p>\n";
  177. $context['text'] .= '<p>'.sprintf(i18n::s('Check the provided %s file to find more help on file permissions.'), '<a href="'.i18n::s('readme.txt').'">'.i18n::s('readme.txt').'</a>')."</p>\n";
  178. $context['text'] .= '<p class="details"><a href="setup.php">'.i18n::s('Check again our ability to write to files')."</a></p>\n";
  179. // check
  180. $value = i18n::s('Configuration files cannot be changed');
  181. $check = i18n::s('WARNING');
  182. } else {
  183. $value = i18n::s('May change configuration files');
  184. $check = i18n::s('OK');
  185. }
  186. // check
  187. $checks[] = array(i18n::s('Permissions'), $value, $check);
  188. // report on prerequisite checks
  189. $context['text'] .= '<h2>'.i18n::s('Pre-installation checks').'</h2>';
  190. // check results
  191. $context['text'] .= '<table border="1">';
  192. $row_count = 1;
  193. foreach($checks as $cells)
  194. $context['text'] .= Skin::table_row($cells, $row_count++);
  195. $context['text'] .= '</table>';
  196. // link to the readme file
  197. $context['text'] .= '<p>'.sprintf(i18n::s('Check the provided %s file to ensure prerequisites are fulfilled.'), '<a href="'.i18n::s('readme.txt').'">'.i18n::s('readme.txt').'</a>')."</p>\n";
  198. // link to the configuration page
  199. if(!count($context['error'])) {
  200. // report on checks
  201. $context['text'] .= '<h2>'.i18n::s('Ready to start the installation').'</h2>';
  202. // splash screen
  203. $context['text'] .= i18n::s("<p>At the moment no configuration file has been found. You will now have to pass through several steps in order to achieve the setup of your server:</p>\n<ul>\n<li>Configure parameters related to the database.</li>\n<li>Load extension hooks.</li>\n<li>Create tables in the database.</li>\n<li>Add one user profile and populate the database.</li>\n<li>Configure the theme of your server.</li>\n</ul>\nIn normal conditions this will take only some minutes. If you have any problems, please consult <a href=\"http://www.yacs.fr/\">www.yacs.fr</a> for additional support.<p>Thank you for having selected the YACS solution.</p>")."\n";
  204. // add a button to start the installation process
  205. $context['text'] .= '<form method="get" action="control/configure.php" id="main_form">'."\n"
  206. .'<p class="assistant_bar">'.Skin::build_submit_button(i18n::s('Start the installation process'), NULL, NULL, 'confirmed').'</p>'."\n"
  207. .'</form>'."\n";
  208. // a place holder for cookies activation
  209. $context['text'] .= '<p id="ask_for_cookies" style="display: none; color: red; text-decoration: blink;"></p>';
  210. // the script used to check that cookies are activated
  211. $context['text'] .= JS_PREFIX
  212. .'document.cookie = \'CookiesEnabled=1\';'."\n"
  213. .'if((document.cookie == "") && document.getElementById) {'."\n"
  214. .' $("#ask_for_cookies").update("'.i18n::s('You must enable cookies to manage this server. Change settings of your browser accordingly, then revisit this page afterwards.').'");'."\n"
  215. .' $("#ask_for_cookies").style.display = "block";'."\n"
  216. .' $("#confirmed").disabled = true;'."\n"
  217. .'}'."\n"
  218. .JS_SUFFIX."\n";
  219. // purge the scripts/run_once directory on first installation
  220. include_once $context['path_to_root'].'scripts/scripts.php';
  221. Scripts::purge_run_once();
  222. }
  223. // on-going installation
  224. } elseif($missing) {
  225. // splash screen
  226. $context['text'] .= '<p>'.i18n::s('Some configuration files are missing. Please follow the link to complete the installation process.')."</p>\n";
  227. // to the control panel
  228. $context['text'] .= '<p><a href="control/">'.i18n::s('Control Panel')."</a></p>\n";
  229. // end of the installation
  230. } elseif(!file_exists('parameters/switch.on') && !file_exists('parameters/switch.off')) {
  231. // create the switch
  232. $content = '---------------------------------------------'."\n"
  233. .'YACS will process requests if this file is named switch.on,'."\n"
  234. .'and will redirect everything to control/closed.php if its name is changed to switch.off.'."\n"
  235. ."\n"
  236. .'Associates can use the script control/switch.php to stop and restart remotely.'."\n"
  237. .'---------------------------------------------'."\n";
  238. if(!Safe::file_put_contents('parameters/switch.on', $content)) {
  239. // not enough rights to write the file
  240. Logger::error(i18n::s('ERROR: YACS cannot create the file parameters/switch.on to activate the server.'));
  241. // allow for a manual update
  242. $context['text'] .= '<p style="text-decoration: blink;">'.sprintf(i18n::s('To actually switch on the server, please copy and paste following lines by yourself in file %s.'), 'parameters/switch.on')."</p>\n";
  243. // content of the switch file
  244. $context['text'] .= '<pre>'.$content."</pre>\n";
  245. }
  246. // if there is no index at the upper level
  247. if(!file_exists($context['path_to_root'].'../index.php') && ($content = Safe::file_get_contents($context['path_to_root'].'index.php'))) {
  248. // silently attempt to duplicate our index
  249. Safe::file_put_contents('../index.php', $content);
  250. // remember this for the next incremental update
  251. $content = '<?php'."\n"
  252. .'// This file has been created by the setup script setup.php'."\n"
  253. .'// on '.gmdate("F j, Y, g:i a").' GMT, for '.Surfer::get_name().'. Please do not modify it manually.'."\n"
  254. .'$context[\'home_at_root\']=\'Y\';'."\n"
  255. .'$context[\'reference_server\']=\''.addcslashes(i18n::s('www.yacs.fr'), "\\'")."';\n"
  256. .'?>'."\n";
  257. Safe::file_put_contents('parameters/scripts.include.php', $content);
  258. }
  259. // the splash message
  260. $context['text'] .= sprintf(i18n::s("<p>You have passed through the several installation steps.</p>\nWhat do you want to do now?<ul>\n<li>Select %s for your site.</li>\n<li>Populate your site with the %s.</li>\n<li>Manage everything from the %s.</li>\n<li>Check the %s of this site.</li>\n<li>Review %s.</li>\n<li>%s.</li>\n<li>Look at the %s.</li>\n<li>Visit %s to learn more.</li>\n</ul>\n<p>Thank you for having selected to use YACS for your web site.</p>\n"),
  261. Skin::build_link('skins/', i18n::s('another skin')),
  262. Skin::build_link('help/populate.php', i18n::s('Content Assistant')),
  263. Skin::build_link('control/', i18n::s('Control Panel')),
  264. Skin::build_link($context['url_to_root'], i18n::s('front page')),
  265. Skin::build_link('users/view.php', i18n::s('your profile')),
  266. Skin::build_link('articles/edit.php', i18n::s('Add a page')),
  267. Skin::build_link('help/', i18n::s('Help index')),
  268. Skin::build_link(i18n::s('http://www.yacs.fr/'), i18n::s('www.yacs.fr'), 'external'))."\n";
  269. // no need for installation
  270. } else {
  271. // the splash message
  272. $context['text'] .= i18n::s('<p>Since basic configuration files exist on your server, it is likely that the installation has been achieved successfully. Click on the link below to modify the running parameters of your server.</p>')."\n";
  273. // to the control panel
  274. $context['text'] .= '<p><a href="control/">'.i18n::s('Control Panel')."</a></p>\n";
  275. }
  276. // render the skin
  277. render_skin();
  278. ?>