99
1010namespace FeatherBB \Controller ;
1111
12+ use Dotenv \Dotenv ;
1213use FeatherBB \Core \Interfaces \Cache ;
1314use FeatherBB \Core \Interfaces \Container ;
1415use FeatherBB \Core \Interfaces \ForumEnv ;
@@ -34,10 +35,10 @@ class Install
3435 'sqlite3 ' => 'SQLite3 ' ,
3536 ];
3637 protected $ availableLangs ;
37- protected $ optionalFields = ['db_user ' , 'db_pass ' , ' db_prefix ' ];
38+ protected $ optionalFields = ['DB_PASS ' , 'DB_PREFIX ' ];
3839 protected $ installLang = 'English ' ;
3940 protected $ defaultStyle = 'FeatherBB ' ;
40- protected $ configKeys = ['db_type ' , 'db_host ' , 'db_name ' , 'db_user ' , 'db_pass ' , 'db_prefix ' ];
41+ protected $ configKeys = ['DB_TYPE ' , 'DB_HOST ' , 'DB_NAME ' , 'DB_USER ' , 'DB_PASS ' , 'DB_PREFIX ' ];
4142 protected $ errors = [];
4243
4344 public function __construct ()
@@ -68,75 +69,60 @@ public function run()
6869
6970 // Second form has been submitted to start install
7071 if (Request::isPost () && !Input::post ('choose_lang ' )) {
71- $ missingFields = [];
7272 $ data = array_map (function ($ item ) {
7373 return Utils::escape (Utils::trim ($ item ));
7474 }, Input::post ('install ' ));
7575
76- foreach ($ data as $ field => $ value ) {
77- // Handle empty fields
78- if (empty ($ value )) {
79- // If the field is required, or if user and pass are missing even though mysql or pgsql are selected as DB
80- if (!in_array ($ field , $ this ->optionalFields ) || (in_array ($ field , ['db_user ' ]) && in_array ($ data ['db_type ' ], ['mysql ' , 'pgsql ' ]))) {
81- $ missingFields [] = $ field ;
82- }
83- }
76+ // VALIDATION
77+ // Make sure base_url doesn't end with a slash
78+ if (substr ($ data ['base_url ' ], -1 ) == '/ ' ) {
79+ $ data ['base_url ' ] = substr ($ data ['base_url ' ], 0 , -1 );
8480 }
8581
86- if (!empty ($ missingFields )) {
87- $ this ->errors = 'The following fields are required but are missing : ' .implode (', ' , $ missingFields );
88- } else { // Missing fields, so we don't need to validate the others
89- // VALIDATION
90- // Make sure base_url doesn't end with a slash
91- if (substr ($ data ['base_url ' ], -1 ) == '/ ' ) {
92- $ data ['base_url ' ] = substr ($ data ['base_url ' ], 0 , -1 );
93- }
94-
95- // Validate username and passwords
96- if (Utils::strlen ($ data ['username ' ]) < 2 ) {
97- $ this ->errors [] = __ ('Username 1 ' );
98- } elseif (Utils::strlen ($ data ['username ' ]) > 25 ) { // This usually doesn't happen since the form element only accepts 25 characters
99- $ this ->errors [] = __ ('Username 2 ' );
100- } elseif (!strcasecmp ($ data ['username ' ], 'Guest ' )) {
101- $ this ->errors [] = __ ('Username 3 ' );
102- } elseif (preg_match ('%[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}% ' , $ data ['username ' ]) || preg_match ('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))% ' , $ data ['username ' ])) {
103- $ this ->errors [] = __ ('Username 4 ' );
104- } elseif ((strpos ($ data ['username ' ], '[ ' ) !== false || strpos ($ data ['username ' ], '] ' ) !== false ) && strpos ($ data ['username ' ], '\'' ) !== false && strpos ($ data ['username ' ], '" ' ) !== false ) {
105- $ this ->errors [] = __ ('Username 5 ' );
106- } elseif (preg_match ('%(?:\[/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\]|\[(?:code|quote|list)=)%i ' , $ data ['username ' ])) {
107- $ this ->errors [] = __ ('Username 6 ' );
108- }
109-
110- if (Utils::strlen ($ data ['password ' ]) < 6 ) {
111- $ this ->errors [] = __ ('Short password ' );
112- } elseif ($ data ['password ' ] != $ data ['password_conf ' ]) {
113- $ this ->errors [] = __ ('Passwords not match ' );
114- }
115-
116- // Validate email
117- if (!filter_var ($ data ['email ' ], FILTER_VALIDATE_EMAIL )) {
118- $ this ->errors [] = __ ('Wrong email ' );
119- }
120-
121- // Validate language
122- if (!in_array ($ data ['language ' ], Lister::getLangs ())) {
123- $ this ->errors [] = __ ('Error default language ' );
124- }
125-
126- // Check if the cache directory is writable
127- if (!is_writable (ForumEnv::get ('FORUM_CACHE_DIR ' ))) {
128- $ this ->errors [] = sprintf (__ ('Alert cache ' ), ForumEnv::get ('FORUM_CACHE_DIR ' ));
129- }
130-
131- // Check if default avatar directory is writable
132- if (!is_writable (ForumEnv::get ('FEATHER_ROOT ' ).'style/img/avatars/ ' )) {
133- $ this ->errors [] = sprintf (__ ('Alert avatar ' ), ForumEnv::get ('FEATHER_ROOT ' ).'style/img/avatars/ ' );
134- }
135-
136- // Validate db_prefix if existing
137- if (!empty ($ data ['db_prefix ' ]) && ((strlen ($ data ['db_prefix ' ]) > 0 && (!preg_match ('%^[a-zA-Z_][a-zA-Z0-9_]*$% ' , $ data ['db_prefix ' ]) || strlen ($ data ['db_prefix ' ]) > 40 )))) {
138- $ this ->errors [] = sprintf (__ ('Table prefix error ' ), $ data ['db_prefix ' ]);
139- }
82+ // Validate username and passwords
83+ if (Utils::strlen ($ data ['username ' ]) < 2 ) {
84+ $ this ->errors [] = __ ('Username 1 ' );
85+ } elseif (Utils::strlen ($ data ['username ' ]) > 25 ) { // This usually doesn't happen since the form element only accepts 25 characters
86+ $ this ->errors [] = __ ('Username 2 ' );
87+ } elseif (!strcasecmp ($ data ['username ' ], 'Guest ' )) {
88+ $ this ->errors [] = __ ('Username 3 ' );
89+ } elseif (preg_match ('%[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}% ' , $ data ['username ' ]) || preg_match ('%((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))% ' , $ data ['username ' ])) {
90+ $ this ->errors [] = __ ('Username 4 ' );
91+ } elseif ((strpos ($ data ['username ' ], '[ ' ) !== false || strpos ($ data ['username ' ], '] ' ) !== false ) && strpos ($ data ['username ' ], '\'' ) !== false && strpos ($ data ['username ' ], '" ' ) !== false ) {
92+ $ this ->errors [] = __ ('Username 5 ' );
93+ } elseif (preg_match ('%(?:\[/?(?:b|u|i|h|colou?r|quote|code|img|url|email|list)\]|\[(?:code|quote|list)=)%i ' , $ data ['username ' ])) {
94+ $ this ->errors [] = __ ('Username 6 ' );
95+ }
96+
97+ if (Utils::strlen ($ data ['password ' ]) < 6 ) {
98+ $ this ->errors [] = __ ('Short password ' );
99+ } elseif ($ data ['password ' ] != $ data ['password_conf ' ]) {
100+ $ this ->errors [] = __ ('Passwords not match ' );
101+ }
102+
103+ // Validate email
104+ if (!filter_var ($ data ['email ' ], FILTER_VALIDATE_EMAIL )) {
105+ $ this ->errors [] = __ ('Wrong email ' );
106+ }
107+
108+ // Validate language
109+ if (!in_array ($ data ['language ' ], Lister::getLangs ())) {
110+ $ this ->errors [] = __ ('Error default language ' );
111+ }
112+
113+ // Check if the cache directory is writable
114+ if (!is_writable (ForumEnv::get ('FORUM_CACHE_DIR ' ))) {
115+ $ this ->errors [] = sprintf (__ ('Alert cache ' ), ForumEnv::get ('FORUM_CACHE_DIR ' ));
116+ }
117+
118+ // Check if default avatar directory is writable
119+ if (!is_writable (ForumEnv::get ('FEATHER_ROOT ' ).'style/img/avatars/ ' )) {
120+ $ this ->errors [] = sprintf (__ ('Alert avatar ' ), ForumEnv::get ('FEATHER_ROOT ' ).'style/img/avatars/ ' );
121+ }
122+
123+ // Validate DB_PREFIX if existing
124+ if (!empty ($ data ['DB_PREFIX ' ]) && ((strlen ($ data ['DB_PREFIX ' ]) > 0 && (!preg_match ('%^[a-zA-Z_][a-zA-Z0-9_]*$% ' , $ data ['DB_PREFIX ' ]) || strlen ($ data ['DB_PREFIX ' ]) > 40 )))) {
125+ $ this ->errors [] = sprintf (__ ('Table prefix error ' ), $ data ['DB_PREFIX ' ]);
140126 }
141127
142128 // End validation and check errors
@@ -174,15 +160,16 @@ public function createConfig(array $data)
174160 // Generate config ...
175161 $ config = [];
176162 foreach ($ data as $ key => $ value ) {
163+ $ key = strtoupper ($ key );
177164 if (in_array ($ key , $ this ->configKeys )) {
178165 $ config [$ key ] = $ value ;
179166 }
180167 }
181168
182169 $ config = array_merge ($ config , [
183- 'cookie_name ' => mb_strtolower (ForumEnv::get ('FORUM_NAME ' )).'_cookie_ ' .Random::key (7 , false , true ),
184- 'jwt_token ' => base64_encode (Random::secureRandomBytes (64 )),
185- 'jwt_algorithm ' => 'HS512 '
170+ 'COOKIE_NAME ' => mb_strtolower (ForumEnv::get ('FORUM_NAME ' )).'_cookie_ ' .Random::key (7 , false , true ),
171+ 'JWT_TOKEN ' => base64_encode (Random::secureRandomBytes (64 )),
172+ 'JWT_ALGORITHM ' => 'HS512 '
186173 ]);
187174
188175 // ... And write it on disk
@@ -197,17 +184,24 @@ public function createConfig(array $data)
197184 public function createDb (array $ data )
198185 {
199186 Hooks::fire ('controller.install.create_db ' );
187+ $ root = realpath (dirname (__FILE__ ).'/../../ ' ).'/ ' ;
188+ try {
189+ $ dotenv = Dotenv::create ($ root );
190+ $ dotenv ->load ();
191+ } catch (\Dotenv \Exception \InvalidPathException $ e ) {}
192+
193+ $ forumEnv = Core::loadDefaultForumEnv ();
194+
195+ Container::set ('forum_env ' , $ forumEnv );
200196
201- // Handle db prefix
202- $ data ['db_prefix ' ] = (!empty ($ data ['db_prefix ' ])) ? $ data ['db_prefix ' ] : '' ;
203197 // Init DB
204- Core::initDb ($ data );
198+ Core::initDb ();
205199 // Load appropriate language
206200 Lang::load ('install ' , 'featherbb ' , false , $ data ['language ' ]);
207201
208202 // Create tables
209203 foreach ($ this ->model ->getDatabaseScheme () as $ table => $ sql ) {
210- if (!$ this ->model ->createTable ($ data [ ' db_prefix ' ] .$ table , $ sql )) {
204+ if (!$ this ->model ->createTable (ForumEnv:: get ( ' DB_PREFIX ' ) .$ table , $ sql )) {
211205 // Error handling
212206 $ this ->errors [] = 'A problem was encountered while creating table ' .$ table ;
213207 }
@@ -228,8 +222,11 @@ public function createDb(array $data)
228222 // Perms::allowGroup(2, array('mod.is_mod', 'mod.edit_users', 'mod.rename_users', 'mod.change_passwords', 'mod.promote_users', 'mod.ban_users', 'user.set_title'));
229223
230224 Perms::allowGroup (3 , ['board.read ' , 'users.view ' , 'search.topics ' , 'search.users ' ]);
231- Perms::allowGroup (4 , ['board.read ' , 'users.view ' , 'search.topics ' , 'search.users ' , 'topic.reply ' , 'topic.post ' , 'topic.delete ' , 'post.delete ' , 'post.edit ' , 'post.links ' , 'email.send ' ]);
232- Perms::allowGroup (2 , ['board.read ' , 'users.view ' , 'user.set_title ' , 'search.topics ' , 'search.users ' , 'topic.reply ' , 'topic.post ' , 'topic.delete ' , 'post.delete ' , 'post.edit ' , 'post.links ' , 'email.send ' , 'mod.is_mod ' , 'mod.edit_users ' , 'mod.rename_users ' , 'mod.change_passwords ' , 'mod.promote_users ' , 'mod.ban_users ' ]);
225+ Perms::allowGroup (4 , ['board.read ' , 'users.view ' , 'search.topics ' , 'search.users ' ,
226+ 'topic.reply ' , 'topic.post ' , 'topic.delete ' , 'post.delete ' , 'post.edit ' , 'post.links ' , 'email.send ' ]);
227+ Perms::allowGroup (2 , ['board.read ' , 'users.view ' , 'user.set_title ' , 'search.topics ' , 'search.users ' ,
228+ 'topic.reply ' , 'topic.post ' , 'topic.delete ' , 'post.delete ' , 'post.edit ' , 'post.links ' , 'email.send ' ,
229+ 'mod.is_mod ' , 'mod.edit_users ' , 'mod.rename_users ' , 'mod.change_passwords ' , 'mod.promote_users ' , 'mod.ban_users ' ]);
233230 Perms::allowGroup (1 , ['* ' ]);
234231 Cache::store ('permissions ' , \FeatherBB \Model \Cache::getPermissions ());
235232 // Init preferences
@@ -295,7 +292,13 @@ public function writeConfig($array)
295292 {
296293 Hooks::fire ('controller.install.write_config ' );
297294
298- return file_put_contents (ForumEnv::get ('FORUM_CONFIG_FILE ' ), '<?php ' ."\n" .'$featherbbConfig = ' .var_export ($ array , true ).'; ' );
295+ $ text = '' ;
296+
297+ foreach ($ array as $ key => $ value ) {
298+ $ text .= $ key .'= ' .$ value ."\n" ;
299+ }
300+
301+ return file_put_contents (ForumEnv::get ('FORUM_CONFIG_FILE ' ), $ text );
299302 }
300303
301304 public function writeHtaccess ()
0 commit comments