1<?php
2
3require_once dirname(__FILE__).'/accesscheck.php';
4
5include dirname(__FILE__).'/structure.php';
6
7function output($message)
8{
9    if ($GLOBALS['commandline']) {
10        @ob_end_clean();
11        echo strip_tags($message)."\n";
12        ob_start();
13    } else {
14        echo $message;
15        flush();
16        @ob_end_flush();
17    }
18    flush();
19}
20cl_output(s('Initialising phpList database structure.'));
21
22$success = 1;
23
24## fall back to environment variables (mostly for CLI)
25if (!isset($_REQUEST['adminname'])) {
26    $_REQUEST['adminname'] = getenv('ADMIN_NAME');
27}
28if (!isset($_REQUEST['orgname'])) {
29    $_REQUEST['orgname'] = getenv('ORGANISATION_NAME');
30}
31if (!isset($_REQUEST['adminpassword'])) {
32    $_REQUEST['adminpassword'] = getenv('ADMIN_PASSWORD');
33}
34if (!isset($_REQUEST['adminemail'])) {
35    $_REQUEST['adminemail'] = getenv('ADMIN_EMAIL');
36}
37
38## require some variables on CLI
39if ($GLOBALS['commandline']) {
40  if (empty($_REQUEST['adminname'])) {
41      $_REQUEST['adminname'] = 'admin';
42  }
43  if (empty($_REQUEST['orgname'])) {
44      $_REQUEST['orgname'] = s('Organisation Name');
45  }
46  if (empty($_REQUEST['adminpassword'])) {
47      output(s('Admin password not set, cannot continue'));
48      cl_output(s('set ADMIN_PASSWORD environment variable'));
49      return;
50  }
51  if (empty($_REQUEST['adminemail'])) {
52      output(s('Admin email not set, cannot continue'));
53      cl_output(s('set ADMIN_EMAIL environment variable'));
54      return;
55  }
56  if ($GLOBALS['commandline'] && !is_email($_REQUEST['adminemail'])) {
57    output(s('Unable to validate email address for admin: '.strip_tags($_REQUEST['adminemail'])));
58    return;
59  }
60}
61
62$force = (!empty($_GET['force']) && $_GET['force'] == 'yes') || isset($cline['f']);
63
64if ($force) {
65    foreach ($DBstruct as $table => $val) {
66        if ($table == 'attribute' && Sql_Table_Exists('attribute')) {
67            $req = Sql_Query("select tablename from {$tables['attribute']}");
68            while ($row = Sql_Fetch_Row($req)) {
69                Sql_Query('drop table if exists '.$table_prefix.'listattr_'.$row[0]);
70            }
71        }
72        Sql_Query('drop table if exists '.$tables[$table]);
73    }
74    if (!$GLOBALS['commandline']) {
75      session_destroy();
76      Redirect('initialise&firstinstall=1');
77      exit;
78    }
79}
80@ob_end_flush();
81
82if (!$GLOBALS['commandline'] && empty($_SESSION['hasconf']) && !empty($_REQUEST['firstinstall']) && (empty($_REQUEST['adminemail']) || strlen($_REQUEST['adminpassword']) < 8)) {
83    $output = '<noscript>';
84    $output .= '<div class="error">'.s('To install phpList, you need to enable Javascript').'</div>';
85    $output .= '</noscript>';
86
87    if ($_SESSION['adminlanguage']['iso'] != $GLOBALS['default_system_language'] &&
88        in_array($_SESSION['adminlanguage']['iso'], array_keys($GLOBALS['LANGUAGES']))
89    ) {
90        $output .= '<div class="info error">'.s('The default system language is different from your browser language.').'<br/>';
91        $output .= s('You can set <pre>$default_system_language = "%s";</pre> in your config file, to use your language as the fallback language.',
92                $_SESSION['adminlanguage']['iso']).'<br/>';
93        $output .= s('It is best to do this before initialising the database.');
94        $output .= '</div>';
95    }
96
97    $output .= '<form method="post" action="" class="configForm" id="initialiseform">';
98    $output .= '<fieldset><legend>'.s('phpList initialisation').' </legend>
99    <input type="hidden" name="firstinstall" value="1" />';
100    $output .= '<input type="hidden" name="page" value="initialise" />';
101    $output .= '<label for="adminname">'.s('Please enter your name.').'</label>';
102    $output .= '<div class="field"><input type="text" name="adminname" class="error missing" value="'.htmlspecialchars($_REQUEST['adminname']).'" /></div>';
103    $output .= '<label for="orgname">'.s('The name of your organisation').'</label>';
104    $output .= '<input type="text" name="orgname" value="'.htmlspecialchars($_REQUEST['orgname']).'" />';
105    $output .= '<label for="adminemail">'.s('Please enter your email address.').'</label>';
106
107    $output .= '<input type="text" name="adminemail" value="'.htmlspecialchars($_REQUEST['adminemail']).'" />';
108    $output .= s('The initial <i>login name</i> will be').' "admin"'.'<br/>';
109    $output .= '<label for="adminpassword">'.s('Please enter the password you want to use for this account.').' ('.$GLOBALS['I18N']->get('minimum of 8 characters.').')</label>';
110    $output .= '<input type="text" name="adminpassword" value="" id="initialadminpassword" /><br/><br/>';
111    $output .= '<input type="submit" value="'.s('Continue').'" id="initialisecontinue" disabled="disabled" />';
112    $output .= '</fieldset></form>';
113    output($output);
114    return;
115}
116
117//var_dump($GLOBALS['plugins']);exit;
118
119if ($GLOBALS['commandline'] && $_SESSION['hasconf'] && empty($force)) {
120  cl_output(s('Already initialised. Use -f to force'));
121  return;
122}
123
124output('<h3>'.s('Creating tables')."</h3><br />");
125foreach ($DBstruct as $table => $val) {
126    if ($force) {
127        if ($table == 'attribute' &&  Sql_Table_exists('attribute')) {
128            $req = Sql_Query("select tablename from {$tables['attribute']}");
129            while ($row = Sql_Fetch_Row($req)) {
130                Sql_Query("drop table if exists $table_prefix"."listattr_$row[0]", 1);
131            }
132        }
133        Sql_query("drop table if exists $tables[$table]");
134        unset($_SESSION["dbtables"]);
135    }
136    $query = "CREATE TABLE $tables[$table] (\n";
137    foreach ($DBstruct[$table] as $column => $struct) {
138        if (preg_match('/index_\d+/', $column)) {
139            $query .= 'index '.$struct[0].',';
140        } elseif (preg_match('/unique_\d+/', $column)) {
141            $query .= 'unique '.$struct[0].',';
142        } else {
143            $query .= "$column ".$struct[0].',';
144        }
145    }
146    // get rid of the last ,
147    $query = substr($query, 0, -1);
148    $query .= "\n) default character set utf8";
149
150    if (!empty($GLOBALS['mysql_database_engine'])) {
151      $query .= ' engine '.$GLOBALS['mysql_database_engine'];
152    }
153
154    // submit it to the database
155    output(s('Initialising table')." <b>$table</b>");
156    if (!$force && Sql_Table_Exists($tables[$table])) {
157        Error(s('Table already exists').'<br />');
158        output( '... '.s('failed')."<br />");
159        $success = 0;
160    } else {
161        $res = Sql_Query($query, 0);
162        $error = Sql_Has_Error($database_connection);
163        $success = $force || ($success && !$error);
164        if (!$error || $force) {
165            if ($table == 'admin') {
166                // create a default admin
167                $_SESSION['firstinstall'] = 1;
168                $adminemail = $_REQUEST['adminemail'];
169                $adminpass = $_REQUEST['adminpassword'];
170                Sql_Query(sprintf('insert into %s (loginname,namelc,email,created,modified,password,passwordchanged,superuser,disabled)
171                    values("%s","%s","%s",now(),now(),"%s",now(),%d,0)',
172                    $tables['admin'], 'admin', 'admin', sql_escape($adminemail), encryptPass($adminpass), 1));
173
174                //# let's add them as a subscriber as well
175                $userid = addNewUser($adminemail, $adminpass);
176                Sql_Query(sprintf('update %s set confirmed = 1 where id = %d', $tables['user'], $userid));
177
178                /* to send the token at the end, doesn't work yet
179                $adminid = Sql_Insert_Id();
180                */
181            } elseif ($table == 'task') {
182                foreach ($system_pages as $type => $pages) {
183                    foreach ($pages as $page => $access_level) {
184                        Sql_Query(sprintf('replace into %s (page,type) values("%s","%s")',
185                            $tables['task'], $page, $type));
186                    }
187                }
188            }
189
190            output( '... '.s('ok')."<br />");
191        } else {
192            output( '... '.s('failed')."<br />\n");
193        }
194    }
195}
196//https://mantis.phplist.com/view.php?id=16879 make sure the new settings are saved
197if ($success) {
198    $_SESSION['hasconf'] = true;
199}
200
201//# initialise plugins that are already here
202foreach ($GLOBALS['plugins'] as $pluginName => $plugin) {
203    output( s('Initialise plugin').' '.$pluginName.'<br/>');
204    if (method_exists($plugin, 'initialise')) {
205        $plugin->initialise();
206    }
207    SaveConfig(md5('plugin-'.$pluginName.'-initialised'), time(), 0);
208}
209
210if ($success) {
211    output( s('Setting default configuration').'<br/>');
212    // mark the database to be our current version
213    output('<strong>'.s('Admin =').'</strong> '.$_REQUEST['adminname'].'<br/>');
214    output('<strong>'.s('Admin Email =').'</strong> '.$adminemail.'<br/>');
215    SaveConfig('version', VERSION, 0);
216    SaveConfig('admin_address', $adminemail, 1);
217    SaveConfig('message_from_name', strip_tags($_REQUEST['adminname']), 1);
218    SaveConfig('campaignfrom_default', "$adminemail ".strip_tags($_REQUEST['adminname']));
219    SaveConfig('notifystart_default', $adminemail);
220    SaveConfig('notifyend_default', $adminemail);
221    SaveConfig('report_address', $adminemail);
222    SaveConfig('message_from_address', $adminemail);
223    SaveConfig('message_from_name', strip_tags($_REQUEST['adminname']));
224    SaveConfig('message_replyto_address', $adminemail);
225    SaveConfig('secret', bin2hex(random_bytes(20)));
226    SaveConfig('lastcheckupdate', date('m/d/Y h:i:s', time()), 0, true);
227
228    if (!empty($_REQUEST['orgname'])) {
229        SaveConfig('organisation_name', strip_tags($_REQUEST['orgname']), 1);
230        SaveConfig('campaignfrom_default', "$adminemail ".strip_tags($_REQUEST['orgname']));
231        SaveConfig('message_from_name', strip_tags($_REQUEST['orgname']));
232    } elseif (!empty($_REQUEST['adminname'])) {
233        SaveConfig('organisation_name', strip_tags($_REQUEST['adminname']), 1);
234    } else {
235        SaveConfig('organisation_name', strip_tags($_REQUEST['adminemail']), 1);
236    }
237    // add a draft campaign for invite plugin
238    addInviteCampaign(1);
239    // add a testlist
240    $info = s('List for testing');
241    $result = Sql_query("insert into {$tables['list']} (name,description,entered,active,owner) values(\"test\",\"$info\",now(),0,1)");
242    $info = s('Sign up to our newsletter');
243    $result = Sql_query("insert into {$tables['list']} (name,description,entered,active,owner) values(\"newsletter\",\"$info\",now(),1,1)");
244
245    //# add the admin to the lists
246    Sql_Query(sprintf('insert into %s (listid, userid, entered) values(%d,%d,now())', $tables['listuser'], 1, $userid));
247    Sql_Query(sprintf('insert into %s (listid, userid, entered) values(%d,%d,now())', $tables['listuser'], 2, $userid));
248
249    $uri = $_SERVER['REQUEST_URI'];
250    $uri = str_replace('?'.$_SERVER['QUERY_STRING'], '', $uri);
251    $body =
252        'Version: '.VERSION."\r\n"
253        .' Url: '
254        .$_SERVER['SERVER_NAME']
255        .$uri
256        ."\r\n";
257    printf('<p class="information">'
258        .$GLOBALS['I18N']->get('Success')
259        .': <a class="button" href="mailto:info@phplist.com?subject=Successful installation of phplist&amp;body=%s">'
260        .$GLOBALS['I18N']->get('Tell us about it')
261        .'</a>. </p>', $body);
262    //printf('<p class="information">
263    //'.$GLOBALS['I18N']->get("Please make sure to read the file README.security that can be found in the zip file.").'</p>');
264    echo subscribeToAnnouncementsForm($_REQUEST['adminemail']);
265
266    // make sure the 0 template has the powered by image
267    $query = sprintf('insert into %s (template, mimetype, filename, data, width, height) values (0, "image/png", "powerphplist.png", "%s", 70, 30)',
268        $GLOBALS['tables']['templateimage'], $newpoweredimage);
269    Sql_Query($query);
270    echo '<div id="continuesetup" style="display:none;" class="fleft">'.$GLOBALS['I18N']->get('Continue with').' '.PageLinkButton('setup',
271            $GLOBALS['I18N']->get('phpList Setup')).'</div>';
272
273    unset($_SESSION['hasI18Ntable']);
274
275    //# load language files
276    // this is too slow
277    $GLOBALS['I18N']->initFSTranslations();
278} else {
279    echo '<div class="initialiseOptions"><ul><li>'.s('Maybe you want to').' '.PageLinkButton('upgrade',
280            s('Upgrade')).' '.s('instead?').'</li>
281    <li>' .PageLinkButton('initialise', s('Force Initialisation'),
282            'force=yes').' '.s('(will erase all data!)').' '."</li></ul></div>\n";
283}