]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Core/Install.php
13ead0ef0e09c149b8a8d644bf6d98251b5f3a99
[galette.git] / galette / lib / Galette / Core / Install.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Galette installation
7 *
8 * PHP version 5
9 *
10 * Copyright © 2013-2014 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Core
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2013-2014 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.8 - 2013-01-09
35 */
36
37 namespace Galette\Core;
38
39 use Analog\Analog;
40 use Laminas\Db\Adapter\Adapter;
41
42 /**
43 * Galette installation
44 *
45 * @category Core
46 * @name Install
47 * @package Galette
48 * @author Johan Cwiklinski <johan@x-tnd.be>
49 * @copyright 2013-2014 The Galette Team
50 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
51 * @link http://galette.tuxfamily.org
52 * @since Available since 0.8 - 2013-01-09
53 */
54 class Install
55 {
56 const STEP_CHECK = 0;
57 const STEP_TYPE = 1;
58 const STEP_DB = 2;
59 const STEP_DB_CHECKS = 3;
60 const STEP_VERSION = 4; //only for update
61 const STEP_DB_UPGRADE = 5;
62 const STEP_DB_INSTALL = 6;
63 const STEP_ADMIN = 7;
64 const STEP_GALETTE_INIT = 8;
65 const STEP_END = 9;
66
67 const INSTALL = 'i';
68 const UPDATE = 'u';
69
70 //db version/galette version mapper
71 private $versions_mapper = array(
72 '0.700' => '0.70',
73 '0.701' => '0.71',
74 '0.702' => '0.74',
75 '0.703' => '0.75',
76 '0.704' => '0.76'
77 );
78
79 private $_step;
80 private $_mode;
81 private $_version;
82 private $_installed_version;
83
84 private $_db_type;
85 private $_db_host;
86 private $_db_port;
87 private $_db_name;
88 private $_db_user;
89 private $_db_pass;
90
91 private $_db_connected;
92 private $_report;
93
94 private $_admin_login;
95 private $_admin_pass;
96
97 private $_error;
98
99 /**
100 * Main constructor
101 */
102 public function __construct()
103 {
104 $this->_step = self::STEP_CHECK;
105 $this->_mode = null;
106 $this->_version = str_replace('v', '', GALETTE_VERSION);
107 $this->_db_connected = false;
108 $this->_db_prefix = null;
109 }
110
111 /**
112 * Return current step title
113 *
114 * @return string
115 */
116 public function getStepTitle()
117 {
118 $step_title = null;
119 switch ($this->_step) {
120 case self::STEP_CHECK:
121 $step_title = _T("Checks");
122 break;
123 case self::STEP_TYPE:
124 $step_title = _T("Installation mode");
125 break;
126 case self::STEP_DB:
127 $step_title = _T("Database");
128 break;
129 case self::STEP_DB_CHECKS:
130 $step_title = _T("Database access and permissions");
131 break;
132 case self::STEP_VERSION:
133 $step_title = _T("Previous version selection");
134 break;
135 case self::STEP_DB_UPGRADE:
136 $step_title = _T("Datapase upgrade");
137 break;
138 case self::STEP_DB_INSTALL:
139 $step_title = _T("Tables Creation");
140 break;
141 case self::STEP_ADMIN:
142 $step_title = _T("Admin parameters");
143 break;
144 case self::STEP_GALETTE_INIT:
145 $step_title = _T("Galette initialization");
146 break;
147 case self::STEP_END:
148 $step_title = _T("End!");
149 break;
150 }
151 return $step_title;
152 }
153
154 /**
155 * HTML validation image
156 *
157 * @param boolean $arg Argument
158 *
159 * @return html string
160 */
161 public function getValidationImage($arg)
162 {
163 $img_name = ($arg === true) ? 'valid' : 'invalid';
164 $src = GALETTE_THEME_DIR . 'images/icon-' . $img_name . '.png';
165 $alt = ($arg === true) ? _T("Ok") : _T("Ko");
166 $img = '<img src="' . $src . '" alt="' . $alt . '"/>';
167 return $img;
168 }
169
170 /**
171 * Get current mode
172 *
173 * @return char
174 */
175 public function getMode()
176 {
177 return $this->_mode;
178 }
179
180 /**
181 * Are we installing?
182 *
183 * @return boolean
184 */
185 public function isInstall()
186 {
187 return $this->_mode === self::INSTALL;
188 }
189
190 /**
191 * Are we upgrading?
192 *
193 * @return boolean
194 */
195 public function isUpgrade()
196 {
197 return $this->_mode === self::UPDATE;
198 }
199
200 /**
201 * Set installation mode
202 *
203 * @param char $mode Requested mode
204 *
205 * @return void
206 */
207 public function setMode($mode)
208 {
209 if ($mode === self::INSTALL || $mode === self::UPDATE) {
210 $this->_mode = $mode;
211 } else {
212 throw new \UnexpectedValueException('Unknown mode "' . $mode . '"');
213 }
214 }
215
216 /**
217 * Go back to previous step
218 *
219 * @return void
220 */
221 public function atPreviousStep()
222 {
223 if ($this->_step > 0) {
224 if (
225 $this->_step - 1 !== self::STEP_DB_INSTALL
226 && $this->_step !== self::STEP_END
227 ) {
228 if ($this->_step === self::STEP_DB_INSTALL) {
229 $this->_step = self::STEP_DB_CHECKS;
230 } else {
231 if ($this->_step === self::STEP_DB_UPGRADE) {
232 $this->setInstalledVersion(null);
233 }
234 $this->_step = $this->_step - 1;
235 }
236 } else {
237 $msg = null;
238 if ($this->_step === self::STEP_END) {
239 $msg = 'Ok man, install is finished already!';
240 } else {
241 $msg = 'It is forbidden to rerun database install!';
242 }
243 Analog::log($msg, Analog::WARNING);
244 }
245 }
246 }
247
248 /**
249 * Are we at check step?
250 *
251 * @return boolean
252 */
253 public function isCheckStep()
254 {
255 return $this->_step === self::STEP_CHECK;
256 }
257
258 /**
259 * Set step to type of installation
260 *
261 * @return void
262 */
263 public function atTypeStep()
264 {
265 $this->_step = self::STEP_TYPE;
266 }
267
268 /**
269 * Are we at type step?
270 *
271 * @return boolean
272 */
273 public function isTypeStep()
274 {
275 return $this->_step === self::STEP_TYPE;
276 }
277
278 /**
279 * Set step to database information
280 *
281 * @return void
282 */
283 public function atDbStep()
284 {
285 $this->_step = self::STEP_DB;
286 }
287
288 /**
289 * Are we at database step?
290 *
291 * @return boolean
292 */
293 public function isDbStep()
294 {
295 return $this->_step === self::STEP_DB;
296 }
297
298 /**
299 * Is DB step passed?
300 *
301 * @return boolean
302 */
303 public function postCheckDb()
304 {
305 return $this->_step > self::STEP_DB_CHECKS;
306 }
307
308 /**
309 * Set database type
310 *
311 * @param string $type Database type
312 * @param array $errs Errors array
313 *
314 * @return boolean
315 */
316 public function setDbType($type, &$errs)
317 {
318 switch ($type) {
319 case Db::MYSQL:
320 case Db::PGSQL:
321 $this->_db_type = $type;
322 break;
323 default:
324 $errs[] = _T("Database type unknown");
325 }
326 }
327
328 /**
329 * Get database type
330 *
331 * @return string
332 */
333 public function getDbType()
334 {
335 return $this->_db_type;
336 }
337
338 /**
339 * Set connection information
340 *
341 * @param string $host Database host
342 * @param string $port Database port
343 * @param string $name Database name
344 * @param string $user Database user name
345 * @param string $pass Database user's password
346 *
347 * @return void
348 */
349 public function setDsn($host, $port, $name, $user, $pass)
350 {
351 $this->_db_host = $host;
352 $this->_db_port = $port;
353 $this->_db_name = $name;
354 $this->_db_user = $user;
355 $this->_db_pass = $pass;
356 }
357
358 /**
359 * Set tables prefix
360 *
361 * @param string $prefix Prefix
362 *
363 * @return void
364 */
365 public function setTablesPrefix($prefix)
366 {
367 $this->_db_prefix = $prefix;
368 }
369
370 /**
371 * Retrieve database host
372 *
373 * @return string
374 */
375 public function getDbHost()
376 {
377 return $this->_db_host;
378 }
379
380 /**
381 * Retrieve database port
382 *
383 * @return string
384 */
385 public function getDbPort()
386 {
387 return $this->_db_port;
388 }
389
390 /**
391 * Retrieve database name
392 *
393 * @return string
394 */
395 public function getDbName()
396 {
397 return $this->_db_name;
398 }
399
400 /**
401 * Retrieve database user
402 *
403 * @return string
404 */
405 public function getDbUser()
406 {
407 return $this->_db_user;
408 }
409
410 /**
411 * Retrieve database password
412 *
413 * @return string
414 */
415 public function getDbPass()
416 {
417 return $this->_db_pass;
418 }
419
420 /**
421 * Retrieve tables prefix
422 *
423 * @return string
424 */
425 public function getTablesPrefix()
426 {
427 return $this->_db_prefix;
428 }
429
430 /**
431 * Set step to database checks
432 *
433 * @return void
434 */
435 public function atDbCheckStep()
436 {
437 $this->_step = self::STEP_DB_CHECKS;
438 }
439
440 /**
441 * Are we at database check step?
442 *
443 * @return boolean
444 */
445 public function isDbCheckStep()
446 {
447 return $this->_step === self::STEP_DB_CHECKS;
448 }
449
450 /**
451 * Test database connection
452 *
453 * @return true|array true if connection was successfull,
454 * an array with some infos otherwise
455 */
456 public function testDbConnexion()
457 {
458 return Db::testConnectivity(
459 $this->_db_type,
460 $this->_db_user,
461 $this->_db_pass,
462 $this->_db_host,
463 $this->_db_port,
464 $this->_db_name
465 );
466 }
467
468 /**
469 * Is database connexion ok?
470 *
471 * @return boolean
472 */
473 public function isDbConnected()
474 {
475 return $this->_db_connected;
476 }
477
478 /**
479 * Set step to version selection
480 *
481 * @return void
482 */
483 public function atVersionSelection()
484 {
485 $this->_step = self::STEP_VERSION;
486 }
487
488 /**
489 * Are we at version selection step?
490 *
491 * @return boolean
492 */
493 public function isVersionSelectionStep()
494 {
495 return $this->_step === self::STEP_VERSION;
496 }
497
498 /**
499 * Set step to database installation
500 *
501 * @return void
502 */
503 public function atDbInstallStep()
504 {
505 $this->_step = self::STEP_DB_INSTALL;
506 }
507
508 /**
509 * Are we at db installation step?
510 *
511 * @return boolean
512 */
513 public function isDbinstallStep()
514 {
515 return $this->_step === self::STEP_DB_INSTALL;
516 }
517
518 /**
519 * Set step to database upgrade
520 *
521 * @return void
522 */
523 public function atDbUpgradeStep()
524 {
525 $this->_step = self::STEP_DB_UPGRADE;
526 }
527
528 /**
529 * Are we at db upgrade step?
530 *
531 * @return boolean
532 */
533 public function isDbUpgradeStep()
534 {
535 return $this->_step === self::STEP_DB_UPGRADE;
536 }
537
538
539 /**
540 * Install/Update SQL scripts
541 *
542 * @param string $path Path to scripts (defaults to core scripts)
543 *
544 * @return array
545 */
546 public function getScripts($path = null)
547 {
548 if ($path === null) {
549 $path = GALETTE_ROOT . '/install';
550 }
551 $update_scripts = array();
552
553 if ($this->isUpgrade()) {
554 $update_scripts = self::getUpdateScripts(
555 $path,
556 $this->_db_type,
557 $this->_installed_version
558 );
559 } else {
560 $update_scripts['current'] = $this->_db_type . '.sql';
561 }
562
563 return $update_scripts;
564 }
565
566 /**
567 * List updates scripts from given path
568 *
569 * @param string $path Scripts path
570 * @param string $db_type Database type
571 * @param string $version Previous version, defaults to null
572 *
573 * @return array If a previous version is provided, update scripts
574 * file path from this one to the latest will be returned.
575 * If no previous version is provided, that will return all
576 * updates versions known.
577 */
578 public static function getUpdateScripts(
579 $path,
580 $db_type = 'mysql',
581 $version = null
582 ) {
583 $dh = opendir($path . '/scripts');
584 $php_update_scripts = array();
585 $sql_update_scripts = array();
586 if ($dh !== false) {
587 while (($file = readdir($dh)) !== false) {
588 if (preg_match("/upgrade-to-(.*).php/", $file, $ver)) {
589 if ($version === null) {
590 $php_update_scripts[$ver[1]] = $ver[1];
591 } else {
592 if ($version <= $ver[1]) {
593 $php_update_scripts[$ver[1]] = $file;
594 }
595 }
596 }
597 if (
598 preg_match(
599 "/upgrade-to-(.*)-" . $db_type . ".sql/",
600 $file,
601 $ver
602 )
603 ) {
604 if ($version === null) {
605 $sql_update_scripts[$ver[1]] = $ver[1];
606 } else {
607 if ($version <= $ver[1]) {
608 $sql_update_scripts[$ver[1]] = $file;
609 }
610 }
611 }
612 }
613 $update_scripts = array_merge($sql_update_scripts, $php_update_scripts);
614 closedir($dh);
615 ksort($update_scripts);
616 }
617 return $update_scripts;
618 }
619
620 /**
621 * Execute SQL scripts
622 *
623 * @param Galette\Core\Db $zdb Database instance
624 *
625 * @return boolean
626 */
627 public function executeScripts($zdb)
628 {
629 $queries_results = array();
630 $fatal_error = false;
631 $update_scripts = $this->getScripts();
632 $sql_query = '';
633 $this->_report = array();
634 $scripts_path = GALETTE_ROOT . '/install/scripts/';
635
636 foreach ($update_scripts as $key => $val) {
637 if (substr($val, -strlen('.sql')) === '.sql') {
638 //just a SQL script, run it
639 $script = fopen($scripts_path . $val, 'r');
640
641 if ($script === false) {
642 throw new \RuntimeException(
643 'Unable to read SQL script from ' . $scripts_path . $val
644 );
645 }
646
647 $sql_query .= @fread(
648 $script,
649 @filesize($scripts_path . $val)
650 ) . "\n";
651 } else {
652 //we got an update class
653 include_once $scripts_path . $val;
654 $className = '\Galette\Updates\UpgradeTo' .
655 str_replace('.', '', $key);
656 $ret = array(
657 'message' => null,
658 'res' => false
659 );
660 try {
661 $updater = new $className();
662 if ($updater instanceof \Galette\Updater\AbstractUpdater) {
663 $updater->run($zdb, $this);
664 $ret = $updater->getReport();
665 $this->_report = array_merge($this->_report, $ret);
666 } else {
667 $fatal_error = true;
668 Analog::log(
669 'Update class does not extends AbstractUpdater!',
670 Analog::ERROR
671 );
672 }
673
674 $ret['message'] = str_replace(
675 '%version',
676 $key,
677 _T("%version script has been successfully executed :)")
678 );
679 $ret['res'] = true;
680 $this->_report[] = $ret;
681 } catch (\RuntimeException $e) {
682 Analog::log(
683 $e->getMessage(),
684 Analog::ERROR
685 );
686 $ret['message'] = str_replace(
687 '%version',
688 $key,
689 _T("Unable to run %version update script :(")
690 );
691 $fatal_error = true;
692 $this->_report[] = $ret;
693 }
694 }
695 }
696
697 if ($sql_query !== '') {
698 $sql_res = $this->executeSql($zdb, $sql_query);
699 $fatal_error = !$sql_res;
700 }
701 return !$fatal_error;
702 }
703
704 /**
705 * Executes SQL queries
706 *
707 * @param Db $zdb Database instance
708 * @param string $sql_query SQL instructions
709 *
710 * @return boolean;
711 */
712 public function executeSql($zdb, $sql_query)
713 {
714 $fatal_error = false;
715
716 // begin : copyright (2002) the phpbb group (support@phpbb.com)
717 // load in the sql parser
718 include_once GALETTE_ROOT . 'includes/sql_parse.php';
719
720 $sql_query = preg_replace('/galette_/', $this->_db_prefix, $sql_query);
721 $sql_query = remove_remarks($sql_query);
722
723 $sql_query = split_sql_file($sql_query, ';');
724
725 $zdb->connection->beginTransaction();
726
727 for ($i = 0; $i < sizeof($sql_query); $i++) {
728 $query = trim($sql_query[$i]);
729 if ($query != '' && $query[0] != '-') {
730 //some output infos
731 $ret = array(
732 'message' => $query,
733 'res' => false
734 );
735
736 try {
737 $zdb->db->query(
738 $query,
739 Adapter::QUERY_MODE_EXECUTE
740 );
741 $ret['res'] = true;
742 } catch (\Exception $e) {
743 $log_lvl = Analog::WARNING;
744 //if error are on drop, DROP, rename or RENAME we can continue
745 $parts = explode(' ', $query, 1);
746 if (
747 (strcasecmp(trim($parts[0]), 'drop') != 0)
748 && (strcasecmp(trim($parts[0]), 'rename') != 0)
749 ) {
750 $log_lvl = Analog::ERROR;
751 $ret['debug'] = $e->getMessage();
752 $ret['query'] = $query;
753 $ret['res'] = false;
754 $fatal_error = true;
755 } else {
756 $ret['res'] = true;
757 }
758 Analog::log(
759 'Error executing query | ' . $e->getMessage(),
760 $log_lvl
761 );
762 }
763
764 $queries_results[] = $ret;
765 }
766 }
767
768 if ($fatal_error) {
769 $zdb->connection->rollBack();
770 } else {
771 $zdb->connection->commit();
772 }
773
774 $this->_report = array_merge($this->_report, $queries_results);
775 return !$fatal_error;
776 }
777
778 /**
779 * Retrieve database installation report
780 *
781 * @return array
782 */
783 public function getDbInstallReport()
784 {
785 return $this->_report;
786 }
787
788 /**
789 * Reinitialize report array
790 *
791 * @return void
792 */
793 public function reinitReport()
794 {
795 $this->_report = array();
796 }
797
798 /**
799 * Set step to super admin information
800 *
801 * @return void
802 */
803 public function atAdminStep()
804 {
805 $this->_step = self::STEP_ADMIN;
806 }
807
808 /**
809 * Are we at super admin information step?
810 *
811 * @return boolean
812 */
813 public function isAdminStep()
814 {
815 return $this->_step === self::STEP_ADMIN;
816 }
817
818 /**
819 * Set super administrator information
820 *
821 * @param string $login Login
822 * @param string $pass Password
823 *
824 * @return void
825 */
826 public function setAdminInfos($login, $pass)
827 {
828 $this->_admin_login = $login;
829 $this->_admin_pass = password_hash($pass, PASSWORD_BCRYPT);
830 }
831
832 /**
833 * Retrieve super admin login
834 *
835 * @return string
836 */
837 public function getAdminLogin()
838 {
839 return $this->_admin_login;
840 }
841
842 /**
843 * Retrieve super admin password
844 *
845 * @return string
846 */
847 public function getAdminPass()
848 {
849 return $this->_admin_pass;
850 }
851
852 /**
853 * Set step to Galette initialization
854 *
855 * @return void
856 */
857 public function atGaletteInitStep()
858 {
859 $this->_step = self::STEP_GALETTE_INIT;
860 }
861
862 /**
863 * Are we at Galette initialization step?
864 *
865 * @return boolean
866 */
867 public function isGaletteInitStep()
868 {
869 return $this->_step === self::STEP_GALETTE_INIT;
870 }
871
872 /**
873 * Load existing config
874 *
875 * @param array $post_data Data posted
876 * @param array $error_detected Errors array
877 *
878 * @return void
879 */
880 public function loadExistingConfig($post_data, &$error_detected)
881 {
882 if (file_exists(GALETTE_CONFIG_PATH . 'config.inc.php')) {
883 $existing = $this->loadExistingConfigFile($post_data);
884
885 if ($existing['db_type'] !== null) {
886 $this->setDbType($existing['db_type'], $error_detected);
887 }
888
889 if (
890 $existing['db_host'] !== null
891 || $existing['db_user'] !== null
892 || $existing['db_name'] !== null
893 ) {
894 $this->setDsn(
895 $existing['db_host'],
896 $existing['db_port'],
897 $existing['db_name'],
898 $existing['db_user'],
899 null
900 );
901 }
902
903 if ($existing['prefix'] !== null) {
904 $this->setTablesPrefix(
905 $existing['prefix']
906 );
907 }
908 }
909 }
910
911 /**
912 * Load contents from existing config file
913 *
914 * @param array $post_data Data posted
915 * @param boolean $pass Retrieve password
916 *
917 * @return array
918 */
919 private function loadExistingConfigFile($post_data = array(), $pass = false)
920 {
921 $existing = array(
922 'db_type' => null,
923 'db_host' => null,
924 'db_port' => null,
925 'db_user' => null,
926 'db_name' => null,
927 'prefix' => null
928 );
929
930 if (file_exists(GALETTE_CONFIG_PATH . 'config.inc.php')) {
931 $conf = file_get_contents(GALETTE_CONFIG_PATH . 'config.inc.php');
932 if ($conf !== false) {
933 if (!isset($post_data['install_dbtype'])) {
934 $res = preg_match(
935 '/TYPE_DB["\'], ["\'](.*)["\']\);/',
936 $conf,
937 $matches
938 );
939 if (isset($matches[1])) {
940 $existing['db_type'] = $matches[1];
941 }
942 }
943 if (!isset($post_data['install_dbhost'])) {
944 $res = preg_match(
945 '/HOST_DB["\'], ["\'](.*)["\']\);/',
946 $conf,
947 $matches
948 );
949 if (isset($matches[1])) {
950 $existing['db_host'] = $matches[1];
951 }
952 }
953 if (!isset($post_data['install_dbport'])) {
954 $res = preg_match(
955 '/PORT_DB["\'], ["\'](.*)["\']\);/',
956 $conf,
957 $matches
958 );
959 if (isset($matches[1])) {
960 $existing['db_port'] = $matches[1];
961 }
962 }
963 if (!isset($post_data['install_dbuser'])) {
964 $res = preg_match(
965 '/USER_DB["\'], ["\'](.*)["\']\);/',
966 $conf,
967 $matches
968 );
969 if (isset($matches[1])) {
970 $existing['db_user'] = $matches[1];
971 }
972 }
973 if (!isset($post_data['install_dbname'])) {
974 $res = preg_match(
975 '/NAME_DB["\'], ["\'](.*)["\']\);/',
976 $conf,
977 $matches
978 );
979 if (isset($matches[1])) {
980 $existing['db_name'] = $matches[1];
981 }
982 }
983
984
985 if (!isset($post_data['install_dbprefix'])) {
986 $res = preg_match(
987 '/PREFIX_DB["\'], ["\'](.*)["\']\);/',
988 $conf,
989 $matches
990 );
991 if (isset($matches[1])) {
992 $existing['prefix'] = $matches[1];
993 }
994 }
995
996 if ($pass === true) {
997 $res = preg_match(
998 '/PWD_DB["\'], ["\'](.*)["\']\);/',
999 $conf,
1000 $matches
1001 );
1002 if (isset($matches[1])) {
1003 $existing['pwd_db'] = $matches[1];
1004 }
1005 }
1006 }
1007 }
1008
1009 return $existing;
1010 }
1011
1012 /**
1013 * Write configuration file to disk
1014 *
1015 * @return boolean
1016 */
1017 public function writeConfFile()
1018 {
1019 $error = false;
1020 $ret = array(
1021 'message' => _T("Write configuration file"),
1022 'res' => false
1023 );
1024
1025 //if config file is already up-to-date, nothing to write
1026 $existing = $this->loadExistingConfigFile(array(), true);
1027
1028 if (
1029 isset($existing['db_type'])
1030 && $existing['db_type'] == $this->_db_type
1031 && isset($existing['db_host'])
1032 && $existing['db_host'] == $this->_db_host
1033 && isset($existing['db_port'])
1034 && $existing['db_port'] == $this->_db_port
1035 && isset($existing['db_user'])
1036 && $existing['db_user'] == $this->_db_user
1037 && isset($existing['pwd_db'])
1038 && $existing['pwd_db'] == $this->_db_pass
1039 && isset($existing['db_name'])
1040 && $existing['db_name'] == $this->_db_name
1041 && isset($existing['prefix'])
1042 && $existing['prefix'] == $this->_db_prefix
1043 ) {
1044 Analog::log(
1045 'Config file is already up-to-date, nothing to do.',
1046 Analog::INFO
1047 );
1048
1049 $this->_report[] = array(
1050 'message' => _T("Config file already exists and is up to date"),
1051 'res' => true
1052 );
1053 return true;
1054 }
1055
1056 $conffile = GALETTE_CONFIG_PATH . 'config.inc.php';
1057 if (
1058 is_writable(GALETTE_CONFIG_PATH)
1059 && (!file_exists($conffile) || file_exists($conffile) && is_writable($conffile))
1060 && $fd = @fopen($conffile, 'w')
1061 ) {
1062 $data = "<?php
1063 define('TYPE_DB', '" . $this->_db_type . "');
1064 define('HOST_DB', '" . $this->_db_host . "');
1065 define('PORT_DB', '" . $this->_db_port . "');
1066 define('USER_DB', '" . $this->_db_user . "');
1067 define('PWD_DB', '" . $this->_db_pass . "');
1068 define('NAME_DB', '" . $this->_db_name . "');
1069 define('PREFIX_DB', '" . $this->_db_prefix . "');
1070 ";
1071 fwrite($fd, $data);
1072 fclose($fd);
1073 $ret['res'] = true;
1074 Analog::log('Configuration file written on disk', Analog::INFO);
1075 } else {
1076 $str = str_replace(
1077 '%path',
1078 $conffile,
1079 _T("Unable to create configuration file (%path)")
1080 );
1081 Analog::log($str, Analog::WARNING);
1082 $ret['error'] = $str;
1083 $error = true;
1084 }
1085 $this->_report[] = $ret;
1086 return !$error;
1087 }
1088
1089 /**
1090 * Initialize Galette relevant objects
1091 *
1092 * @param I18n $i18n I18n
1093 * @param Db $zdb Database instance
1094 * @param Login $login Loged in instance
1095 *
1096 * @return boolean
1097 */
1098 public function initObjects(I18n $i18n, Db $zdb, Login $login)
1099 {
1100 if ($this->isInstall()) {
1101 $preferences = new Preferences($zdb, false);
1102 $ct = new \Galette\Entity\ContributionsTypes($zdb);
1103 $status = new \Galette\Entity\Status($zdb);
1104 include_once '../includes/fields_defs/members_fields.php';
1105 include_once '../includes/fields_defs/members_fields_cats.php';
1106 $fc = new \Galette\Entity\FieldsConfig(
1107 $zdb,
1108 \Galette\Entity\Adherent::TABLE,
1109 $members_fields,
1110 $members_fields_cats,
1111 true
1112 );
1113 //$fc = new \Galette\Entity\FieldsCategories();
1114 $texts = new \Galette\Entity\Texts($preferences);
1115 $titles = new \Galette\Repository\Titles();
1116
1117 $models = new \Galette\Repository\PdfModels($zdb, $preferences, $login);
1118
1119 $this->_error = false;
1120
1121 //Install preferences
1122 $res = $preferences->installInit(
1123 $i18n->getID(),
1124 $this->getAdminLogin(),
1125 $this->getAdminPass()
1126 );
1127 $this->proceedReport(_T("Preferences"), $res);
1128
1129 //Install contributions types
1130 $res = $ct->installInit();
1131 $this->proceedReport(_T("Contributions types"), $res);
1132
1133 //Install statuses
1134 $res = $status->installInit();
1135 $this->proceedReport(_T("Status"), $res);
1136
1137 //Install fields configuration and categories
1138 $res = $fc->installInit();
1139 $this->proceedReport(_T("Fields config and categories"), $res);
1140
1141 //Install texts
1142 $res = $texts->installInit(false);
1143 $this->proceedReport(_T("Mails texts"), $res);
1144
1145 //Install titles
1146 $res = $titles->installInit($zdb);
1147 $this->proceedReport(_T("Titles"), $res);
1148
1149 //Install PDF models
1150 $res = $models->installInit(false);
1151 $this->proceedReport(_T("PDF Models"), $res);
1152
1153 return !$this->_error;
1154 } elseif ($this->isUpgrade()) {
1155 $preferences = new Preferences($zdb);
1156 $preferences->store();
1157 $this->proceedReport(_T("Update preferences"), true);
1158
1159 $models = new \Galette\Repository\PdfModels($zdb, $preferences, new Login($zdb, $i18n, new \RKA\Session()));
1160 $res = $models->installInit(true);
1161 $this->proceedReport(_T("Update models"), true);
1162
1163 $texts = new \Galette\Entity\Texts($preferences);
1164 $res = $texts->installInit(true);
1165 $this->proceedReport(_T("Mails texts"), true);
1166
1167 return true;
1168 }
1169 }
1170
1171 /**
1172 * Proceed installation report for each Entity/Repository
1173 *
1174 * @param string $msg Report message title
1175 * @param mixed $res Initialialization result
1176 *
1177 * @return void
1178 */
1179 private function proceedReport($msg, $res)
1180 {
1181 $ret = array(
1182 'message' => $msg,
1183 'res' => false
1184 );
1185
1186 if ($res instanceof \Exception) {
1187 $ret['debug'] = $res->getMessage();
1188 $this->_error = true;
1189 } else {
1190 $ret['res'] = true;
1191 }
1192 $this->_report[] = $ret;
1193 }
1194 /**
1195 * Retrieve galette initialization report
1196 *
1197 * @return array
1198 */
1199 public function getInitializationReport()
1200 {
1201 return $this->_report;
1202 }
1203
1204 /**
1205 * Set step to database installation
1206 *
1207 * @return void
1208 */
1209 public function atEndStep()
1210 {
1211 $this->_step = self::STEP_END;
1212 }
1213
1214 /**
1215 * Are we at end step?
1216 *
1217 * @return boolean
1218 */
1219 public function isEndStep()
1220 {
1221 return $this->_step === self::STEP_END;
1222 }
1223
1224 /**
1225 * Set installed version if we're upgrading
1226 *
1227 * @param string $version Installed version
1228 *
1229 * @return void
1230 */
1231 public function setInstalledVersion($version)
1232 {
1233 $this->_installed_version = $version;
1234 }
1235
1236 /**
1237 * Current Galette installed version, according to database
1238 *
1239 * @param Db $zdb Database instance
1240 *
1241 * @return string
1242 */
1243 public function getCurrentVersion($zdb)
1244 {
1245 try {
1246 $db_ver = $zdb->getDbVersion(true);
1247 if (isset($this->versions_mapper[$db_ver])) {
1248 return $this->versions_mapper[$db_ver];
1249 } else {
1250 return $db_ver;
1251 }
1252 } catch (\LogicException $e) {
1253 return false;
1254 }
1255 }
1256
1257 /**
1258 * Check if step is passed
1259 *
1260 * @param int $step Step
1261 *
1262 * @return boolean
1263 */
1264 public function isStepPassed($step)
1265 {
1266 return $this->_step > $step;
1267 }
1268 }