Completed
Push — master ( 10f95b...bf15d4 )
by Michael
09:02
created

InstallCommand::processSql()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 45
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 45
ccs 0
cts 20
cp 0
rs 8.439
cc 6
eloc 20
nc 10
nop 0
crap 42
1
<?php
2
/**
3
 * Joomla! Statistics Server
4
 *
5
 * @copyright  Copyright (C) 2013 - 2017 Open Source Matters, Inc. All rights reserved.
6
 * @license    http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later
7
 */
8
9
namespace Joomla\StatsServer\Commands;
10
11
use Joomla\Controller\AbstractController;
12
use Joomla\Database\DatabaseDriver;
13
use Joomla\Database\Mysql\MysqlDriver;
14
use Joomla\StatsServer\CommandInterface;
15
16
/**
17
 * Install command
18
 *
19
 * @method         \Joomla\StatsServer\CliApplication  getApplication()  Get the application object.
20
 * @property-read  \Joomla\StatsServer\CliApplication  $app              Application object
21
 *
22
 * @since          1.0
23
 */
24
class InstallCommand extends AbstractController implements CommandInterface
25
{
26
	/**
27
	 * Database driver.
28
	 *
29
	 * @var    DatabaseDriver
30
	 * @since  1.0
31
	 */
32
	private $db = null;
33
34
	/**
35
	 * Constructor.
36
	 *
37
	 * @param   DatabaseDriver  $db  Database driver.
38
	 *
39
	 * @since   1.0
40
	 */
41
	public function __construct(DatabaseDriver $db)
42
	{
43
		$this->db = $db;
44
	}
45
46
	/**
47
	 * Execute the controller.
48
	 *
49
	 * @return  boolean
50
	 *
51
	 * @since   1.0
52
	 */
53
	public function execute()
54
	{
55
		$this->getApplication()->outputTitle('Installer');
56
57
		// Check for PDO MySQL support
58
		if (!MysqlDriver::isSupported())
59
		{
60
			$this->getApplication()->out('<error>PDO with MySQL support is not available on this server!</error>');
61
62
			return false;
63
		}
64
65
		try
66
		{
67
			// Check if the database "exists"
68
			$tables = $this->db->getTableList();
69
70
			if (!$this->getApplication()->input->getBool('reinstall', false))
71
			{
72
				$this->getApplication()->out()
73
					->out('<fg=black;bg=yellow>WARNING: A database has been found !!</fg=black;bg=yellow>')
74
					->out()
75
					->out('Do you want to reinstall ?')
76
					->out()
77
					->out('1) Yes')
78
					->out('2) No')
79
					->out()
80
					->out('<question>' . g11n3t('Select:') . '</question>', false);
81
82
				$in = trim($this->getApplication()->in());
83
84
				if ((int) $in !== 1)
85
				{
86
					$this->getApplication()->out('<info>Aborting installation.</info>');
87
88
					return true;
89
				}
90
			}
91
92
			$this->cleanDatabase($tables);
93
		}
94
		catch (\RuntimeException $e)
95
		{
96
			// Check if the message is "Could not connect to database."  Odds are, this means the DB isn't there or the server is down.
97
			if (strpos($e->getMessage(), 'Could not connect to database.') !== false)
98
			{
99
				$this->getApplication()->out('No database found.')
100
					->out('Creating the database...', false);
101
102
				$this->db->setQuery('CREATE DATABASE ' . $this->db->quoteName($this->getApplication()->get('database.name')))
103
					->execute();
104
105
				$this->db->select($this->getApplication()->get('database.name'));
106
107
				$this->getApplication()->out('<info>Database created.</info>');
108
			}
109
			else
110
			{
111
				throw $e;
112
			}
113
		}
114
115
		// Perform the installation
116
		$this->processSql()
117
			->getApplication()
118
			->out()
119
			->out('<fg=green;options=bold>Installation has been completed successfully.</fg=green;options=bold>');
120
121
		return true;
122
	}
123
124
	/**
125
	 * Cleanup the database.
126
	 *
127
	 * @param   array  $tables  Tables to remove.
128
	 *
129
	 * @return  $this
130
	 *
131
	 * @since   1.0
132
	 */
133
	private function cleanDatabase(array $tables) : InstallCommand
134
	{
135
		$this->getApplication()->out('Removing existing tables...', false);
136
137
		// Foreign key constraint fails fix
138
		$this->db->setQuery('SET FOREIGN_KEY_CHECKS=0')
139
			->execute();
140
141
		foreach ($tables as $table)
142
		{
143
			$this->db->dropTable($table, true);
144
			$this->getApplication()->out('.', false);
145
		}
146
147
		$this->db->setQuery('SET FOREIGN_KEY_CHECKS=1')
148
			->execute();
149
150
		$this->getApplication()->out('<info>Tables removed.</info>');
151
152
		return $this;
153
	}
154
155
	/**
156
	 * Process the main SQL file.
157
	 *
158
	 * @return  $this
159
	 *
160
	 * @since   1.0
161
	 * @throws  \UnexpectedValueException
162
	 */
163
	private function processSql() : InstallCommand
164
	{
165
		$fName = APPROOT . '/etc/mysql.sql';
166
167
		if (!file_exists($fName))
168
		{
169
			throw new \UnexpectedValueException('Install SQL file for MySQL not found.');
170
		}
171
172
		$sql = file_get_contents($fName);
173
174
		if (!$sql)
175
		{
176
			throw new \UnexpectedValueException('SQL file corrupted.');
177
		}
178
179
		$this->out(sprintf('Creating tables from file %s', realpath($fName)), false);
0 ignored issues
show
Bug introduced by
The method out() does not seem to exist on object<Joomla\StatsServe...ommands\InstallCommand>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
180
181
		foreach ($this->db->splitSql($sql) as $query)
182
		{
183
			$q = trim($this->db->replacePrefix($query));
184
185
			if ('' == trim($q))
186
			{
187
				continue;
188
			}
189
190
			$this->db->setQuery($q)
191
				->execute();
192
193
			$this->getApplication()->out('.', false);
194
		}
195
196
		$this->getApplication()->out('<info>Database tables created successfully.</info>');
197
198
		return $this;
199
	}
200
201
	/**
202
	 * Get the command's description
203
	 *
204
	 * @return  string
205
	 *
206
	 * @since   1.0
207
	 */
208
	public function getDescription() : string
209
	{
210
		return 'Installs the application.';
211
	}
212
213
	/**
214
	 * Get the command's title
215
	 *
216
	 * @return  string
217
	 *
218
	 * @since   1.0
219
	 */
220
	public function getTitle() : string
221
	{
222
		return 'Install Application';
223
	}
224
}
225