1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14: 
 15: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 16: 
 17:  18:  19:  20:  21:  22: 
 23: class cCLISetup {
 24: 
 25:      26:  27:  28: 
 29:     protected $settings;
 30: 
 31:      32:  33:  34: 
 35:     protected $args;
 36: 
 37:      38:  39:  40: 
 41:     protected $settingsFile;
 42: 
 43:      44:  45:  46:  47: 
 48:     public function __construct($args) {
 49:         $settings = array();
 50: 
 51:         $this->settings['db']['host'] = 'localhost';
 52:         $this->settings['db']['user'] = 'root';
 53:         $this->settings['db']['password'] = '';
 54:         $this->settings['db']['charset'] = 'utf8';
 55:         $this->settings['db']['collation'] = 'utf8_general_ci';
 56:         $this->settings['db']['database'] = 'contenido';
 57:         $this->settings['db']['prefix'] = 'con';
 58: 
 59:         $this->settings['paths']['http_root_path'] = '';
 60: 
 61:         $this->settings['setup']['client_mode'] = '';
 62: 
 63:         $this->settings['admin_user']['password'] = '';
 64:         $this->settings['admin_user']['email'] = '';
 65: 
 66:         $this->args = $args;
 67: 
 68:         $this->args['interactive'] = isset($this->args['interactive']) || isset($this->args['i']); 
 69: 
 70:         
 71:         $this->settingsFile = 'autoinstall.ini';
 72:     }
 73: 
 74:      75:  76: 
 77:     public function interpretCommandline() {
 78:         global $belang;
 79: 
 80:         $belang = ($this->args['locale']) ? $this->args['locale'] : "en_US"; 
 81: 
 82:         cI18n::init(CON_SETUP_PATH . '/locale/', $belang, 'setup');
 83: 
 84:         
 85:         if (isset($this->args['h']) || $this->args['help']) {
 86:             printHelpText();
 87:             exit(0);
 88:         }
 89: 
 90:         
 91:         if (isset($this->args['file'])) {
 92:             $this->settingsFile = $this->args['file'];
 93:         }
 94: 
 95:         prntln("\r" . i18n('This program will install CONTENIDO on this computer.', 'setup'));
 96: 
 97:         
 98:         if ($this->args['interactive']) {
 99:             
100:             prntln();
101:             prntln();
102:             
103:             
104:             $this->getSettingsFromFile($this->settingsFile);
105:             $this->getSettingsFromCommandLine($this->args);
106:             $this->getUserInputSettings();
107:         } else if ($this->args['noninteractive']) {
108:             
109:             echo(i18n('Looking for ', 'setup') . $this->settingsFile . '...');
110:             if (file_exists($this->settingsFile)) {
111:                 
112:                 prntln(i18n('found', 'setup'));
113:                 prntln(i18n('CONTENIDO will use the specified settings from ', 'setup') . $this->settingsFile);
114:                 prntln();
115:                 $this->getSettingsFromFile($this->settingsFile);
116:                 $this->getSettingsFromCommandLine($this->args);
117:                 $this->printSettings();
118:             } else {
119:                 
120:                 prntln(i18n('not found', 'setup'));
121:                 prntln(sprintf(i18n('CONTENIDO was unable to locate the configuration file %s, but you asked to use it.', 'setup'), $this->settingsFile));
122:                 prntln(i18n('Setup can not continue.', 'setup'));
123:                 exit(1);
124:             }
125:         } else {
126:             
127:             echo(i18n('Looking for ', 'setup') . $this->settingsFile . '...');
128:             if (file_exists($this->settingsFile)) {
129:                 
130:                 prntln(i18n('found', 'setup'));
131:                 prntln(i18n('CONTENIDO will use the specified settings from ', 'setup') . $this->settingsFile);
132:                 prntln();
133:                 $this->getSettingsFromFile($this->settingsFile);
134:                 $this->getSettingsFromCommandLine($this->args);
135:                 $this->printSettings();
136:             } else {
137:                 
138:                 prntln(i18n('not found', 'setup'));
139:                 prntln();
140:                 prntln();
141:                 $this->getSettingsFromFile($this->settingsFile);
142:                 $this->getSettingsFromCommandLine($this->args);
143:                 $this->getUserInputSettings();
144:             }
145:         }
146:     }
147: 
148:     149: 150: 
151:     public function printSettings() {
152:         prntln(i18n('CONTENIDO will be installed with the following settings: ', 'setup'));
153:         $noPasswordArray = $this->settings;
154:         $noPasswordArray['db']['password'] = '**********';
155:         $noPasswordArray['admin_user']['password'] =  '**********';
156:         prntln(json_encode($noPasswordArray));
157:     }
158: 
159:     160: 161: 162: 163: 
164:     public function getSettingsFromCommandLine() {
165:         $this->settings['db']['host'] = ($this->args['dbhost'] == '') ? $this->settings['db']['host'] : $this->args['dbhost'];
166:         $this->settings['db']['user'] = ($this->args['dbuser'] == '') ? $this->settings['db']['user'] : $this->args['dbuser'];
167:         $this->settings['db']['password'] = ($this->args['dbpassword'] == '') ? $this->settings['db']['password'] : $this->args['dbpassword'];
168:         $this->settings['db']['charset'] = ($this->args['dbcharset'] == '') ? $this->settings['db']['charset'] : $this->args['dbcharset'];
169:         $this->settings['db']['collation'] = ($this->args['dbcollation'] == '') ? $this->settings['db']['collation'] : $this->args['dbcollation'];
170:         $this->settings['db']['database'] = ($this->args['dbdatabase'] == '') ? $this->settings['db']['database'] : $this->args['dbdatabase'];
171:         $this->settings['db']['prefix'] = ($this->args['dbprefix'] == '') ? $this->settings['db']['prefix'] : $this->args['dbprefix'];
172: 
173:         $this->settings['paths']['http_root_path'] = ($this->args['pathshttprootpath'] == '') ? $this->settings['paths']['http_root_path'] : $this->args['pathshttprootpath'];
174: 
175:         $this->settings['setup']['client_mode'] = ($this->args['setupclientmode'] == '') ? $this->settings['setup']['client_mode'] : $this->args['setupclientmode'];
176: 
177:         $this->settings['admin_user']['password'] = ($this->args['adminuserpassword'] == '') ? $this->settings['admin_user']['password'] : $this->args['adminuserpassword'];
178:         $this->settings['admin_user']['email'] = ($this->args['adminuseremail'] == '') ? $this->settings['admin_user']['email'] : $this->args['adminuseremail'];
179:         $this->settings['advanced']['delete_database'] = ($this->args['advanceddeletedatabase'] == '') ? $this->settings['advanced']['delete_database'] : $this->args['advanceddeletedatabase'];
180:     }
181: 
182:     183: 184: 
185:     public function getUserInputSettings() {
186:         $settings = array();
187: 
188:         
189:         prntln('>>>>> '. i18n('Welcome to CONTENIDO', 'setup'). ' <<<<<');
190:         prntln('');
191:         prntln(i18n('Database settings:', 'setup'));
192: 
193:         
194:         prnt(i18n('Host', 'setup') . ' [' . $this->settings['db']['host'] . ']: ', 1);
195:         $line = trim(fgets(STDIN));
196:         $this->settings['db']['host'] = ($line == "") ? $this->settings['db']['host'] : $line;
197: 
198:         
199:         prnt(i18n('User', 'setup') . ' [' . $this->settings['db']['user'] . ']: ', 1);
200:         $line = trim(fgets(STDIN));
201:         $this->settings['db']['user'] = ($line == "") ? $this->settings['db']['user'] : $line;
202: 
203:         
204:         $dbpw = passwordPrompt(i18n('Password', 'setup'), 1);
205:         $this->settings['db']['password'] = ($dbpw == '') ? $this->settings['db']['password'] : $dbpw;
206: 
207:         
208:         prnt(i18n('Database name', 'setup') .' [' . $this->settings['db']['database'] . ']: ', 1);
209:         $line = trim(fgets(STDIN));
210:         $this->settings['db']['database'] = ($line == "") ? $this->settings['db']['database'] : $line;
211: 
212:         
213:         prnt(i18n('Charset', 'setup') . ' [' . $this->settings['db']['charset'] . ']: ', 1);
214:         $line = trim(fgets(STDIN));
215:         $this->settings['db']['charset'] = ($line == "") ? $this->settings['db']['charset'] : $line;
216: 
217:         
218:         prnt(i18n('Collation', 'setup') . ' [' . $this->settings['db']['collation'] . ']: ', 1);
219:         $line = trim(fgets(STDIN));
220:         $this->settings['db']['collation'] = ($line == "") ? $this->settings['db']['collation'] : $line;
221: 
222:         
223:         prnt(i18n('Prefix', 'setup') . ' [' . $this->settings['db']['prefix'] . ']: ', 1);
224:         $line = trim(fgets(STDIN));
225:         $this->settings['db']['prefix'] = ($line == "") ? $this->settings['db']['prefix'] : $line;
226: 
227:         
228:         prntln();
229:         prntln(i18n('Please enter the http path to where the contenido/ folder resides', 'setup'));
230:         prntln(i18n('e.g. http://localhost/', 'setup'));
231:         prnt(i18n('Backend web path', 'setup') .' [' . $this->settings['paths']['http_root_path'] . ']: ', 1);
232:         $line = trim(fgets(STDIN));
233:         $this->settings['paths']['http_root_path'] = ($line == "") ? $this->settings['paths']['http_root_path'] : $line;
234: 
235:         
236:         prntln();
237:         $displayStandard = i18n('yes', 'setup');
238:         if ($this->settings['setup']['client_mode'] == 'CLIENTMODULES') {
239:             $displayStandard = i18n('modules', 'setup');
240:         } else if ($this->settings['setup']['client_mode'] == 'NOCLIENT') {
241:             $displayStandard = i18n('no', 'setup');
242:         }
243:         $first = true;
244:         while ($this->settings['setup']['client_mode'] == "" || $first) {
245:             $first = false;
246:             prntln(i18n('Do you want to install the example client?', 'setup'));
247:             prntln(i18n('Please choose "yes" (to install the modules AND the content), "modules" (to install only the modules) or "no"', 'setup'));
248:             prnt(i18n('Examples? (yes/modules/no)', 'setup') . '[' . $displayStandard . ']: ', 1);
249:             $line = strtolower(trim(fgets(STDIN)));
250:             if ($line == "") {
251:                 $line = $displayStandard;
252:             }
253:             if ($line == 'yes' || $line == i18n('yes', 'setup')) {
254:                 $this->settings['setup']['client_mode'] = 'CLIENTEXAMPLES';
255:             } else if ($line == 'modules' || $line == i18n('modules', 'setup')) {
256:                 $this->settings['setup']['client_mode'] = 'CLIENTMODULES';
257:             } else if ($line == 'no' || $line == i18n('no', 'setup')) {
258:                 $this->settings['setup']['client_mode'] = 'NOCLIENT';
259:             }
260:         }
261: 
262:         
263:         $password1 = "something";
264:         $password2 = "something else";
265:         prntln();
266:         prntln(i18n('Admin information:'));
267:         while ($password1 != $password2) {
268:             prntln(i18n('You have to enter the password twice and they have to match', 'setup'), 1);
269:             $password1 = passwordPrompt(i18n('Admin password', 'setup'), 1);
270: 
271:             $password2 = passwordPrompt(i18n('Repeat admin password', 'setup'), 1);
272:         }
273:         $this->settings['admin_user']['password'] = ($password1 == '') ? $this->settings['admin_user']['password'] : $password1;
274: 
275:         
276:         prnt(i18n('Admin email', 'setup') . ' [' . $this->settings['admin_user']['email'] . ']: ', 1);
277:         $line = trim(fgets(STDIN));
278:         $this->settings['admin_user']['email'] = ($line == "") ? $this->settings['admin_user']['email'] : $line;
279: 
280:         
281:         prntln(i18n('Thank you.', 'setup'));
282:         prntln();
283:         prntln();
284:     }
285: 
286:     287: 288: 289: 290: 
291:     public function getSettingsFromFile($file) {
292:         if (!cFileHandler::exists($file)) {
293:             return;
294:         }
295: 
296:         $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
297: 
298:         switch ($ext) {
299:             case 'ini':
300:                 $this->settings = parse_ini_file($file, true);
301:                 break;
302:             case 'xml':
303:                 $xml = simplexml_load_file($file);
304:                 if (!$xml) {
305:                     return;
306:                 }
307: 
308:                 $this->settings['db']['host'] = trim($xml->db->host);
309:                 $this->settings['db']['user'] = trim($xml->db->user);
310:                 $this->settings['db']['password'] = trim($xml->db->password);
311:                 $this->settings['db']['charset'] = trim($xml->db->charset);
312:                 $this->settings['db']['database'] = trim($xml->db->database);
313:                 $this->settings['db']['prefix'] = trim($xml->db->prefix);
314:                 $this->settings['db']['collation'] = trim($xml->db->collation);
315: 
316:                 $this->settings['paths']['http_root_path'] = trim($xml->path->http_root_path);
317: 
318:                 $this->settings['setup']['client_mode'] = trim($xml->client->client_mode);
319: 
320:                 $this->settings['admin_user']['password'] = trim($xml->admin_user->password);
321:                 $this->settings['admin_user']['email'] = trim($xml->admin_user->email);
322:                 $this->settings['advanced']['delete_database'] = trim($xml->advanced->delete_database);
323:                 break;
324:             case 'json':
325:                 $this->settings = json_decode(file_get_contents($file), true);
326:                 break;
327:         }
328: 
329:     }
330: 
331:     332: 333: 334: 335: 336: 
337:     public function executeSystemTests() {
338:         global $cfg, $args;
339: 
340:         if ($this->settings['advanced']['delete_database'] == '1' || $this->settings['advanced']['delete_database'] == 'YES') {
341:             $answer = '';
342:             while ($answer != 'Y' && $answer != 'N') {
343:                 prnt(sprintf(i18n("You chose in the configuration file to delete the database '%s' before installing.\nDO YOU REALLY WANT TO CONTINUE WITH DELETING THIS DATABASE? (Y/N) [N]: ", 'setup'), $this->settings['db']['database']));
344:                 $answer = trim(fgets(STDIN));
345:                 if ($answer == "") {
346:                     $answer = "N";
347:                 }
348:             }
349:             if ($answer != "Y") {
350:                 exit(3);
351:             }
352: 
353:             $db = getSetupMySQLDBConnection(false);
354:             $db->query('DROP DATABASE ' . $this->settings['db']['database']);
355: 
356:             prntln();
357:             prntln(sprintf(i18n('THE DATABASE %s HAS BEEN DELETED!!!', 'setup'), $this->settings['db']['database']));
358:             prntln();
359:         }
360: 
361:         prnt(i18n('Testing your system...', 'setup'));
362: 
363:         $fine = true;
364: 
365:         
366:         i18nInit('../data/locale/', $belang);
367: 
368:         
369:         $test = new cSystemtest($cfg);
370:         $test->runTests(false); 
371:         $test->testFilesystem(true, false); 
372:         $test->testFrontendFolderCreation(); 
373:         $test->checkSetupMysql('setup', $cfg['db']['connection']['database'], $_SESSION['dbprefix'], $_SESSION['dbcharset'], $_SESSION['dbcollation']); 
374: 
375:         $testResults = $test->getResults();
376: 
377:         foreach ($testResults as $testResult) {
378:             if ($testResult["severity"] == cSystemtest::C_SEVERITY_NONE) {
379:                 continue;
380:             }
381: 
382:             if ($testResult['result'] == false) {
383:                 $fine = false;
384:             }
385:         }
386:         if (!$fine) {
387:             prntln(i18n('error', 'setup'));
388:             foreach ($testResults as $testResult) {
389:                 if ($testResult["severity"] == cSystemtest::C_SEVERITY_NONE) {
390:                     continue;
391:                 }
392: 
393:                 if ($testResult['result'] == false) {
394:                     prntln(html_entity_decode(strip_tags($testResult['headline'], 1)));
395:                     prntln(html_entity_decode(strip_tags($testResult['message'], 2)));
396:                 }
397:             }
398:             prntln();
399:             prntln(i18n('There have been errors during the system check.', 'setup'));
400:             prntln(i18n('However this might be caused by differing configurations between the CLI php and the CGI php.', 'setup'));
401: 
402:             if ($args['noninteractive']) {
403:                 exit(3);
404:             }
405: 
406:             $answer = '';
407:             while ($answer != 'y' && $answer != 'n' && $answer != i18n('y', 'setup') && $answer != i18n('n', 'setup')) {
408:                 prnt(i18n('Do you want to continue despite the errors? (y/n) [n]: ', 'setup'));
409:                 $answer = trim(fgets(STDIN));
410:                 if ($answer == "") {
411:                     $answer = "n";
412:                 }
413:             }
414:             if (strtolower($answer) == "n" || strtolower($answer) == strtolower(i18n('n', 'setup'))) {
415:                 exit(3);
416:             }
417:         } else {
418:             prntln(i18n('Your system seems to be okay.', 'setup'));
419:             prntln();
420:         }
421:     }
422: 
423:     424: 425: 
426:     public function applySettings() {
427:         global $cfg, $_SESSION;
428: 
429:         $cfg['db'] = array(
430:             'connection' => array(
431:                 'host'     => $this->settings['db']['host'],
432:                 'user'     => $this->settings['db']['user'],
433:                 'password' => $this->settings['db']['password'],
434:                 'charset'  => $this->settings['db']['charset'],
435:                 'database' => $this->settings['db']['database']
436:             ),
437:             'haltBehavior'    => 'report',
438:             'haltMsgPrefix'   => (isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] . ' ' : '',
439:             'enableProfiling' => false
440:         );
441:         $_SESSION['setuptype'] = 'setup';
442:         $_SESSION['dbname'] = $this->settings['db']['database'];
443:         $_SESSION['configmode'] = 'save';
444:         $_SESSION['override_root_http_path'] = $this->settings['paths']['http_root_path'];
445:         $_SESSION['clientmode'] = $this->settings['setup']['client_mode'];
446:         $_SESSION['adminpass'] = $this->settings['admin_user']['password'];
447:         $_SESSION['adminmail'] = $this->settings['admin_user']['email'];
448:         $_SESSION['dbprefix'] = $this->settings['db']['prefix'];
449:         $_SESSION['dbcollation'] = $this->settings['db']['collation'];
450:         $_SESSION['dbcharset'] = $this->settings['db']['charset'];
451:         $cfg['sql']['sqlprefix'] = $this->settings['db']['prefix'];
452:     }
453: }
454: