Completed
Push — master ( 11ee78...8b3cbf )
by Thomas
04:46
created

InstallerApplication::installKeeko()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 49
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 49
rs 9.2258
cc 1
eloc 29
nc 1
nop 2
1
<?php
2
namespace keeko\core\installer;
3
4
use Composer\IO\IOInterface;
5
use Composer\IO\NullIO;
6
use keeko\core\model\Application;
7
use keeko\core\model\ApplicationQuery;
8
use keeko\core\model\ApplicationUri;
9
use keeko\core\model\Group;
10
use keeko\core\model\LanguageQuery;
11
use keeko\core\model\Localization;
12
use keeko\core\model\LocalizationQuery;
13
use keeko\core\model\Map\UserTableMap;
14
use keeko\core\model\Preference;
15
use keeko\core\model\User;
16
use keeko\core\model\UserQuery;
17
use keeko\core\package\AbstractApplication;
18
use keeko\core\package\ModuleManager;
19
use keeko\core\package\PackageManager;
20
use keeko\core\preferences\SystemPreferences;
21
use keeko\core\service\ServiceContainer;
22
use phootwork\lang\Text;
23
use Propel\Runtime\Propel;
24
use Symfony\Component\HttpFoundation\Request;
25
26
class InstallerApplication extends AbstractApplication {
27
	
28
	const DEFAULT_LOCALE = 'en';
29
30
	/** @var IOInterface */
31
	private $io;
32
	
33
	/** @var PackageManager */
34
	private $packageManager;
35
	
36
	/** @var AppInstaller */
37
	private $appInstaller;
38
	
39
	/** @var ModuleInstaller */
40
	private $moduleInstaller;
41
	
42
	/** @var ModuleManager */
43
	private $moduleManager;
44
45
	public function __construct(Application $model, ServiceContainer $service, IOInterface $io = null) {
46
		parent::__construct($model, $service);
47
		$this->io = $io ?: new NullIO();
48
	}
49
50
	private function initialize() {
51
		$this->packageManager = $this->service->getPackageManager();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
52
		$this->appInstaller = new AppInstaller($this->service);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
53
		$this->moduleInstaller = new ModuleInstaller($this->service);
54
		$this->moduleManager = $this->service->getModuleManager();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
55
	}
56
57
	public function install($rootUrl, $locale = self::DEFAULT_LOCALE) {
58
		if (!KEEKO_DATABASE_LOADED) {
59
			throw new \Exception('Cannot install keeko - no database defined');
60
		}
61
		
62
		$root = new Text($rootUrl);
63
		if ($root->endsWith('/')) {
64
			$rootUrl = $root->substring(0, -1);
65
		}
66
67
		$this->io->write('Install Log:');
68
69
		$this->installDatabase();
70
		$this->initialize();
71
		$this->installGroupsAndUsers();
72
		$this->installKeeko($rootUrl, $locale);
73
	}
74
	
75
	/**
76
	 * Runs the main setup routine
77
	 */
78
	public function run(Request $request) {
79
		$uri = $request->getUri();
80
		
81
		$this->install($uri, $request->getLocale());
82
	}
83
	
84
	/**
85
	 * Writes the database config
86
	 *
87
	 * @param string $host
88
	 * @param string $database
89
	 * @param string $user
90
	 * @param string $password
91
	 */
92
	public function writeConfig($host, $database, $user, $password) {
0 ignored issues
show
Unused Code introduced by
The parameter $host is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $database is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $user is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $password is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
		
94
	}
95
96
	/**
97
	 *
98
	 * @param string $locale
99
	 * @return Localization
100
	 */
101
	private function getLocale($locale) {
102
		$langTag = \Locale::getPrimaryLanguage($locale);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
103
		$regionTag = \Locale::getRegion($locale);
104
		
105
		$lang = LanguageQuery::create()->findOneBySubtag($langTag);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
106
		$query = LocalizationQuery::create()->filterByLanguage($lang);
107
		
108
		if (!empty($regionTag)) {
109
			$query->filterByRegion($regionTag);
110
		}
111
		
112
		$local = $query->findOne();
113
		
114
		// if no locale found -> create one
115
		if ($local === null) {
116
			$local = new Localization();
117
			$local->setLanguage($lang);
118
			if (!empty($regionTag)) {
119
				$local->setRegion($regionTag);
120
			}
121
			$local->setIsDefault(true);
122
			$local->save();
123
		}
124
125
		return $local;
126
	}
127
	
128
	private function installGroupsAndUsers() {
129
		$guestGroup = new Group();
130
		$guestGroup->setName('Guest');
131
		$guestGroup->setIsGuest(true);
132
		$guestGroup->save();
133
		
134
		$userGroup = new Group();
135
		$userGroup->setName('Users');
136
		$userGroup->setIsDefault(true);
137
		$userGroup->save();
138
		
139
		$adminGroup = new Group();
140
		$adminGroup->setName('Administrators');
141
		$adminGroup->save();
142
143
		
144
		$con = Propel::getConnection();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
145
		$adapter = Propel::getAdapter();
146
		
147
		// guest
148
		$guest = new User();
149
		$guest->setDisplayName('Guest');
150
		$guest->save();
151
		
152
		$stmt = $con->prepare(sprintf('UPDATE %s SET id = -1 WHERE ID = 1', $adapter->quoteIdentifierTable(UserTableMap::TABLE_NAME)));
153
		$stmt->execute();
154
		
155
		// root
156
		$root = new User();
157
		$root->setDisplayName('root');
158
		$root->setLoginName('root');
159
		$root->setPassword(password_hash('root', PASSWORD_BCRYPT));
160
		$root->save();
161
162
		$stmt = $con->prepare(sprintf('UPDATE %s SET id = 0 WHERE ID = 2', $adapter->quoteIdentifierTable(UserTableMap::TABLE_NAME)));
163
		$stmt->execute();
164
		
165
		$root = UserQuery::create()->findOneById(0);
166
		$root->addGroup($userGroup);
167
		$root->addGroup($adminGroup);
168
		$root->save();
169
		
170
		// @TODO: Cross-SQL-Server routine wanted!!
171
		$stmt = $con->prepare(sprintf('ALTER TABLE %s AUTO_INCREMENT = 1', $adapter->quoteIdentifierTable(UserTableMap::TABLE_NAME)));
172
		$stmt->execute();
173
		
174
	}
175
176
	private function installKeeko($rootUrl, $locale = self::DEFAULT_LOCALE) {
177
		// 1) apps
178
		
179
		// api
180
		$apiUrl = $rootUrl . '/api/';
181
		$this->installApp('keeko/api-app');
182
		$this->setupApp('keeko/api-app', $apiUrl, $locale);
183
		
184
		// developer
185
		$this->installApp('keeko/developer-app');
186
		$this->setupApp('keeko/developer-app', $rootUrl . '/developer/', $locale);
187
		
188
		// website
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
189
// 		$websiteApp = $this->installApp('keeko/website-app');
190
		
191
		
192
		// 2) preferences
193
		$core = $this->service->getPackageManager()->getComposerPackage('keeko/core');
194
		
195
		$pref = new Preference();
196
		$pref->setKey(SystemPreferences::VERSION);
197
		$pref->setValue($core->getPrettyVersion());
198
		$pref->save();
199
		
200
		$pref = new Preference();
201
		$pref->setKey(SystemPreferences::PLATTFORM_NAME);
202
		$pref->setValue('Keeko');
203
		$pref->save();
204
		
205
		$pref = new Preference();
206
		$pref->setKey(SystemPreferences::API_URL);
207
		$pref->setValue($apiUrl);
208
		$pref->save();
209
		
210
		$pref = new Preference();
211
		$pref->setKey(SystemPreferences::API_VERSION);
212
		$pref->setValue('1');
213
		$pref->save();
214
215
		// 3) modules
216
		$this->installModule('keeko/user');
217
		$this->activateModule('keeko/user');
218
		
219
		$this->installModule('keeko/group');
220
		$this->activateModule('keeko/group');
221
		
222
		$this->installModule('keeko/auth');
223
		$this->activateModule('keeko/auth');
224
	}
225
226
	public function installApp($packageName) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
227
		return $this->appInstaller->install($this->io, $packageName);
228
	}
229
	
230
	public function setupApp($packageName, $uri, $locale = self::DEFAULT_LOCALE) {
231
		$this->io->write(sprintf('[Keeko] Setup App %s at %s', $packageName, $uri));
232
		$app = ApplicationQuery::create()->findOneByName($packageName);
233
		
234
		if ($app === null) {
235
			throw new \Exception(sprintf('Application (%s) not found', $packageName));
236
		}
237
		
238
		$comps = parse_url($uri);
239
		
240
		$uri = new ApplicationUri();
241
		$uri->setApplication($app);
242
		$uri->setLocalization($this->getLocale($locale));
243
		$uri->setHttphost($comps['host']);
244
		$uri->setBasepath($comps['path']);
245
		$uri->setSecure($comps['scheme'] == 'https');
246
		$uri->save();
247
	}
248
	
249
	public function installModule($packageName) {
250
		$this->moduleInstaller->install($this->io, $packageName);
251
	}
252
253
	public function activateModule($packageName) {
254
		$this->moduleInstaller->activate($this->io, $packageName);
255
	}
256
257
	private function installDatabase() {
258
		$files = [
259
			'sql/keeko.sql',
260
			'data/static-data.sql'
261
		];
262
		$con = Propel::getConnection();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
263
		
264
		foreach ($files as $file) {
265
			$path = KEEKO_PATH . '/packages/keeko/core/database/' . $file;
266
			
267
			if (file_exists($path)) {
268
				$sql = file_get_contents($path);
269
				
270
				try {
271
					$stmt = $con->prepare($sql);
272
					$stmt->execute();
273
				} catch (\Exception $e) {
274
					echo $e->getMessage();
275
				}
276
			}
277
		}
278
	}
279
}