PageRenderTime 43ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/web/concrete/controllers/install.php

https://github.com/ayamyau/concrete5
PHP | 352 lines | 303 code | 41 blank | 8 comment | 33 complexity | 58bac81b3c6a28a034105ab9b2c66ea6 MD5 | raw file
  1. <?
  2. defined('C5_EXECUTE') or die("Access Denied.");
  3. if (!defined('E_DEPRECATED')) {
  4. error_reporting(E_ALL ^ E_NOTICE);
  5. } else {
  6. error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);
  7. }
  8. ini_set('display_errors', 1);
  9. if (!ini_get('safe_mode')) {
  10. @set_time_limit(120);
  11. }
  12. date_default_timezone_set(@date_default_timezone_get());
  13. define('ENABLE_CACHE', false);
  14. define('UPLOAD_FILE_EXTENSIONS_ALLOWED', '*.jpg;');
  15. if (!defined('DIR_FILES_UPLOADED')) {
  16. define('DIR_FILES_UPLOADED', DIR_FILES_UPLOADED_STANDARD);
  17. }
  18. if (!defined('DIR_FILES_TRASH')) {
  19. define('DIR_FILES_TRASH', DIR_FILES_TRASH_STANDARD);
  20. }
  21. define('DIR_FILES_INCOMING', DIR_FILES_UPLOADED . '/incoming');
  22. define('DIR_FILES_UPLOADED_THUMBNAILS', DIR_FILES_UPLOADED . '/thumbnails');
  23. define('DIR_FILES_UPLOADED_THUMBNAILS_LEVEL2', DIR_FILES_UPLOADED . '/thumbnails/level2');
  24. define('DIR_FILES_UPLOADED_THUMBNAILS_LEVEL3', DIR_FILES_UPLOADED . '/thumbnails/level3');
  25. define('DIR_FILES_AVATARS', DIR_FILES_UPLOADED . '/avatars');
  26. class InstallController extends Controller {
  27. public $helpers = array('form', 'html');
  28. private $fp;
  29. // default values to be the currently defined vals
  30. private $installData = array(
  31. "DIR_BASE_CORE"=>DIR_BASE_CORE,
  32. "DIR_FILES_BIN_HTMLDIFF"=>DIR_FILES_BIN_HTMLDIFF,
  33. "DIR_BASE"=>DIR_BASE,
  34. "DIR_REL"=>DIR_REL,
  35. "BASE_URL"=>BASE_URL,
  36. "DIR_CONFIG_SITE" => DIR_CONFIG_SITE,
  37. "DIR_FILES_UPLOADED"=>DIR_FILES_UPLOADED,
  38. "DIR_FILES_UPLOADED_THUMBNAILS"=>DIR_FILES_UPLOADED_THUMBNAILS,
  39. "DIR_FILES_UPLOADED_THUMBNAILS_LEVEL2" => DIR_FILES_UPLOADED_THUMBNAILS_LEVEL2,
  40. "DIR_FILES_TRASH"=>DIR_FILES_TRASH,
  41. "DIR_FILES_INCOMING" => DIR_FILES_INCOMING,
  42. "DIR_FILES_CACHE"=>DIR_FILES_CACHE,
  43. "DIR_FILES_CACHE_DB"=>DIR_FILES_CACHE_DB,
  44. "DIR_FILES_AVATARS"=>DIR_FILES_AVATARS,
  45. "DIR_PACKAGES"=>DIR_PACKAGES,
  46. "USER_SUPER_ID"=>USER_SUPER_ID,
  47. "USER_SUPER"=>USER_SUPER,
  48. "GUEST_GROUP_ID"=>GUEST_GROUP_ID,
  49. "ADMIN_GROUP_ID"=>ADMIN_GROUP_ID,
  50. "APP_VERSION"=>APP_VERSION,
  51. "DEBUG_DISPLAY_ERRORS"=>DEBUG_DISPLAY_ERRORS,
  52. "uPassword"=>NULL
  53. );
  54. public function setInstallData($data) {
  55. // reset only the supplied vals
  56. foreach($data as $key=>$value) {
  57. $this->installData[$key] = $value;
  58. }
  59. }
  60. protected function installDB() {
  61. $installDirectory = $this->installData['DIR_BASE_CORE'] . '/config';
  62. if ($_POST['INSTALL_SAMPLE_CONTENT']) {
  63. $contentfile = $installDirectory . '/install/sample_content.sql';
  64. } else {
  65. $contentfile = $installDirectory . '/install/no_sample_content.sql';
  66. }
  67. if (!file_exists($contentfile)) {
  68. throw new Exception(t('Unable to locate database import file.'));
  69. }
  70. $sql = file_get_contents($installDirectory . '/install/schema.sql');
  71. $schema = explode("\n\n", $sql);
  72. $sql = file_get_contents($contentfile);
  73. $sql = str_replace('{[CCM:SITE]}', addslashes($_POST['SITE']), $sql);
  74. $statements = explode("\n\n", $sql);
  75. $statements = array_merge($schema, $statements);
  76. $db = Loader::db();
  77. $db->ensureEncoding();
  78. foreach ($statements as $statement) {
  79. if (trim($statement) != "") {
  80. $r = $db->execute($statement);
  81. if (!$r) {
  82. throw new Exception(t('Unable to install database: %s', $db->ErrorMsg()));
  83. }
  84. }
  85. }
  86. }
  87. public function test_url($num1, $num2) {
  88. $js = Loader::helper('json');
  89. $num = $num1 + $num2;
  90. print $js->encode(array('response' => $num));
  91. exit;
  92. }
  93. public function on_start() {
  94. $this->setRequiredItems();
  95. $this->setOptionalItems();
  96. }
  97. private function setRequiredItems() {
  98. $this->set('imageTest', function_exists('imagecreatetruecolor'));
  99. $this->set('mysqlTest', function_exists('mysql_connect'));
  100. $this->set('xmlTest', function_exists('xml_parse') && function_exists('simplexml_load_file'));
  101. $this->set('fileWriteTest', $this->testFileWritePermissions());
  102. }
  103. private function setOptionalItems() {
  104. // no longer need lucene
  105. //$this->set('searchTest', function_exists('iconv') && function_exists('mb_strtolower') && (@preg_match('/\pL/u', 'a') == 1));
  106. $this->set('remoteFileUploadTest', function_exists('iconv'));
  107. // no longer need built-in gettext
  108. //$this->set('langTest', Localization::isAvailable() && (!ini_get('safe_mode')));
  109. $diffExecTest = is_executable($this->installData['DIR_FILES_BIN_HTMLDIFF']);
  110. $diffSystem = (!ini_get('safe_mode'));
  111. if ($diffExecTest && $diffSystem) {
  112. $this->set('diffTest', true);
  113. } else {
  114. $this->set('diffTest', false);
  115. }
  116. if (version_compare(PHP_VERSION, '5.2.0', '>')) {
  117. $phpVtest = true;
  118. } else {
  119. $phpVtest = false;
  120. }
  121. $this->set('phpVtest',$phpVtest);
  122. }
  123. public function passedRequiredItems() {
  124. if ($this->get('imageTest') && $this->get('mysqlTest') && $this->get('fileWriteTest') && $this->get('xmlTest')) {
  125. return true;
  126. }
  127. }
  128. private function testFileWritePermissions() {
  129. $e = Loader::helper('validation/error');
  130. if (!is_writable($this->installData['DIR_CONFIG_SITE'])) {
  131. $e->add(t('Your configuration directory config/ does not appear to be writable by the web server.'));
  132. }
  133. if (!is_writable($this->installData['DIR_FILES_UPLOADED'])) {
  134. $e->add(t('Your files directory files/ does not appear to be writable by the web server.'));
  135. }
  136. if (!is_writable($this->installData['DIR_PACKAGES'])) {
  137. $e->add(t('Your packages directory packages/ does not appear to be writable by the web server.'));
  138. }
  139. $this->fileWriteErrors = $e;
  140. if ($this->fileWriteErrors->has()) {
  141. return false;
  142. } else {
  143. return true;
  144. }
  145. }
  146. public function getDBErrorMsg() {
  147. return t('Function mysql_connect() not found. Your system does not appear to have MySQL available within PHP.');
  148. }
  149. public function configure() {
  150. try {
  151. $val = Loader::helper('validation/form');
  152. $val->setData($this->post());
  153. $val->addRequired("SITE", t("Please specify your site's name"));
  154. $val->addRequiredEmail("uEmail", t('Please specify a valid email address'));
  155. $val->addRequired("DB_DATABASE", t('You must specify a valid database name'));
  156. $val->addRequired("DB_SERVER", t('You must specify a valid database server'));
  157. $e = Loader::helper('/validation/error');
  158. if(is_object($this->fileWriteErrors)) {
  159. $e = $this->fileWriteErrors;
  160. }
  161. if (!function_exists('mysql_connect')) {
  162. $e->add($this->getDBErrorMsg());
  163. } else {
  164. // attempt to connect to the database
  165. $db = Loader::db( $_POST['DB_SERVER'], $_POST['DB_USERNAME'], $_POST['DB_PASSWORD'], $_POST['DB_DATABASE'], true);
  166. if ($_POST['DB_SERVER'] && $_POST['DB_DATABASE']) {
  167. if (!$db) {
  168. $e->add(t('Unable to connect to database.'));
  169. } else {
  170. $num = $db->GetCol("show tables");
  171. if (count($num) > 0) {
  172. $e->add(t('There are already %s tables in this database. Concrete must be installed in an empty database.', count($num)));
  173. }
  174. }
  175. }
  176. }
  177. if ($val->test() && (!$e->has())) {
  178. if (!is_dir($this->installData['DIR_FILES_UPLOADED_THUMBNAILS'])) {
  179. mkdir($this->installData['DIR_FILES_UPLOADED_THUMBNAILS']);
  180. }
  181. if (!is_dir($this->installData['DIR_FILES_INCOMING'])) {
  182. mkdir($this->installData['DIR_FILES_INCOMING']);
  183. }
  184. if (!is_dir($this->installData['DIR_FILES_TRASH'])) {
  185. mkdir($this->installData['DIR_FILES_TRASH']);
  186. }
  187. if (!is_dir($this->installData['DIR_FILES_CACHE'])) {
  188. mkdir($this->installData['DIR_FILES_CACHE']);
  189. }
  190. if (!is_dir($this->installData['DIR_FILES_CACHE_DB'])) {
  191. mkdir($this->installData['DIR_FILES_CACHE_DB']);
  192. }
  193. if (!is_dir($this->installData['DIR_FILES_AVATARS'])) {
  194. mkdir($this->installData['DIR_FILES_AVATARS']);
  195. }
  196. if (isset($_POST['uPasswordForce'])) {
  197. $this->installData['uPassword'] = $_POST['uPasswordForce'];
  198. }
  199. if (isset($_POST['packages'])) {
  200. $this->installData['packages'] = $_POST['packages'];
  201. }
  202. $this->installDB();
  203. $vh = Loader::helper('validation/identifier');
  204. // copy the files
  205. $fh = Loader::helper('file');
  206. if ($_POST['INSTALL_SAMPLE_CONTENT']) {
  207. $fh->copyAll($this->installData['DIR_BASE_CORE'] . '/config/install/files', DIR_FILES_UPLOADED);
  208. }
  209. // insert admin user into the user table
  210. $salt = ( defined('MANUAL_PASSWORD_SALT') ) ? MANUAL_PASSWORD_SALT : $vh->getString(64);
  211. if(!isset($this->installData['uPassword'])) {
  212. $uPassword = rand(100000, 999999);
  213. } else {
  214. $uPassword = $this->installData['uPassword'];
  215. }
  216. $uEmail = $_POST['uEmail'];
  217. $uPasswordEncrypted = User::encryptPassword($uPassword, $salt);
  218. UserInfo::addSuperUser($uPasswordEncrypted, $uEmail);
  219. if (defined('PERMISSIONS_MODEL') && PERMISSIONS_MODEL != 'simple') {
  220. $setPermissionsModel = PERMISSIONS_MODEL;
  221. }
  222. if (file_exists($this->installData['DIR_CONFIG_SITE'])) {
  223. $this->fp = @fopen($this->installData['DIR_CONFIG_SITE'] . '/site.php', 'w+');
  224. if ($this->fp) {
  225. Cache::flush();
  226. if (is_array($this->installData['packages'])) {
  227. foreach($this->installData['packages'] as $pkgHandle) {
  228. $p = Loader::package($pkgHandle);
  229. $p->install();
  230. }
  231. }
  232. // write the config file
  233. $configuration = "<?php\n";
  234. $configuration .= "define('DB_SERVER', '" . addslashes($_POST['DB_SERVER']) . "');\n";
  235. $configuration .= "define('DB_USERNAME', '" . addslashes($_POST['DB_USERNAME']) . "');\n";
  236. $configuration .= "define('DB_PASSWORD', '" . addslashes($_POST['DB_PASSWORD']) . "');\n";
  237. $configuration .= "define('DB_DATABASE', '" . addslashes($_POST['DB_DATABASE']) . "');\n";
  238. $configuration .= "define('BASE_URL', '" . $this->installData['BASE_URL'] . "');\n";
  239. $configuration .= "define('DIR_REL', '" . $this->installData['DIR_REL'] . "');\n";
  240. if (isset($setPermissionsModel)) {
  241. $configuration .= "define('PERMISSIONS_MODEL', '" . addslashes($setPermissionsModel) . "');\n";
  242. }
  243. $configuration .= "define('PASSWORD_SALT', '{$salt}');\n";
  244. if (is_array($_POST['SITE_CONFIG'])) {
  245. foreach($_POST['SITE_CONFIG'] as $key => $value) {
  246. $configuration .= "define('" . $key . "', '" . $value . "');\n";
  247. }
  248. }
  249. $res = fwrite($this->fp, $configuration);
  250. fclose($this->fp);
  251. chmod($this->installData['DIR_CONFIG_SITE'] . '/site.php', 0777);
  252. // save some options into the database
  253. Config::save('SITE', $_POST['SITE']);
  254. // add the current app version as our site's app version
  255. Config::save('SITE_APP_VERSION', $this->installData['APP_VERSION']);
  256. Config::save('SITE_DEBUG_LEVEL', $this->installData['DEBUG_DISPLAY_ERRORS']);
  257. Config::save('ENABLE_LOG_EMAILS', 1);
  258. Config::save('ENABLE_LOG_ERRORS', 1);
  259. Config::save('FULL_PAGE_CACHE_GLOBAL', 0);
  260. // login
  261. define('PASSWORD_SALT', $salt);
  262. $u = new User($this->installData['USER_SUPER'], $uPassword);
  263. $this->set('message', t('Congratulations. concrete5 has been installed. You have been logged in as <b>%s</b> with the password <b>%s</b>.<br/><br/>If you wish to change this password, you may do so from the users area of the dashboard.', $this->installData['USER_SUPER'], $uPassword));
  264. } else {
  265. throw new Exception(t('Unable to open config/site.php for writing.'));
  266. }
  267. } else {
  268. throw new Exception(t('Unable to locate config directory.'));
  269. }
  270. } else {
  271. if ($e->has()) {
  272. $this->set('error', $e);
  273. } else {
  274. $this->set('error', $val->getError());
  275. }
  276. }
  277. } catch (Exception $e) {
  278. // remove site.php so that we can try again ?
  279. if (is_resource($this->fp)) {
  280. fclose($this->fp);
  281. }
  282. if (file_exists($this->installData['DIR_CONFIG_SITE'] . '/site.php')) {
  283. unlink($this->installData['DIR_CONFIG_SITE'] . '/site.php');
  284. }
  285. $this->set('error', $e);
  286. }
  287. }
  288. }
  289. ?>