Test Failed
Push — master ( c74bbe...37fc36 )
by Joe
04:37
created

Plugin::setPermissionsChmod()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
dl 0
loc 4
ccs 0
cts 4
cp 0
crap 6
rs 10
c 1
b 0
f 0
eloc 3
nc 2
nop 1
1
<?php
2
/**
3
 * Plugins Management
4
 * @author Joe Huss <[email protected]>
5
 * @copyright 2017
6
 * @package MyAdmin
7
 * @category Plugins
8
 */
9
10
/**
11
 * MyAdmin Installer Plugin
12
 * @link https://github.com/composer/composer/blob/master/src/Composer/Plugin/PluginInterface.php
13
 */
14
15
namespace MyAdmin\Plugins;
16
17
use Composer\Composer;
18
use Composer\EventDispatcher\EventSubscriberInterface;
19
use Composer\IO\IOInterface;
20
use Composer\Plugin\PluginInterface;
21
use Composer\Plugin\Capable;
22
use Composer\Plugin\PluginEvents;
23
use Composer\Plugin\PreFileDownloadEvent;
24
use Composer\Script\Event;
25
26
/**
27
 * MyAdmin Installer Plugin
28
 */
29
class Plugin implements PluginInterface, EventSubscriberInterface, Capable {
30
	protected $composer;
31
	protected $io;
32
33
	/**
34
	 * Apply plugin modifications to Composer
35
	 *
36
	 * @param Composer	$composer
37
	 * @param IOInterface $io
38
	 */
39
	public function activate(Composer $composer, IOInterface $io) {
40
		$this->composer = $composer;
41
		$this->io = $io;
42
		print 'Hello peoples...';
43
		$installer = new Installer($this->io, $this->composer);
44
		$this->composer->getInstallationManager()->addInstaller($installer);
45
	}
46
47
	/**
48
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
49
	 */
50
	public function getCapabilities() {
51
		return [
52
			'Composer\Plugin\Capability\CommandProvider' => 'MyAdmin\Plugins\CommandProvider'
53
		];
54
	}
55
56
	/**
57
	 *
58
	 *	Events
59
	 *
60
	 *		Command Events					Composer\Script\Event
61
	 *
62
	 * 			pre-install-cmd				occurs before the install command is executed with a lock file present.
63
	 * 			post-install-cmd			occurs after the install command has been executed with a lock file present.
64
	 * 			pre-update-cmd				occurs before the update command is executed, or before the install command is executed without a lock file present.
65
	 * 			post-update-cmd				occurs after the update command has been executed, or after the install command has been executed without a lock file present.
66
	 * 			post-status-cmd				occurs after the status command has been executed.
67
	 * 			pre-archive-cmd				occurs before the archive command is executed.
68
	 * 			post-archive-cmd			occurs after the archive command has been executed.
69
	 * 			pre-autoload-dump			occurs before the autoloader is dumped, either during install/update, or via the dump-autoload command.
70
	 * 			post-autoload-dump			occurs after the autoloader has been dumped, either during install/update, or via the dump-autoload command.
71
	 * 			post-root-package-install	occurs after the root package has been installed, during the create-project command.
72
	 *			post-create-project-cmd		occurs after the create-project command has been executed.
73
	 *
74
	 *		Installer Events				Composer\Installer\InstallerEvent
75
	 *
76
	 * 			pre-dependencies-solving	occurs before the dependencies are resolved.
77
	 * 			post-dependencies-solving	occurs after the dependencies have been resolved.
78
	 *
79
	 *		Package Events					Composer\Installer\PackageEvent
80
	 *
81
	 * 			pre-package-install			occurs before a package is installed.
82
	 * 			post-package-install		occurs after a package has been installed.
83
	 * 			pre-package-update			occurs before a package is updated.
84
	 * 			post-package-update			occurs after a package has been updated.
85
	 * 			pre-package-uninstall		occurs before a package is uninstalled.
86
	 * 			post-package-uninstall		occurs after a package has been uninstalled.
87
	 *
88
	 * 		Plugin Events					Composer\Plugin\PluginEvents
89
	 *
90
	 * 			init						occurs after a Composer instance is done being initialized.
91
	 * 			command						occurs before any Composer Command is executed on the CLI. It provides you with access to the input and output objects of the program.
92
	 * 			pre-file-download			occurs before files are downloaded and allows you to manipulate the RemoteFilesystem object prior to downloading files based on the URL to be downloaded.
93
	 */
94
	public static function getSubscribedEvents() {
95
		return [
96
			PluginEvents::PRE_FILE_DOWNLOAD => [
97
				['onPreFileDownload', 0]
98
			]
99
		];
100
	}
101
102
	/**
103
	* @param PreFileDownloadEvent $event
104
	*/
105
	public function onPreFileDownload(PreFileDownloadEvent $event) {
106
		/*$protocol = parse_url($event->getProcessedUrl(), PHP_URL_SCHEME);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% 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...
107
		if ($protocol === 's3') {
108
			$awsClient = new AwsClient($this->io, $this->composer->getConfig());
109
			$s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient);
110
			$event->setRemoteFilesystem($s3RemoteFilesystem);
111
		}*/
112
	}
113
114
	public static function setPermissions(Event $event) {
115
		if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
116
			$event->getIO()->write('<info>No permissions setup is required on Windows.</info>');
117
			return;
118
		}
119
		$event->getIO()->write('Setting up permissions.');
120
		try {
121
			self::setPermissionsSetfacl($event);
122
			return;
123
		} catch (\Exception $setfaclException) {
124
			$event->getIO()->write(sprintf('<error>%s</error>', $setfaclException->getMessage()));
125
			$event->getIO()->write('<info>Trying chmod...</info>');
126
		}
127
		try {
128
			self::setPermissionsChmod($event);
129
			return;
130
		} catch (\Exception $chmodException) {
131
			$event->getIO()->write(sprintf('<error>%s</error>', $chmodException->getMessage()));
132
		}
133
	}
