Passed
Push — master ( 5f11e6...c54283 )
by Daimona
02:14
created

CLI::getURL()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php declare( strict_types=1 );
2
3
namespace BotRiconferme;
4
5
/**
6
 * CLI helper
7
 *
8
 * Example options:
9
 *
10
 * 'username' => 'BotRiconferme'
11
 * 'list-title' => 'Utente:BotRiconferme/List.json',
12
 * 'config-title' => 'Utente:BotRiconferme/Config.json',
13
 * 'msg-title' => 'Utente:BotRiconferme/Messages.json"
14
 *
15
 * --password=(BotPassword)
16
 * OR
17
 * --use-password-file
18
 * which will look for a $PWFILE file in the current directory containing only the plain password
19
 *
20
 * --task=update-list
21
 * OR
22
 * --subtask=user-notice
23
 */
24
class CLI {
25
	public const SHORT_OPTS = '';
26
27
	public const LONG_OPTS = [
28
		'username:',
29
		'list-title:',
30
		'config-title:',
31
		'msg-title:',
32
33
		'force-url:',
34
35
		'password:',
36
		'use-password-file',
37
38
		'error-title:',
39
40
		'task:',
41
		'subtask:'
42
	];
43
44
	public const REQUIRED_OPTS = [
45
		'username',
46
		'list-title',
47
		'config-title',
48
		'msg-title',
49
	];
50
51
	/** @todo Make it customizable? */
52
	public const PASSWORD_FILE = __DIR__ . '/password.txt';
53
54
	/** @var array */
55
	private $opts;
56
57
	/**
58
	 * @return bool
59
	 */
60
	public static function isCLI() : bool {
61
		return PHP_SAPI === 'cli';
62
	}
63
64
	/**
65
	 * Populate options and check for required ones
66
	 */
67
	public function __construct() {
68
		$opts = getopt( self::SHORT_OPTS, self::LONG_OPTS );
69
		$this->checkRequired( $opts );
70
		$this->canonicalize( $opts );
71
		$this->opts = $opts;
72
	}
73
74
	/**
75
	 * @param array $opts
76
	 */
77
	private function checkRequired( array $opts ) {
78
		foreach ( self::REQUIRED_OPTS as $opt ) {
79
			if ( !array_key_exists( $opt, $opts ) ) {
80
				exit( "Required option $opt missing." );
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
81
			}
82
		}
83
84
		if ( !array_key_exists( 'password', $opts ) && !array_key_exists( 'use-password-file', $opts ) ) {
85
			exit( 'Please provide a password or use a password file' );
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
86
		} elseif ( array_key_exists( 'password', $opts ) && array_key_exists( 'use-password-file', $opts ) ) {
87
			exit( 'Can only use one of "password" and "use-password-file"' );
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
88
		}
89
90
		if ( array_key_exists( 'use-password-file', $opts ) && !file_exists( self::PASSWORD_FILE ) ) {
91
			exit( 'Please create the password file (' . self::PASSWORD_FILE . ')' );
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
92
		}
93
94
		if ( array_key_exists( 'task', $opts ) && array_key_exists( 'subtask', $opts ) ) {
95
			exit( 'Cannot specify both task and subtask.' );
1 ignored issue
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
96
		}
97
	}
98
99
	/**
100
	 * @param array &$opts
101
	 */
102
	private function canonicalize( array &$opts ) {
103
		if ( array_key_exists( 'use-password-file', $opts ) ) {
104
			$pw = file_get_contents( self::PASSWORD_FILE );
105
			$opts['password'] = $pw;
106
			unset( $opts['use-password-file'] );
107
		}
108
	}
109
110
	/**
111
	 * These are the options required by Config.
112
	 * @return array
113
	 */
114
	public function getMainOpts() : array {
115
		return array_intersect_key(
116
			$this->opts,
117
			array_fill_keys( Config::REQUIRED_OPTS, true )
118
		);
119
	}
120
121
	/**
122
	 * @param string $opt
123
	 * @param mixed $default
124
	 * @return mixed
125
	 */
126
	public function getOpt( string $opt, $default = null ) {
127
		return $this->opts[$opt] ?? $default;
128
	}
129
130
	/**
131
	 * @return array Either [ 'task' => taskname ] or [ 'subtask' => subtaskname ]
132
	 */
133
	public function getTaskOpt() : array {
134
		return array_intersect_key(
135
			$this->opts,
136
			[ 'task' => true, 'subtask' => true ]
137
		);
138
	}
139
140
	/**
141
	 * @return string|null
142
	 */
143
	public function getURL() : ?string {
144
		return $this->getOpt( 'force-url' );
145
	}
146
}
147