Passed
Push — master ( 5fd064...896ccb )
by Fabio
04:59
created

TActiveRecordAction::actionGenerateAll()   F

Complexity

Conditions 23
Paths 2816

Size

Total Lines 51
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 23
eloc 38
c 1
b 0
f 0
nc 2816
nop 1
dl 0
loc 51
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * TActiveRecordAction class file
4
 *
5
 * @author Brad Anderson <[email protected]>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 * @package Prado\Shell\Actions
9
 */
10
11
namespace Prado\Shell\Actions;
12
13
use Prado\Data\ActiveRecord\TActiveRecordConfig;
14
use Prado\Data\ActiveRecord\TActiveRecordManager;
15
use Prado\Prado;
16
use Prado\Shell\TShellAction;
17
18
/**
19
 * TActiveRecordAction class.
20
 *
21
 * Create active record skeleton
22
 *
23
 * @author Brad Anderson <belisoful[at]icloud[dot]com> - Shell refactor
24
 * @author Matthias Endres <me[at]me23[dot]de> - Generate-All
25
 * @author Daniel Sampedro Bello <darthdaniel85[at]gmail[dot]com> - Generate-All
26
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> - Generate
27
 * @package Prado\Shell\Actions
28
 * @since 3.1
29
 */
30
class TActiveRecordAction extends TShellAction
31
{
32
	protected $action = 'activerecord';
33
	protected $methods = ['generate', 'generate-all'];
34
	protected $parameters = [['table', 'output'], ['output']];
35
	protected $optional = [['soap', 'overwrite'], ['soap', 'overwrite', 'prefix', 'suffix']];
36
	protected $description = [
37
		'Provides Active Record skeleton generation.',
38
		'Generate Active Record skeleton for <table> to <output>. May also generate [soap] properties.',
39
		"Generate Active Record skeleton for all Tables to <output>. May also generate [soap] properties.\nGenerated Classes are named like the Table with optional [Prefix] and/or [Suffix]. [Overwrite] is used to overwrite existing Files."
40
	];
41
	private $_soap = false;
42
	private $_overwrite = false;
43
	
44
	private $_soapall = false;
45
	private $_overwriteall = false;
46
	private $_prefix = '';
47
	private $_postfix = '';
48
	
49
	
50
	
51
	/**
52
	 * This is the Shell Command for Generating all Action Record table skeletons
53
	 * @param array $args parameters
54
	 * @return bool is the action handled
55
	 */
56
	public function actionGenerateAll($args)
57
	{
58
		$app_dir = Prado::getApplication()->getBasePath();
59
		$this->_soapall = count($args) > 2 ? ($args[2] == "soap" || $args[2] == "true" ? true : false) : false;
60
		$this->_overwriteall = count($args) > 3 ? ($args[3] == "overwrite" || $args[3] == "true" ? true : false) : false;
61
		$this->_prefix = count($args) > 4 ? $args[4] : '';
62
		$this->_postfix = count($args) > 5 ? $args[5] : '';
63
64
		if ($app_dir !== false) {
0 ignored issues
show
introduced by
The condition $app_dir !== false is always true.
Loading history...
65
			$config = $this->getActiveRecordConfig();
66
67
			$manager = TActiveRecordManager::getInstance();
68
			$con = $manager->getDbConnection();
69
			$con->setActive(true);
70
			$command = null;
71
72
			switch ($con->getDriverName()) {
73
				case 'mysqli':
74
				case 'mysql':
75
					$command = $con->createCommand("SHOW TABLES");
76
					break;
77
				case 'sqlite': //sqlite 3
78
				case 'sqlite2': //sqlite 2
79
					$command = $con->createCommand("SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'");
80
					break;
81
				case 'pgsql':
82
				case 'mssql': // Mssql driver on windows hosts
83
				case 'sqlsrv': // sqlsrv driver on windows hosts
84
				case 'dblib': // dblib drivers on linux (and maybe others os) hosts
85
				case 'oci':
86
//				case 'ibm':
87
				default:
88
					$this->_outWriter->writeError("Sorry, generateAll is not implemented for " . $con->getDriverName() . ".");
89
90
			   }
91
92
			$dataReader = $command->query();
93
			$dataReader->bindColumn(1, $table);
94
			$tables = [];
95
			while ($dataReader->read() !== false) {
96
				$tables[] = $table;
97
			}
98
			$con->setActive(false);
99
			foreach ($tables as $key => $table) {
100
				$output = $args[1] . "." . $this->_prefix . ucfirst($table) . $this->_postfix;
101
				if ($config !== false && $output !== false) {
102
					$this->generate("generate " . $table . " " . $output . " " . $this->_soapall . " " . $this->_overwriteall);
103
				}
104
			}
105
		}
106
		return true;
107
	}
108
109
	/**
110
	 * @param string $l commandline
111
	 */
112
	public function generate($l)
113
	{
114
		$input = explode(" ", trim($l));
115
		if (count($input) > 2) {
116
			$app_dir = dirname(Prado::getApplication()->getBasePath());
0 ignored issues
show
Unused Code introduced by
The assignment to $app_dir is dead and can be removed.
Loading history...
117
			$args = [$input[0], $input[1], $input[2]];
118
			if (count($input) > 3) {
119
				$args[] = 'soap';
120
			}
121
			if (count($input) > 4) {
122
				$args[] = 'overwrite';
123
			}
124
			$this->actionGenerate($args);
125
		} else {
126
			$this->_outWriter->writeLine("\n    Usage: generate table_name Application.pages.RecordClassName");
127
		}
128
	}
129
	
130
	
131
	/**
132
	 * This is the Shell Command for Generating a specific Action Record table skeleton
133
	 * @param array $args parameters
134
	 * @return bool is the action handled
135
	 */
136
	public function actionGenerate($args)
137
	{
138
		$this->_soapall = count($args) > 3 ? ($args[3] == "soap" || $args[2] == "true" ? true : false) : false;
139
		$this->_overwriteall = count($args) > 4 ? ($args[4] == "overwrite" || $args[3] == "true" ? true : false) : false;
140
		$config = $this->getActiveRecordConfig();
141
		$output = $this->getOutputFile($args[2]);
142
		if (is_file($output) && !$this->_overwrite) {
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type false; however, parameter $filename of is_file() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
		if (is_file(/** @scrutinizer ignore-type */ $output) && !$this->_overwrite) {
Loading history...
143
			$this->_outWriter->writeError("File $output already exists, skipping. ");
144
		} elseif ($config !== false && $output !== false) {
145
			$this->generateActiveRecord($config, $args[1], $output);
146
		}
147
		return true;
148
	}
149
150
	/**
151
	 * gets the TActiveRecordConfig for the application
152
	 * @return false|TActiveRecordConfig
153
	 */
154
	protected function getActiveRecordConfig()
155
	{
156
		foreach (Prado::getApplication()->getModules() as $module) {
157
			if ($module instanceof TActiveRecordConfig) {
158
				return $module;
159
			}
160
		}
161
		return null;
162
	}
163
164
	/**
165
	 * @param string $namespace output file in namespace format
166
	 * @return false|string
167
	 */
168
	protected function getOutputFile($namespace)
169
	{
170
		$app_dir = Prado::getApplication()->getBasePath();
171
		if (is_file($namespace) && strpos($namespace, $app_dir) === 0) {
172
			return $namespace;
173
		}
174
		$file = Prado::getPathOfNamespace($namespace, ".php");
175
		if ($file !== null && false !== ($path = realpath(dirname($file))) && is_dir($path)) {
176
			if (strpos($path, $app_dir) === 0) {
177
				return $file;
178
			}
179
		}
180
		$this->_outWriter->writeError('Output file ' . $file . ' must be within directory ' . $app_dir . "");
181
		return false;
182
	}
183
184
	/**
185
	 * @param TActiveRecordConfig $config database configuration
186
	 * @param string $tablename table name
187
	 * @param string $output output file name
188
	 * @return bool
189
	 */
190
	protected function generateActiveRecord($config, $tablename, $output)
191
	{
192
		$manager = TActiveRecordManager::getInstance();
193
		if ($manager->getDbConnection()) {
194
			$gateway = $manager->getRecordGateway();
195
			$tableInfo = $gateway->getTableInfo($manager->getDbConnection(), $tablename);
196
			if (count($tableInfo->getColumns()) === 0) {
197
				$this->_outWriter->writeError('Unable to find table or view "' . $tablename . '" in "' . $manager->getDbConnection()->getConnectionString() . "\".");
198
				return false;
199
			} else {
200
				$properties = [];
201
				foreach ($tableInfo->getColumns() as $field => $column) {
202
					$properties[] = $this->generateProperty($field, $column);
203
				}
204
			}
205
206
			$classname = basename($output, '.php');
207
			$class = $this->generateClass($properties, $tablename, $classname);
208
			$this->_outWriter->writeLine("  Writing class $classname to file $output");
209
			file_put_contents($output, $class);
210
		} else {
211
			$this->_outWriter->writeError('Unable to connect to database with ConnectionID=\'' . $config->getConnectionID() . "'. Please check your settings in application.xml and ensure your database connection is set up first.");
212
		}
213
		return true;
214
	}
215
216
	/**
217
	 * @param string $field php variable name
218
	 * @param \Prado\Data\Common\TDbTableColumn $column database column name
219
	 * @return string
220
	 */
221
	protected function generateProperty($field, $column)
222
	{
223
		$prop = '';
224
		$name = '$' . $field;
225
		$type = $column->getPHPType();
226
		if ($this->_soap) {
227
			$prop .= <<<EOD
228
229
	/**
230
	 * @var $type $name
231
	 * @soapproperty
232
	 */
233
234
EOD;
235
		}
236
		$prop .= "\tpublic $name;";
237
		return $prop;
238
	}
239
240
	/**
241
	 * @param array $properties class varibles
242
	 * @param string $tablename database table name
243
	 * @param string $class php class name
244
	 * @return string
245
	 */
246
	protected function generateClass($properties, $tablename, $class)
247
	{
248
		$props = implode("\n", $properties);
249
		$date = date('Y-m-d h:i:s');
250
		return <<<EOD
251
<?php
252
/**
253
 * Auto generated by prado-cli.php on $date.
254
 */
255
class $class extends TActiveRecord
256
{
257
	const TABLE='$tablename';
258
259
$props
260
261
	public static function finder(\$className=__CLASS__)
262
	{
263
		return parent::finder(\$className);
264
	}
265
}
266
267
EOD;
268
	}
269
}
270