134
135
	public static function getWritableDirs(Event $event) {
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...
136
		$configuration = $event->getComposer()->getPackage()->getExtra();
137
		if (!isset($configuration['writable-dirs']))
138
			throw new \Exception('The writable-dirs must be specified in composer arbitrary extra data.');
139
		if (!is_array($configuration['writable-dirs']))
140
			throw new \Exception('The writable-dirs must be an array.');
141
		return $configuration['writable-dirs'];
142
	}
143
144
	public static function setPermissionsSetfacl(Event $event) {
145
		foreach (self::getWritableDirs($event) as $path)
146
			self::SetfaclPermissionsSetter($path);
147
	}
148
149
	public static function setPermissionsChmod(Event $event) {
150
		foreach (self::getWritableDirs($event) as $path)
151
			self::ChmodPermissionsSetter($path);
152
	}
153
154
	public static function SetfaclPermissionsSetter($path) {
155
		if (!is_dir($path))
156
			throw new \Exception('Path Not Found: '.$path);
157
		self::runCommand('setfacl -m u:"%httpduser%":rwX -m u:$USER:rwX %path%', $path);
158
		self::runCommand('setfacl -d -m u:"%httpduser%":rwX -m u:$USER:rwX %path%', $path);
159
	}
160
161
	public static function ChmodPermissionsSetter($path) {
162
		if (!is_dir($path))
163
			throw new \Exception('Path Not Found: '.$path);
164
		self::runCommand('chmod +a "%httpduser% allow delete,write,append,file_inherit,directory_inherit" %path%', $path);
165
		self::runCommand('chmod +a "$USER allow delete,write,append,file_inherit,directory_inherit" %path%', $path);
166
	}
167
168
	public static function runCommand($command, $path) {
169
		return self::runProcess(str_replace(['%httpduser%', '%path%'], [self::getHttpdUser(), $path], $command));
170
	}
171
172
	public static function getHttpdUser() {
173
		return self::runProcess("ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\  -f1");
174
	}
175
176
	public static function runProcess($commandline) {
177
		exec($commandline, $output, $return);
178
		if ($return != 0)
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $return of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
179
			throw new \Exception('Returned Error Code '.$return);
180
		return implode(PHP_EOL, $output);
181
	}
182
}
183