| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugins\Diagnostics\Commands; |
|
|
| use Piwik\Development; |
| use Piwik\FileIntegrity; |
| use Piwik\Filesystem; |
| use Piwik\Plugin\ConsoleCommand; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class UnexpectedFiles extends ConsoleCommand |
| { |
| protected function configure() |
| { |
| $this->setName('diagnostics:unexpected-files') |
| ->setDescription('Show a list of unexpected files found in the Matomo installation directory and optionally delete them.') |
| ->addNoValueOption('delete', null, 'Delete all the unexpected files'); |
| } |
|
|
| |
| |
| |
| protected function doExecute(): int |
| { |
| $input = $this->getInput(); |
| $output = $this->getOutput(); |
|
|
| |
| if (Development::isEnabled()) { |
| $output->writeln("Aborting - this command cannot be used in development mode as it requires a release manifest file"); |
| return 1; |
| } |
|
|
| |
| $manifest = PIWIK_INCLUDE_PATH . '/config/manifest.inc.php'; |
| if (!file_exists($manifest)) { |
| $output->writeln("Release manifest file '" . $manifest . "' not found."); |
| $output->writeln("Aborting - this command can only be used when a release manifest file is present."); |
| return 1; |
| } |
|
|
|
|
| $delete = $input->getOption('delete'); |
| if ($delete) { |
| $output->writeln("<info>Preparing to delete all unexpected files from the Matomo installation directory</info>"); |
|
|
| if (!$this->askForDeleteConfirmation()) { |
| $output->writeln("Aborted - no files were deleted"); |
| return 1; |
| } |
|
|
| return $this->runUnexpectedFiles(true); |
| } |
|
|
| return $this->runUnexpectedFiles(false); |
| } |
|
|
| |
| |
| |
| private function runUnexpectedFiles(bool $delete = false): int |
| { |
| $output = $this->getOutput(); |
|
|
| |
| |
| $excludedFiles = [ |
| '/^config\/config.ini.php$/', |
| '/^config\/common.config.ini.php$/', |
| '/\.htaccess$/', |
| '/^config\/config.php$/', |
| '/^misc\/.*$/', |
| ]; |
|
|
| $files = FileIntegrity::getUnexpectedFilesList(); |
| $fails = 0; |
|
|
| foreach ($files as $f) { |
| foreach ($excludedFiles as $ef) { |
| if (preg_match($ef, $f)) { |
| continue 2; |
| } |
| } |
|
|
| $fileName = realpath($f); |
|
|
| if ($delete) { |
| if (Filesystem::deleteFileIfExists($fileName)) { |
| $output->writeln("Deleted unexpected file '" . $fileName); |
| } else { |
| $output->writeln("Failed to delete unexpected file '" . $fileName); |
| $fails++; |
| } |
| } else { |
| $output->writeln($fileName); |
| } |
| } |
| if ($delete && $fails) { |
| $output->writeln("Failed to delete " . $fails . " unexpected files"); |
| return 1; |
| } |
| return 0; |
| } |
|
|
| |
| |
| |
| private function askForDeleteConfirmation(): bool |
| { |
| if (!$this->getInput()->isInteractive()) { |
| return true; |
| } |
|
|
| return $this->askForConfirmation( |
| '<comment>You are about to delete files. This action cannot be undone, are you sure you want to continue? (Y/N)</comment>', |
| false |
| ); |
| } |
| } |
|
|