Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

609 lines
18 KiB

  1. <?php
  2. require_once "include/Photo.php";
  3. $install_wizard_pass=1;
  4. function install_init(&$a){
  5. // $baseurl/install/testrwrite to test if rewite in .htaccess is working
  6. if ($a->argc==2 && $a->argv[1]=="testrewrite") {
  7. echo "ok";
  8. killme();
  9. }
  10. // We overwrite current theme css, because during install we could not have a working mod_rewrite
  11. // so we could not have a css at all. Here we set a static css file for the install procedure pages
  12. $a->config['system']['theme'] = "../install";
  13. $a->theme['stylesheet'] = $a->get_baseurl()."/view/install/style.css";
  14. global $install_wizard_pass;
  15. if (x($_POST,'pass'))
  16. $install_wizard_pass = intval($_POST['pass']);
  17. }
  18. function install_post(&$a) {
  19. global $install_wizard_pass, $db;
  20. switch($install_wizard_pass) {
  21. case 1:
  22. case 2:
  23. return;
  24. break; // just in case return don't return :)
  25. case 3:
  26. $urlpath = $a->get_path();
  27. $dbhost = notags(trim($_POST['dbhost']));
  28. $dbuser = notags(trim($_POST['dbuser']));
  29. $dbpass = notags(trim($_POST['dbpass']));
  30. $dbdata = notags(trim($_POST['dbdata']));
  31. $phpath = notags(trim($_POST['phpath']));
  32. require_once("include/dba.php");
  33. unset($db);
  34. $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true);
  35. /*if(get_db_errno()) {
  36. unset($db);
  37. $db = new dba($dbhost, $dbuser, $dbpass, '', true);
  38. if(! get_db_errno()) {
  39. $r = q("CREATE DATABASE '%s'",
  40. dbesc($dbdata)
  41. );
  42. if($r) {
  43. unset($db);
  44. $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true);
  45. } else {
  46. $a->data['db_create_failed']=true;
  47. }
  48. } else {
  49. $a->data['db_conn_failed']=true;
  50. return;
  51. }
  52. }*/
  53. if(get_db_errno()) {
  54. $a->data['db_conn_failed']=true;
  55. }
  56. return;
  57. break;
  58. case 4:
  59. $urlpath = $a->get_path();
  60. $dbhost = notags(trim($_POST['dbhost']));
  61. $dbuser = notags(trim($_POST['dbuser']));
  62. $dbpass = notags(trim($_POST['dbpass']));
  63. $dbdata = notags(trim($_POST['dbdata']));
  64. $phpath = notags(trim($_POST['phpath']));
  65. $timezone = notags(trim($_POST['timezone']));
  66. $language = notags(trim($_POST['language']));
  67. $adminmail = notags(trim($_POST['adminmail']));
  68. // In step 4 of the installer, we passed the check for mcrypt
  69. // already, so we can activate RINO, make RINO2 the default
  70. // and only fall back if the mcrypt_create_iv function is
  71. // not available on the system.
  72. $rino = 2;
  73. if (! function_exists('mcrypt_create_iv')) {
  74. $rino = 1;
  75. }
  76. // connect to db
  77. $db = new dba($dbhost, $dbuser, $dbpass, $dbdata, true);
  78. $tpl = get_markup_template('htconfig.tpl');
  79. $txt = replace_macros($tpl,array(
  80. '$dbhost' => $dbhost,
  81. '$dbuser' => $dbuser,
  82. '$dbpass' => $dbpass,
  83. '$dbdata' => $dbdata,
  84. '$timezone' => $timezone,
  85. '$language' => $language,
  86. '$urlpath' => $urlpath,
  87. '$phpath' => $phpath,
  88. '$adminmail' => $adminmail,
  89. '$rino' => $rino
  90. ));
  91. $result = file_put_contents('.htconfig.php', $txt);
  92. if(! $result) {
  93. $a->data['txt'] = $txt;
  94. }
  95. $errors = load_database($db);
  96. if($errors)
  97. $a->data['db_failed'] = $errors;
  98. else
  99. $a->data['db_installed'] = true;
  100. return;
  101. break;
  102. }
  103. }
  104. function get_db_errno() {
  105. if(class_exists('mysqli'))
  106. return mysqli_connect_errno();
  107. else
  108. return mysql_errno();
  109. }
  110. function install_content(&$a) {
  111. global $install_wizard_pass, $db;
  112. $o = '';
  113. $wizard_status = "";
  114. $install_title = t('Friendica Communications Server - Setup');
  115. if(x($a->data,'db_conn_failed')) {
  116. $install_wizard_pass = 2;
  117. $wizard_status = t('Could not connect to database.');
  118. }
  119. if(x($a->data,'db_create_failed')) {
  120. $install_wizard_pass = 2;
  121. $wizard_status = t('Could not create table.');
  122. }
  123. $db_return_text="";
  124. if(x($a->data,'db_installed')) {
  125. $txt = '<p style="font-size: 130%;">';
  126. $txt .= t('Your Friendica site database has been installed.') . EOL;
  127. $db_return_text .= $txt;
  128. }
  129. if(x($a->data,'db_failed')) {
  130. $txt = t('You may need to import the file "database.sql" manually using phpmyadmin or mysql.') . EOL;
  131. $txt .= t('Please see the file "INSTALL.txt".') . EOL ."<hr>" ;
  132. $txt .= "<pre>".$a->data['db_failed'] . "</pre>". EOL ;
  133. $db_return_text .= $txt;
  134. }
  135. if($db && $db->connected) {
  136. $r = q("SELECT COUNT(*) as `total` FROM `user`");
  137. if($r && count($r) && $r[0]['total']) {
  138. $tpl = get_markup_template('install.tpl');
  139. return replace_macros($tpl, array(
  140. '$title' => $install_title,
  141. '$pass' => '',
  142. '$status' => t('Database already in use.'),
  143. '$text' => '',
  144. ));
  145. }
  146. }
  147. if(x($a->data,'txt') && strlen($a->data['txt'])) {
  148. $db_return_text .= manual_config($a);
  149. }
  150. if ($db_return_text!="") {
  151. $tpl = get_markup_template('install.tpl');
  152. return replace_macros($tpl, array(
  153. '$title' => $install_title,
  154. '$pass' => "",
  155. '$text' => $db_return_text . what_next(),
  156. ));
  157. }
  158. switch ($install_wizard_pass){
  159. case 1: { // System check
  160. $checks = array();
  161. check_funcs($checks);
  162. check_imagik($checks);
  163. check_htconfig($checks);
  164. check_smarty3($checks);
  165. check_keys($checks);
  166. if(x($_POST,'phpath'))
  167. $phpath = notags(trim($_POST['phpath']));
  168. check_php($phpath, $checks);
  169. check_htaccess($checks);
  170. function check_passed($v, $c){
  171. if ($c['required'])
  172. $v = $v && $c['status'];
  173. return $v;
  174. }
  175. $checkspassed = array_reduce($checks, "check_passed", true);
  176. $tpl = get_markup_template('install_checks.tpl');
  177. $o .= replace_macros($tpl, array(
  178. '$title' => $install_title,
  179. '$pass' => t('System check'),
  180. '$checks' => $checks,
  181. '$passed' => $checkspassed,
  182. '$see_install' => t('Please see the file "INSTALL.txt".'),
  183. '$next' => t('Next'),
  184. '$reload' => t('Check again'),
  185. '$phpath' => $phpath,
  186. '$baseurl' => $a->get_baseurl(),
  187. ));
  188. return $o;
  189. }; break;
  190. case 2: { // Database config
  191. $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost');
  192. $dbuser = notags(trim($_POST['dbuser']));
  193. $dbpass = notags(trim($_POST['dbpass']));
  194. $dbdata = notags(trim($_POST['dbdata']));
  195. $phpath = notags(trim($_POST['phpath']));
  196. $tpl = get_markup_template('install_db.tpl');
  197. $o .= replace_macros($tpl, array(
  198. '$title' => $install_title,
  199. '$pass' => t('Database connection'),
  200. '$info_01' => t('In order to install Friendica we need to know how to connect to your database.'),
  201. '$info_02' => t('Please contact your hosting provider or site administrator if you have questions about these settings.'),
  202. '$info_03' => t('The database you specify below should already exist. If it does not, please create it before continuing.'),
  203. '$status' => $wizard_status,
  204. '$dbhost' => array('dbhost', t('Database Server Name'), $dbhost, '', 'required'),
  205. '$dbuser' => array('dbuser', t('Database Login Name'), $dbuser, '', 'required', 'autofocus'),
  206. '$dbpass' => array('dbpass', t('Database Login Password'), $dbpass, '', 'required'),
  207. '$dbdata' => array('dbdata', t('Database Name'), $dbdata, '', 'required'),
  208. '$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.'), 'required', 'autofocus', 'email'),
  209. '$lbl_10' => t('Please select a default timezone for your website'),
  210. '$baseurl' => $a->get_baseurl(),
  211. '$phpath' => $phpath,
  212. '$submit' => t('Submit'),
  213. ));
  214. return $o;
  215. }; break;
  216. case 3: { // Site settings
  217. require_once('include/datetime.php');
  218. $dbhost = ((x($_POST,'dbhost')) ? notags(trim($_POST['dbhost'])) : 'localhost');
  219. $dbuser = notags(trim($_POST['dbuser']));
  220. $dbpass = notags(trim($_POST['dbpass']));
  221. $dbdata = notags(trim($_POST['dbdata']));
  222. $phpath = notags(trim($_POST['phpath']));
  223. $adminmail = notags(trim($_POST['adminmail']));
  224. $timezone = ((x($_POST,'timezone')) ? ($_POST['timezone']) : 'America/Los_Angeles');
  225. /* Installed langs */
  226. $lang_choices = get_available_languages();
  227. $tpl = get_markup_template('install_settings.tpl');
  228. $o .= replace_macros($tpl, array(
  229. '$title' => $install_title,
  230. '$pass' => t('Site settings'),
  231. '$status' => $wizard_status,
  232. '$dbhost' => $dbhost,
  233. '$dbuser' => $dbuser,
  234. '$dbpass' => $dbpass,
  235. '$dbdata' => $dbdata,
  236. '$phpath' => $phpath,
  237. '$adminmail' => array('adminmail', t('Site administrator email address'), $adminmail, t('Your account email address must match this in order to use the web admin panel.'), 'required', 'autofocus', 'email'),
  238. '$timezone' => field_timezone('timezone', t('Please select a default timezone for your website'), $timezone, ''),
  239. '$language' => array('language', t('System Language:'), 'en', t('Set the default language for your Friendica installation interface and to send emails.'), $lang_choices),
  240. '$baseurl' => $a->get_baseurl(),
  241. '$submit' => t('Submit'),
  242. ));
  243. return $o;
  244. }; break;
  245. }
  246. }
  247. /**
  248. * checks : array passed to template
  249. * title : string
  250. * status : boolean
  251. * required : boolean
  252. * help : string optional
  253. */
  254. function check_add(&$checks, $title, $status, $required, $help){
  255. $checks[] = array(
  256. 'title' => $title,
  257. 'status' => $status,
  258. 'required' => $required,
  259. 'help' => $help,
  260. );
  261. }
  262. function check_php(&$phpath, &$checks) {
  263. $passed = $passed2 = $passed3 = false;
  264. if (strlen($phpath)){
  265. $passed = file_exists($phpath);
  266. } else {
  267. $phpath = trim(shell_exec('which php'));
  268. $passed = strlen($phpath);
  269. }
  270. $help = "";
  271. if(!$passed) {
  272. $help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL;
  273. $help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='https://github.com/friendica/friendica/blob/master/doc/Install.md#set-up-the-poller'>'Setup the poller'</a>") . EOL ;
  274. $help .= EOL . EOL ;
  275. $tpl = get_markup_template('field_input.tpl');
  276. $help .= replace_macros($tpl, array(
  277. '$field' => array('phpath', t('PHP executable path'), $phpath, t('Enter full path to php executable. You can leave this blank to continue the installation.')),
  278. ));
  279. $phpath="";
  280. }
  281. check_add($checks, t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help);
  282. if($passed) {
  283. $cmd = "$phpath -v";
  284. $result = trim(shell_exec($cmd));
  285. $passed2 = ( strpos($result, "(cli)") !== false );
  286. list($result) = explode("\n", $result);
  287. $help = "";
  288. if(!$passed2) {
  289. $help .= t('PHP executable is not the php cli binary (could be cgi-fgci version)'). EOL;
  290. $help .= t('Found PHP version: ')."<tt>$result</tt>";
  291. }
  292. check_add($checks, t('PHP cli binary'), $passed2, true, $help);
  293. }
  294. if($passed2) {
  295. $str = autoname(8);
  296. $cmd = "$phpath testargs.php $str";
  297. $result = trim(shell_exec($cmd));
  298. $passed3 = $result == $str;
  299. $help = "";
  300. if(!$passed3) {
  301. $help .= t('The command line version of PHP on your system does not have "register_argc_argv" enabled.'). EOL;
  302. $help .= t('This is required for message delivery to work.');
  303. }
  304. check_add($checks, t('PHP register_argc_argv'), $passed3, true, $help);
  305. }
  306. }
  307. function check_keys(&$checks) {
  308. $help = '';
  309. $res = false;
  310. if(function_exists('openssl_pkey_new'))
  311. $res=openssl_pkey_new(array(
  312. 'digest_alg' => 'sha1',
  313. 'private_key_bits' => 4096,
  314. 'encrypt_key' => false ));
  315. // Get private key
  316. if(! $res) {
  317. $help .= t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys'). EOL;
  318. $help .= t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".');
  319. }
  320. check_add($checks, t('Generate encryption keys'), $res, true, $help);
  321. }
  322. function check_funcs(&$checks) {
  323. $ck_funcs = array();
  324. check_add($ck_funcs, t('libCurl PHP module'), true, true, "");
  325. check_add($ck_funcs, t('GD graphics PHP module'), true, true, "");
  326. check_add($ck_funcs, t('OpenSSL PHP module'), true, true, "");
  327. check_add($ck_funcs, t('mysqli PHP module'), true, true, "");
  328. check_add($ck_funcs, t('mb_string PHP module'), true, true, "");
  329. check_add($ck_funcs, t('mcrypt PHP module'), true, true, "");
  330. check_add($ck_funcs, t('XML PHP module'), true, true, "");
  331. check_add($ck_funcs, t('iconv module'), true, true, "");
  332. if(function_exists('apache_get_modules')){
  333. if (! in_array('mod_rewrite',apache_get_modules())) {
  334. check_add($ck_funcs, t('Apache mod_rewrite module'), false, true, t('Error: Apache webserver mod-rewrite module is required but not installed.'));
  335. } else {
  336. check_add($ck_funcs, t('Apache mod_rewrite module'), true, true, "");
  337. }
  338. }
  339. if(! function_exists('curl_init')){
  340. $ck_funcs[0]['status']= false;
  341. $ck_funcs[0]['help']= t('Error: libCURL PHP module required but not installed.');
  342. }
  343. if(! function_exists('imagecreatefromjpeg')){
  344. $ck_funcs[1]['status']= false;
  345. $ck_funcs[1]['help']= t('Error: GD graphics PHP module with JPEG support required but not installed.');
  346. }
  347. if(! function_exists('openssl_public_encrypt')) {
  348. $ck_funcs[2]['status']= false;
  349. $ck_funcs[2]['help']= t('Error: openssl PHP module required but not installed.');
  350. }
  351. if(! function_exists('mysqli_connect')){
  352. $ck_funcs[3]['status']= false;
  353. $ck_funcs[3]['help']= t('Error: mysqli PHP module required but not installed.');
  354. }
  355. if(! function_exists('mb_strlen')){
  356. $ck_funcs[4]['status']= false;
  357. $ck_funcs[4]['help']= t('Error: mb_string PHP module required but not installed.');
  358. }
  359. if(! function_exists('mcrypt_create_iv')){
  360. $ck_funcs[5]['status']= false;
  361. $ck_funcs[5]['help']= t('Error: mcrypt PHP module required but not installed.');
  362. }
  363. if(! function_exists('iconv_strlen')){
  364. $ck_funcs[7]['status']= false;
  365. $ck_funcs[7]['help']= t('Error: iconv PHP module required but not installed.');
  366. }
  367. $checks = array_merge($checks, $ck_funcs);
  368. // check for 'mcrypt_create_iv()', needed for RINO2
  369. if ($ck_funcs[5]['status']) {
  370. if (function_exists('mcrypt_create_iv')) {
  371. $__status = true;
  372. $__help = t("If you are using php_cli, please make sure that mcrypt module is enabled in its config file");
  373. } else {
  374. $__status = false;
  375. $__help = t('Function mcrypt_create_iv() is not defined. This is needed to enable RINO2 encryption layer.');
  376. }
  377. check_add($checks, t('mcrypt_create_iv() function'), $__status, false, $__help);
  378. }
  379. // check for XML DOM Documents being able to be generated
  380. try {
  381. $xml = new DOMDocument();
  382. } catch (Exception $e) {
  383. $ck_funcs[6]['status'] = false;
  384. $ck_funcs[6]['help'] = t('Error, XML PHP module required but not installed.');
  385. }
  386. /*if((x($_SESSION,'sysmsg')) && is_array($_SESSION['sysmsg']) && count($_SESSION['sysmsg']))
  387. notice( t('Please see the file "INSTALL.txt".') . EOL);*/
  388. }
  389. function check_htconfig(&$checks) {
  390. $status = true;
  391. $help = "";
  392. if( (file_exists('.htconfig.php') && !is_writable('.htconfig.php')) ||
  393. (!file_exists('.htconfig.php') && !is_writable('.')) ) {
  394. $status=false;
  395. $help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL;
  396. $help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL;
  397. $help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Friendica top folder.').EOL;
  398. $help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "INSTALL.txt" for instructions.').EOL;
  399. }
  400. check_add($checks, t('.htconfig.php is writable'), $status, false, $help);
  401. }
  402. function check_smarty3(&$checks) {
  403. $status = true;
  404. $help = "";
  405. if( !is_writable('view/smarty3') ) {
  406. $status=false;
  407. $help = t('Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') .EOL;
  408. $help .= t('In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder.').EOL;
  409. $help .= t('Please ensure that the user that your web server runs as (e.g. www-data) has write access to this folder.').EOL;
  410. $help .= t('Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files (.tpl) that it contains.').EOL;
  411. }
  412. check_add($checks, t('view/smarty3 is writable'), $status, true, $help);
  413. }
  414. function check_htaccess(&$checks) {
  415. $a = get_app();
  416. $status = true;
  417. $help = "";
  418. if (function_exists('curl_init')){
  419. $test = fetch_url($a->get_baseurl()."/install/testrewrite");
  420. if ($test!="ok")
  421. $test = fetch_url(normalise_link($a->get_baseurl()."/install/testrewrite"));
  422. if ($test!="ok") {
  423. $status = false;
  424. $help = t('Url rewrite in .htaccess is not working. Check your server configuration.');
  425. }
  426. check_add($checks, t('Url rewrite is working'), $status, true, $help);
  427. } else {
  428. // cannot check modrewrite if libcurl is not installed
  429. }
  430. }
  431. function check_imagik(&$checks) {
  432. $imagick = false;
  433. $gif = false;
  434. if (class_exists('Imagick')) {
  435. $imagick = true;
  436. $supported = Photo::supportedTypes();
  437. if (array_key_exists('image/gif', $supported)) {
  438. $gif = true;
  439. }
  440. }
  441. check_add($checks, t('ImageMagick PHP extension is installed'), $imagick, false, "");
  442. if ($imagick) {
  443. check_add($checks, t('ImageMagick supports GIF'), $gif, false, "");
  444. }
  445. }
  446. function manual_config(&$a) {
  447. $data = htmlentities($a->data['txt'],ENT_COMPAT,'UTF-8');
  448. $o = t('The database configuration file ".htconfig.php" could not be written. Please use the enclosed text to create a configuration file in your web server root.');
  449. $o .= "<textarea rows=\"24\" cols=\"80\" >$data</textarea>";
  450. return $o;
  451. }
  452. function load_database_rem($v, $i){
  453. $l = trim($i);
  454. if (strlen($l)>1 && ($l[0]=="-" || ($l[0]=="/" && $l[1]=="*"))){
  455. return $v;
  456. } else {
  457. return $v."\n".$i;
  458. }
  459. }
  460. function load_database($db) {
  461. require_once("include/dbstructure.php");
  462. $errors = update_structure(false, true);
  463. /* $str = file_get_contents('database.sql');
  464. $arr = explode(';',$str);
  465. $errors = false;
  466. foreach($arr as $a) {
  467. if(strlen(trim($a))) {
  468. $r = @$db->q(trim($a));
  469. if(false === $r) {
  470. $errors .= t('Errors encountered creating database tables.') . $a . EOL;
  471. }
  472. }
  473. }*/
  474. return $errors;
  475. }
  476. function what_next() {
  477. $a = get_app();
  478. $baseurl = $a->get_baseurl();
  479. return
  480. t('<h1>What next</h1>')
  481. ."<p>".t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.')
  482. .t('Please see the file "INSTALL.txt".')
  483. ."</p><p>"
  484. .t("Go to your new Friendica node <a href='$baseurl/register'>registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.")
  485. ."</p>";
  486. }