Completed
Push — master ( 9d31a7...55703c )
by Fabio
09:26
created

PradoCommandLineActiveRecordGenAll::getXmlFile()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 8
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 7
nc 3
nop 1
dl 0
loc 8
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Prado command line developer tools.
5
 *
6
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
7
 * @link https://github.com/pradosoft/prado4
8
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
9
 * @license https://github.com/pradosoft/prado4/blob/master/LICENSE
10
 */
11
12
if(!isset($_SERVER['argv']) || php_sapi_name()!=='cli')
13
	die('Must be run from the command line');
14
15
if(file_exists($autoloader = realpath(__DIR__ . '/../vendor/autoload.php')))
16
{
17
	include($autoloader);
18
} elseif(file_exists($autoloader = realpath(__DIR__ . '/../autoload.php'))) {
19
	include($autoloader);
20
}
21
22
use Prado\TApplication;
23
use Prado\Prado;
24
25
//stub application class
26
class PradoShellApplication extends TApplication
27
{
28
	public function run()
29
	{
30
		$this->initApplication();
31
	}
32
}
33
34
restore_exception_handler();
35
36
37
//register action classes
38
PradoCommandLineInterpreter::getInstance()->addActionClass('PradoCommandLineCreateProject');
39
PradoCommandLineInterpreter::getInstance()->addActionClass('PradoCommandLineCreateTests');
40
PradoCommandLineInterpreter::getInstance()->addActionClass('PradoCommandLinePhpShell');
41
PradoCommandLineInterpreter::getInstance()->addActionClass('PradoCommandLineActiveRecordGen');
42
PradoCommandLineInterpreter::getInstance()->addActionClass('PradoCommandLineActiveRecordGenAll');
43
44
//run it;
45
PradoCommandLineInterpreter::getInstance()->run($_SERVER['argv']);
46
47
/**************** END CONFIGURATION **********************/
48
49
/**
50
 * PradoCommandLineInterpreter Class
51
 *
52
 * Command line interface, configures the action classes and dispatches the command actions.
53
 *
54
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
55
 * @since 3.0.5
56
 */
57
class PradoCommandLineInterpreter
58
{
59
	/**
60
	 * @var array command action classes
61
	 */
62
	protected $_actions=array();
63
64
	/**
65
	 * @param string action class name
66
	 */
67
	public function addActionClass($class)
68
	{
69
		$this->_actions[$class] = new $class;
70
	}
71
72
	/**
73
	 * @return PradoCommandLineInterpreter static instance
74
	 */
75
	public static function getInstance()
76
	{
77
		static $instance;
78
		if($instance === null)
79
			$instance = new self;
80
		return $instance;
81
	}
82
83
	public static function printGreeting()
84
	{
85
		echo "Command line tools for Prado ".Prado::getVersion().".\n";
86
	}
87
88
	/**
89
	 * Dispatch the command line actions.
90
	 * @param array command line arguments
91
	 */
92
	public function run($args)
93
	{
94
		if(count($args) > 1)
95
			array_shift($args);
96
		$valid = false;
97
		foreach($this->_actions as $class => $action)
98
		{
99
			if($action->isValidAction($args))
100
			{
101
				$valid |= $action->performAction($args);
102
				break;
103
			}
104
			else
105
			{
106
				$valid = false;
107
			}
108
		}
109
		if(!$valid)
110
			$this->printHelp();
111
	}
112
113
	/**
114
	 * Print command line help, default action.
115
	 */
116
	public function printHelp()
117
	{
118
		PradoCommandLineInterpreter::printGreeting();
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
119
120
		echo "usage: php prado-cli.php action <parameter> [optional]\n";
121
		echo "example: php prado-cli.php -c mysite\n\n";
122
		echo "actions:\n";
123
		foreach($this->_actions as $action)
124
			echo $action->renderHelp();
125
	}
126
}
127
128
/**
129
 * Base class for command line actions.
130
 *
131
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
132
 * @since 3.0.5
133
 */
134
abstract class PradoCommandLineAction
135
{
136
	/**
137
	 * Execute the action.
138
	 * @param array command line parameters
139
	 * @return boolean true if action was handled
140
	 */
141
	public abstract function performAction($args);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
142
143
	protected function createDirectory($dir, $mask)
144
	{
145
		if(!is_dir($dir))
146
		{
147
			mkdir($dir);
148
			echo "creating $dir\n";
149
		}
150
		if(is_dir($dir))
151
			chmod($dir, $mask);
152
	}
153
154
	protected function createFile($filename, $content)
155
	{
156
		if(!is_file($filename))
157
		{
158
			file_put_contents($filename, $content);
159
			echo "creating $filename\n";
160
		}
161
	}
162
163
	public function isValidAction($args)
164
	{
165
		return 0 == strcasecmp($args[0], $this->action) &&
0 ignored issues
show
Bug introduced by
The property action does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
166
			count($args)-1 >= count($this->parameters);
0 ignored issues
show
Bug introduced by
The property parameters does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
167
	}
168
169
	public function renderHelp()
170
	{
171
		$params = array();
172
		foreach($this->parameters as $v)
173
			$params[] = '<'.$v.'>';
174
		$parameters = join($params, ' ');
175
		$options = array();
176
		foreach($this->optional as $v)
0 ignored issues
show
Bug introduced by
The property optional does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
177
			$options[] = '['.$v.']';
178
		$optional = (strlen($parameters) ? ' ' : ''). join($options, ' ');
179
		$description='';
180
		foreach(explode("\n", wordwrap($this->description,65)) as $line)
0 ignored issues
show
Bug introduced by
The property description does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
181
			$description .= '    '.$line."\n";
182
		return <<<EOD
183
  {$this->action} {$parameters}{$optional}
184
{$description}
185
186
EOD;
187
	}
188
189
	protected function initializePradoApplication($directory)
0 ignored issues
show
Coding Style introduced by
initializePradoApplication uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
190
	{
191
		$_SERVER['SCRIPT_FILENAME'] = $directory.'/index.php';
192
		$app_dir = realpath($directory.'/protected/');
193
		if($app_dir !== false && is_dir($app_dir))
194
		{
195
			if(Prado::getApplication()===null)
196
			{
197
				$app = new PradoShellApplication($app_dir);
198
				$app->run();
199
				$dir = substr(str_replace(realpath('./'),'',$app_dir),1);
200
				$initialized=true;
0 ignored issues
show
Unused Code introduced by
$initialized is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
201
				PradoCommandLineInterpreter::printGreeting();
202
				echo '** Loaded PRADO appplication in directory "'.$dir."\".\n";
203
			}
204
205
			return Prado::getApplication();
206
		}
207
		else
208
		{
209
			PradoCommandLineInterpreter::printGreeting();
210
			echo '+'.str_repeat('-',77)."+\n";
211
			echo '** Unable to load PRADO application in directory "'.$directory."\".\n";
212
			echo '+'.str_repeat('-',77)."+\n";
213
		}
214
		return false;
215
	}
216
217
}
218
219
/**
220
 * Create a Prado project skeleton, including directories and files.
221
 *
222
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
223
 * @since 3.0.5
224
 */
