Passed
Push — master ( 8ada0c...f8b4e0 )
by Robin
15:48 queued 13s
created

File   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 80
c 2
b 0
f 1
dl 0
loc 115
rs 10
wmc 22

4 Methods

Rating   Name   Duplication   Size   Complexity  
B execute() 0 49 9
B outputStorageDetails() 0 42 11
A __construct() 0 4 1
A configure() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace OC\Core\Command\Info;
6
7
use OC\Files\ObjectStore\ObjectStoreStorage;
8
use OCA\Files_External\Config\ExternalMountPoint;
9
use OCA\GroupFolders\Mount\GroupMountPoint;
0 ignored issues
show
Bug introduced by
The type OCA\GroupFolders\Mount\GroupMountPoint was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use OCP\Files\Folder;
11
use OCP\Files\IHomeStorage;
12
use OCP\Files\Mount\IMountPoint;
13
use OCP\Files\Node;
14
use OCP\Files\NotFoundException;
15
use OCP\IL10N;
16
use OCP\L10N\IFactory;
17
use OCP\Util;
18
use Symfony\Component\Console\Command\Command;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
24
class File extends Command {
25
	private IL10N $l10n;
26
	private FileUtils $fileUtils;
27
28
	public function __construct(IFactory $l10nFactory, FileUtils $fileUtils) {
29
		$this->l10n = $l10nFactory->get("core");
30
		$this->fileUtils = $fileUtils;
31
		parent::__construct();
32
	}
33
34
	protected function configure(): void {
35
		$this
36
			->setName('info:file')
37
			->setDescription('get information for a file')
38
			->addArgument('file', InputArgument::REQUIRED, "File id or path")
39
			->addOption('children', 'c', InputOption::VALUE_NONE, "List children of folders");
40
	}
41
42
	public function execute(InputInterface $input, OutputInterface $output): int {
43
		$fileInput = $input->getArgument('file');
44
		$showChildren = $input->getOption('children');
45
		$node = $this->fileUtils->getNode($fileInput);
46
		if (!$node) {
47
			$output->writeln("<error>file $fileInput not found</error>");
48
			return 1;
49
		}
50
51
		$output->writeln($node->getName());
52
		$output->writeln("  fileid: " . $node->getId());
53
		$output->writeln("  mimetype: " . $node->getMimetype());
54
		$output->writeln("  modified: " . (string)$this->l10n->l("datetime", $node->getMTime()));
55
		$output->writeln("  " . ($node->isEncrypted() ? "encrypted" : "not encrypted"));
56
		$output->writeln("  size: " . Util::humanFileSize($node->getSize()));
57
		if ($node instanceof Folder) {
58
			$children = $node->getDirectoryListing();
59
			$childSize = array_sum(array_map(function (Node $node) {
60
				return $node->getSize();
61
			}, $children));
62
			if ($childSize != $node->getSize()) {
63
				$output->writeln("    <error>warning: folder has a size of " . Util::humanFileSize($node->getSize()) ." but it's children sum up to " . Util::humanFileSize($childSize) . "</error>.");
64
				$output->writeln("    Run <info>occ files:scan --path " . $node->getPath() . "</info> to attempt to resolve this.");
65
			}
66
			if ($showChildren) {
67
				$output->writeln("  children: " . count($children) . ":");
68
				foreach ($children as $child) {
69
					$output->writeln("  - " . $child->getName());
70
				}
71
			} else {
72
				$output->writeln("  children: " . count($children) . " (use <info>--children</info> option to list)");
73
			}
74
		}
75
		$this->outputStorageDetails($node->getMountPoint(), $node, $output);
76
77
		$filesPerUser = $this->fileUtils->getFilesByUser($node);
78
		$output->writeln("");
79
		$output->writeln("The following users have access to the file");
80
		$output->writeln("");
81
		foreach ($filesPerUser as $user => $files) {
82
			$output->writeln("$user:");
83
			foreach ($files as $userFile) {
84
				$output->writeln("  " . $userFile->getPath() . ": " . $this->fileUtils->formatPermissions($userFile->getType(), $userFile->getPermissions()));
85
				$mount = $userFile->getMountPoint();
86
				$output->writeln("    " . $this->fileUtils->formatMountType($mount));
87
			}
88
		}
89
90
		return 0;
91
	}
92
93
	/**
94
	 * @psalm-suppress UndefinedClass
95
	 * @psalm-suppress UndefinedInterfaceMethod
96
	 */
97
	private function outputStorageDetails(IMountPoint $mountPoint, Node $node, OutputInterface $output): void {
98
		$storage = $mountPoint->getStorage();
99
		if (!$storage) {
100
			return;
101
		}
102
		if (!$storage->instanceOfStorage(IHomeStorage::class)) {
103
			$output->writeln("  mounted at: " . $mountPoint->getMountPoint());
104
		}
105
		if ($storage->instanceOfStorage(ObjectStoreStorage::class)) {
106
			/** @var ObjectStoreStorage $storage */
107
			$objectStoreId = $storage->getObjectStore()->getStorageId();
108
			$parts = explode(':', $objectStoreId);
109
			/** @var string $bucket */
110
			$bucket = array_pop($parts);
111
			$output->writeln("  bucket: " . $bucket);
112
			if ($node instanceof \OC\Files\Node\File) {
113
				$output->writeln("  object id: " . $storage->getURN($node->getId()));
114
				try {
115
					$fh = $node->fopen('r');
116
					if (!$fh) {
0 ignored issues
show
introduced by
$fh is of type resource, thus it always evaluated to false.
Loading history...
117
						throw new NotFoundException();
118
					}
119
					$stat = fstat($fh);
120
					fclose($fh);
121
					if ($stat['size'] !== $node->getSize()) {
122
						$output->writeln("  <error>warning: object had a size of " . $stat['size'] . " but cache entry has a size of " . $node->getSize() . "</error>. This should have been automatically repaired");
123
					}
124
				} catch (\Exception $e) {
125
					$output->writeln("  <error>warning: object not found in bucket</error>");
126
				}
127
			}
128
		} else {
129
			if (!$storage->file_exists($node->getInternalPath())) {
130
				$output->writeln("  <error>warning: file not found in storage</error>");
131
			}
132
		}
133
		if ($mountPoint instanceof ExternalMountPoint) {
134
			$storageConfig = $mountPoint->getStorageConfig();
135
			$output->writeln("  external storage id: " . $storageConfig->getId());
136
			$output->writeln("  external type: " . $storageConfig->getBackend()->getText());
137
		} elseif ($mountPoint instanceof GroupMountPoint) {
138
			$output->writeln("  groupfolder id: " . $mountPoint->getFolderId());
0 ignored issues
show
Bug introduced by
The method getFolderId() does not exist on OCP\Files\Mount\IMountPoint. ( Ignorable by Annotation )

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

138
			$output->writeln("  groupfolder id: " . $mountPoint->/** @scrutinizer ignore-call */ getFolderId());

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...
139
		}
140
	}
141
}
142