225
class PradoCommandLineCreateProject extends PradoCommandLineAction
226
{
227
	protected $action = '-c';
228
	protected $parameters = array('directory');
229
	protected $optional = array();
230
	protected $description = 'Creates a Prado project skeleton for the given <directory>.';
231
232
	public function performAction($args)
233
	{
234
		PradoCommandLineInterpreter::printGreeting();
235
		$this->createNewPradoProject($args[1]);
236
		return true;
237
	}
238
239
	/**
240
	 * Functions to create new prado project.
241
	 */
242
	protected function createNewPradoProject($dir)
243
	{
244
		if(strlen(trim($dir)) == 0)
245
			return;
246
247
		$rootPath = realpath(dirname(trim($dir)));
248
249
		if(basename($dir)!=='.')
250
			$basePath = $rootPath.DIRECTORY_SEPARATOR.basename($dir);
251
		else
252
			$basePath = $rootPath;
253
		$appName = basename($basePath);
254
		$assetPath = $basePath.DIRECTORY_SEPARATOR.'assets';
255
		$protectedPath  = $basePath.DIRECTORY_SEPARATOR.'protected';
256
		$runtimePath = $basePath.DIRECTORY_SEPARATOR.'protected'.DIRECTORY_SEPARATOR.'runtime';
257
		$pagesPath = $protectedPath.DIRECTORY_SEPARATOR.'pages';
258
259
		$indexFile = $basePath.DIRECTORY_SEPARATOR.'index.php';
260
		$htaccessFile = $protectedPath.DIRECTORY_SEPARATOR.'.htaccess';
261
		$configFile = $protectedPath.DIRECTORY_SEPARATOR.'application.xml';
262
		$defaultPageFile = $pagesPath.DIRECTORY_SEPARATOR.'Home.page';
263
264
		$this->createDirectory($basePath, 0755);
265
		$this->createDirectory($assetPath,0777);
266
		$this->createDirectory($protectedPath,0755);
267
		$this->createDirectory($runtimePath,0777);
268
		$this->createDirectory($pagesPath,0755);
269
270
		$this->createFile($indexFile, $this->renderIndexFile());
271
		$this->createFile($configFile, $this->renderConfigFile($appName));
272
		$this->createFile($htaccessFile, $this->renderHtaccessFile());
273
		$this->createFile($defaultPageFile, $this->renderDefaultPage());
274
	}
275
276
	protected function renderIndexFile()
277
	{
278
		$framework = realpath(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'framework'.DIRECTORY_SEPARATOR.'prado.php';
279
return '<?php
280
281
$frameworkPath=\''.$framework.'\';
282
283
// The following directory checks may be removed if performance is required
284
$basePath=dirname(__FILE__);
285
$assetsPath=$basePath.\'/assets\';
286
$runtimePath=$basePath.\'/protected/runtime\';
287
288
if(!is_file($frameworkPath))
289
	die("Unable to find prado framework path $frameworkPath.");
290
if(!is_writable($assetsPath))
291
	die("Please make sure that the directory $assetsPath is writable by Web server process.");
292
if(!is_writable($runtimePath))
293
	die("Please make sure that the directory $runtimePath is writable by Web server process.");
294
295
296
require_once($frameworkPath);
297
298
$application=new TApplication;
299
$application->run();
300
';
301
	}
302
303
	protected function renderConfigFile($appName)
304
	{
305
		return <<<EOD
306
<?xml version="1.0" encoding="utf-8"?>
307
308
<application id="$appName" mode="Debug">
309
  <!-- alias definitions and namespace usings
310
  <paths>
311
    <alias id="myalias" path="./lib" />
312
    <using namespace="Application.common.*" />
313
  </paths>
314
  -->
315
316
  <!-- configurations for modules -->
317
  <modules>
318
    <!-- Remove this comment mark to enable caching
319
    <module id="cache" class="System.Caching.TDbCache" />
320
    -->
321
322
    <!-- Remove this comment mark to enable PATH url format
323
    <module id="request" class="THttpRequest" UrlFormat="Path" />
324
    -->
325
326
    <!-- Remove this comment mark to enable logging
327
    <module id="log" class="System.Util.TLogRouter">
328
      <route class="TBrowserLogRoute" Categories="System" />
329
    </module>
330
    -->
331
  </modules>
332
333
  <!-- configuration for available services -->
334
  <services>
335
    <service id="page" class="TPageService" DefaultPage="Home" />
336
  </services>
337
338
  <!-- application parameters
339
  <parameters>
340
    <parameter id="param1" value="value1" />
341
    <parameter id="param2" value="value2" />
342
  </parameters>
343
  -->
344
</application>
345
EOD;
346
	}
347
348
	protected function renderHtaccessFile()
349
	{
350
		return 'deny from all';
351
	}
352
353
354
	protected function renderDefaultPage()
355
	{
356
return <<<EOD
357
<html>
358
<head>
359
  <title>Welcome to PRADO</title>
360
</head>
361
<body>
362
<h1>Welcome to PRADO!</h1>
363
</body>
364
</html>
365
EOD;
366
	}
367
}
368
369
/**
370
 * Creates test fixtures for a Prado application.
371
 *
372
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
373
 * @since 3.0.5
374
 */
375
class PradoCommandLineCreateTests extends PradoCommandLineAction
376
{
377
	protected $action = '-t';
378
	protected $parameters = array('directory');
379
	protected $optional = array();
380
	protected $description = 'Create test fixtures in the given <directory>.';
381
382
	public function performAction($args)
383
	{
384
		PradoCommandLineInterpreter::printGreeting();
385
		$this->createTestFixtures($args[1]);
386
		return true;
387
	}
388
389
	protected function createTestFixtures($dir)
390
	{
391
		if(strlen(trim($dir)) == 0)
392
			return;
393
394
		$rootPath = realpath(dirname(trim($dir)));
395
		$basePath = $rootPath.'/'.basename($dir);
396
397
		$tests = $basePath.'/tests';
398
		$unit_tests = $tests.'/unit';
399
		$functional_tests = $tests.'/functional';
400
401
		$this->createDirectory($tests,0755);
402
		$this->createDirectory($unit_tests,0755);
403
		$this->createDirectory($functional_tests,0755);
404
405
		$unit_test_index = $tests.'/unit.php';
406
		$functional_test_index = $tests.'/functional.php';
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $functional_test_index exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
407
408
		$this->createFile($unit_test_index, $this->renderUnitTestFixture());
409
		$this->createFile($functional_test_index, $this->renderFunctionalTestFixture());
410
	}
411
412
	protected function renderUnitTestFixture()
413
	{
414
		$tester = realpath(dirname(dirname(__FILE__))).'/tests/test_tools/unit_tests.php';
415
return '<?php
416
417
include_once \''.$tester.'\';
418
419
$app_directory = "../protected";
420
$test_cases = dirname(__FILE__)."/unit";
421
422
$tester = new PradoUnitTester($test_cases, $app_directory);
423
$tester->run(new HtmlReporter());
424
';
425
	}
426
427
	protected function renderFunctionalTestFixture()
428
	{
429
		$tester = realpath(dirname(dirname(__FILE__))).'/tests/test_tools/functional_tests.php';
430
return '<?php
431
432
include_once \''.$tester.'\';
433
434
$test_cases = dirname(__FILE__)."/functional";
435
436
$tester=new PradoFunctionalTester($test_cases);
437
$tester->run(new SimpleReporter());
438
';
439
	}
440
441
}
442
443
/**
444
 * Creates and run a Prado application in a PHP Shell.
445
 *
446
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
447
 * @since 3.0.5
448
 */
449
class PradoCommandLinePhpShell extends PradoCommandLineAction
450
{
451
	protected $action = 'shell';
452
	protected $parameters = array();
453
	protected $optional = array('directory');
454
	protected $description = 'Runs a PHP interactive interpreter. Initializes the Prado application in the given [directory].';
455
456
	public function performAction($args)
457
	{
458
		if(count($args) > 1)
459
			$app = $this->initializePradoApplication($args[1]);
0 ignored issues
show
Unused Code introduced by
$app is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
460
461
		\Psy\Shell::debug([], Prado::getApplication());
462
		return true;
463
	}
464
}
465
466
/**
467
 * Create active record skeleton
468
 *
469
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
470
 * @since 3.1
471
 */
472
class PradoCommandLineActiveRecordGen extends PradoCommandLineAction
473
{
474
	protected $action = 'generate';
475
	protected $parameters = array('table', 'output');
476
	protected $optional = array('directory', 'soap');
477
	protected $description = 'Generate Active Record skeleton for <table> to <output> file using application.xml in [directory]. May also generate [soap] properties.';
478
	private $_soap=false;
479
480
	public function performAction($args)
481
	{
482
		$app_dir = count($args) > 3 ? $this->getAppDir($args[3]) : $this->getAppDir();
483
		$this->_soap = count($args) > 4;
484
		if($app_dir !== false)
485
		{
486
			$config = $this->getActiveRecordConfig($app_dir);
487
			$output = $this->getOutputFile($app_dir, $args[2]);
488
			if(is_file($output))
489
				echo "** File $output already exists, skiping. \n";
490
			else if($config !== false && $output !== false)
491
				$this->generateActiveRecord($config, $args[1], $output);
492
		}
493
		return true;
494
	}
495
496
	protected function getAppDir($dir=".")
497
	{
498
		if(is_dir($dir))
499
			return realpath($dir);
500
		if(false !== ($app_dir = realpath($dir.'/protected/')) && is_dir($app_dir))
501
			return $app_dir;
502
		echo '** Unable to find directory "'.$dir."\".\n";
503
		return false;
504
	}
505
506
	protected function getXmlFile($app_dir)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $app_dir is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
507
	{
508
		if(false !== ($xml = realpath($app_dir.'/application.xml')) && is_file($xml))
509
			return $xml;
510
		if(false !== ($xml = realpath($app_dir.'/protected/application.xml')) && is_file($xml))
511
			return $xml;
512
		echo '** Unable to find application.xml in '.$app_dir."\n";
513
		return false;
514
	}
515
516
	protected function getActiveRecordConfig($app_dir)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $app_dir is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
517
	{
518
		if(false === ($xml=$this->getXmlFile($app_dir)))
519
			return false;
520
		if(false !== ($app=$this->initializePradoApplication($app_dir)))
521
		{
522
			Prado::using('System.Data.ActiveRecord.TActiveRecordConfig');
523
			foreach($app->getModules() as $module)
524
				if($module instanceof TActiveRecordConfig)
0 ignored issues
show
Bug introduced by
The class TActiveRecordConfig does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
525
					return $module;
526
			echo '** Unable to find TActiveRecordConfig module in '.$xml."\n";
527
		}
528
		return false;
529
	}
530
531
	protected function getOutputFile($app_dir, $namespace)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $app_dir is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
532
	{
533
		if(is_file($namespace) && strpos($namespace, $app_dir)===0)
534
				return $namespace;
535
		$file = Prado::getPathOfNamespace($namespace, ".php");
536
		if($file !== null && false !== ($path = realpath(dirname($file))) && is_dir($path))
537
		{
538
			if(strpos($path, $app_dir)===0)
539
				return $file;
540
		}
541
		echo '** Output file '.$file.' must be within directory '.$app_dir."\n";
542
		return false;
543
	}
544
545
	protected function generateActiveRecord($config, $tablename, $output)
546
	{
547
		$manager = TActiveRecordManager::getInstance();
548
		if($connection = $manager->getDbConnection()) {
0 ignored issues
show
Unused Code introduced by
$connection is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
549
			$gateway = $manager->getRecordGateway();
550
			$tableInfo = $gateway->getTableInfo($manager->getDbConnection(), $tablename);
551
			if(count($tableInfo->getColumns()) === 0)
552
			{
553
				echo '** Unable to find table or view "'.$tablename.'" in "'.$manager->getDbConnection()->getConnectionString()."\".\n";
554
				return false;
555
			}
556
			else
557
			{
558
				$properties = array();
559
				foreach($tableInfo->getColumns() as $field=>$column)
560
					$properties[] = $this->generateProperty($field,$column);
561
			}
562
563
			$classname = basename($output, '.php');
564
			$class = $this->generateClass($properties, $tablename, $classname);
565
			echo "  Writing class $classname to file $output\n";
566
			file_put_contents($output, $class);
567
		} else {
568
			echo '** 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.\n";
569
		}
570
	}
571
572
	protected function generateProperty($field,$column)
573
	{
574
		$prop = '';
575
		$name = '$'.$field;
576
		$type = $column->getPHPType();
577
		if($this->_soap)
578
		{
579
			$prop .= <<<EOD
580
581
	/**
582
	 * @var $type $name
583
	 * @soapproperty
584
	 */
585
586
EOD;
587
		}
588
		$prop .= "\tpublic $name;";
589
		return $prop;
590
	}
591
592
	protected function generateClass($properties, $tablename, $class)
593
	{
594
		$props = implode("\n", $properties);
595
		$date = date('Y-m-d h:i:s');
596
return <<<EOD
597
<?php
598
/**
599
 * Auto generated by prado-cli.php on $date.
600
 */
601
class $class extends TActiveRecord
602
{
603
	const TABLE='$tablename';
604
605
$props
606
607
	public static function finder(\$className=__CLASS__)
608
	{
609
		return parent::finder(\$className);
610
	}
611
}
612
613
EOD;
614
	}
615
}
616
617
/**
618
 * Create active record skeleton for all tables in DB and its relations
619
 *
620
 * @author Matthias Endres <me[at]me23[dot]de>
621
 * @author Daniel Sampedro Bello <darthdaniel85[at]gmail[dot]com>
622
 * @since 3.2
623
 */
624
class PradoCommandLineActiveRecordGenAll extends PradoCommandLineAction
625
{
626
    protected $action = 'generateAll';
627
    protected $parameters = array('output');
628
    protected $optional = array('directory', 'soap', 'overwrite', 'prefix', 'postfix');
629
    protected $description = "Generate Active Record skeleton for all Tables to <output> file using application.xml in [directory]. May also generate [soap] properties.\nGenerated Classes are named like the Table with optional [Prefix] and/or [Postfix]. [Overwrite] is used to overwrite existing Files.";
630
    private $_soap = false;
631
    private $_prefix = '';
632
    private $_postfix = '';
633
    private $_overwrite = false;
634
635
    public function performAction($args) {
636
        $app_dir = count($args) > 2 ? $this->getAppDir($args[2]) : $this->getAppDir();
637
        $this->_soap = count($args) > 3 ? ($args[3] == "soap" || $args[3] == "true" ? true : false) : false;
638
        $this->_overwrite = count($args) > 4 ? ($args[4] == "overwrite" || $args[4] == "true" ? true : false) : false;
639
        $this->_prefix = count($args) > 5 ? $args[5] : '';
640
        $this->_postfix = count($args) > 6 ? $args[6] : '';
641
642
        if ($app_dir !== false) {
643
            $config = $this->getActiveRecordConfig($app_dir);
644
645
            $manager = TActiveRecordManager::getInstance();
646
            $con = $manager->getDbConnection();
647
            $con->Active = true;
648
649
            switch($con->getDriverName())
650
           	{
651
				case 'mysqli':
652
				case 'mysql':
653
					$command = $con->createCommand("SHOW TABLES");
654
					break;
655
				case 'sqlite': //sqlite 3
656
				case 'sqlite2': //sqlite 2
657
					$command = $con->createCommand("SELECT DISTINCT tbl_name FROM sqlite_master WHERE tbl_name<>'sqlite_sequence'");
658
					break;
659
				case 'pgsql':
660
				case 'mssql': // Mssql driver on windows hosts
661
				case 'sqlsrv': // sqlsrv driver on windows hosts
662
				case 'dblib': // dblib drivers on linux (and maybe others os) hosts
663
				case 'oci':
664
//				case 'ibm':
665
				default:
666
					echo "\n    Sorry, generateAll is not implemented for ".$con->getDriverName()."\n";
667
					
668
           	}
669
670
            $dataReader = $command->query();
0 ignored issues
show
Bug introduced by
The variable $command does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
671
            $dataReader->bindColumn(1, $table);
0 ignored issues
show
Bug introduced by
The variable $table seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
672
            $tables = array();
673
            while ($dataReader->read() !== false) {
674
                $tables[] = $table;
0 ignored issues
show
Bug introduced by
The variable $table seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
675
            }
676
            $con->Active = False;
677
            foreach ($tables as $key => $table) {
678
                $output = $args[1] . "." . $this->_prefix . ucfirst($table) . $this->_postfix;
679
                if ($config !== false && $output !== false) {
680
                    $this->generate("generate " . $table . " " . $output . " " . $this->_soap . " " . $this->_overwrite);
681
                }
682
            }
683
        }
684
        return true;
685
    }
686
687
    public function generate($l)
688
    {
689
		$input = explode(" ", trim($l));
690
		if(count($input) > 2)
691
		{
692
			$app_dir = '.';
693
			if(Prado::getApplication()!==null)
694
				$app_dir = dirname(Prado::getApplication()->getBasePath());
695
			$args = array($input[0],$input[1], $input[2],$app_dir);
696
			if(count($input)>3)
697
				$args = array($input[0],$input[1], $input[2],$app_dir,'soap');
698
			$cmd = new PradoCommandLineActiveRecordGen;
699
			$cmd->performAction($args);
700
		}
701
		else
702
		{
703
			echo "\n    Usage: generate table_name Application.pages.RecordClassName\n";
704
		}
705
    }
706
707
    protected function getAppDir($dir=".") {
708
        if (is_dir($dir))
709
            return realpath($dir);
710
        if (false !== ($app_dir = realpath($dir . '/protected/')) && is_dir($app_dir))
711
            return $app_dir;
712
        echo '** Unable to find directory "' . $dir . "\".\n";
713
        return false;
714
    }
715
716
    protected function getXmlFile($app_dir) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $app_dir is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
717
        if (false !== ($xml = realpath($app_dir . '/application.xml')) && is_file($xml))
718
            return $xml;
719
        if (false !== ($xml = realpath($app_dir . '/protected/application.xml')) && is_file($xml))
720
            return $xml;
721
        echo '** Unable to find application.xml in ' . $app_dir . "\n";
722
        return false;
723
    }
724
725
    protected function getActiveRecordConfig($app_dir) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $app_dir is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
726
        if (false === ($xml = $this->getXmlFile($app_dir)))
727
            return false;
728
        if (false !== ($app = $this->initializePradoApplication($app_dir))) {
729
            Prado::using('System.Data.ActiveRecord.TActiveRecordConfig');
730
            foreach ($app->getModules() as $module)
731
                if ($module instanceof TActiveRecordConfig)
0 ignored issues
show
Bug introduced by
The class TActiveRecordConfig does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
732
                    return $module;
733
            echo '** Unable to find TActiveRecordConfig module in ' . $xml . "\n";
734
        }
735
        return false;
736
    }
737
738
    protected function getOutputFile($app_dir, $namespace) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $app_dir is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
739
        if (is_file($namespace) && strpos($namespace, $app_dir) === 0)
740
            return $namespace;
741
        $file = Prado::getPathOfNamespace($namespace, "");
742
        if ($file !== null && false !== ($path = realpath(dirname($file))) && is_dir($path)) {
743
            if (strpos($path, $app_dir) === 0)
744
                return $file;
745
        }
746
        echo '** Output file ' . $file . ' must be within directory ' . $app_dir . "\n";
747
        return false;
748
    }
749
750
}
751