Ghost Exploiter Team Official
Mass Deface
Directory >>
/
var
/
www
/
html
/
back
/
vendor
/
psy
/
psysh
/
src
/
ManualUpdater
/
Mass Deface Auto Detect Domain
/*Ubah Ke document_root untuk mass deface*/
File / Folder
Size
Action
.
-
type
file
dir
+File/Dir
Checker.php
0.751KB
edt
ren
GitHubChecker.php
4.917KB
edt
ren
Installer.php
2.688KB
edt
ren
IntervalChecker.php
3.501KB
edt
ren
ManualUpdate.php
11.199KB
edt
ren
<?php /* * This file is part of Psy Shell. * * (c) 2012-2025 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\ManualUpdater; use Psy\ConfigPaths; use Psy\Configuration; use Psy\Exception\ErrorException; use Psy\Exception\InvalidManualException; use Psy\VersionUpdater\Downloader; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; /** * Manual update command. * * If a new manual version is available, this command will download and install it. */ class ManualUpdate { const SUCCESS = 0; const FAILURE = 1; /** @var array{checker: Checker, installer: Installer}[] */ private array $updates; private ?Downloader $downloader = null; /** * @param array{checker: Checker, installer: Installer} ...$updates Update configuration(s) */ public function __construct(array ...$updates) { $this->updates = $updates; } /** * Create a ManualUpdate instance from Configuration and command-line input. * * @param Configuration $config Configuration instance * @param InputInterface $input Input interface * @param OutputInterface $output Output interface * * @return self */ public static function fromConfig(Configuration $config, InputInterface $input, OutputInterface $output): self { $lang = $input->getOption('update-manual') ?: null; // Clear the manual update cache when explicitly running --update-manual $cacheFile = $config->getManualUpdateCheckCacheFile(); if ($cacheFile && \file_exists($cacheFile)) { @\unlink($cacheFile); } // Get current manual language before potentially deleting files $currentLang = null; $removedInvalidSqlite = false; $manualFile = $config->getManualDbFile(); if ($manualFile && \file_exists($manualFile)) { try { $manual = $config->getManual(); if ($manual) { $currentMeta = $manual->getMeta(); $currentLang = $currentMeta['lang'] ?? null; } } catch (InvalidManualException $e) { $removedInvalidSqlite = \substr($e->getManualFile(), -7) === '.sqlite'; self::handleInvalidManual($e, $input, $output); } } $dataDir = $config->getManualInstallDir(); if ($dataDir === false) { throw new \RuntimeException('Unable to find a writable data directory for manual installation'); } $phpManualPath = $dataDir.'/php_manual.php'; $sqliteManualPath = $dataDir.'/php_manual.sqlite'; $formats = self::getFormatsToUpdate( $input, $output, \file_exists($phpManualPath), \file_exists($sqliteManualPath), $removedInvalidSqlite, $sqliteManualPath ); // Build update configurations for selected formats $checkerLang = $lang ?: $currentLang ?: 'en'; $updates = []; foreach ($formats as $format) { $path = $format === 'php' ? $phpManualPath : $sqliteManualPath; $meta = self::getManualMeta($path); $updates[] = [ 'checker' => new GitHubChecker($checkerLang, $format, $meta['version'] ?? null, $meta['lang'] ?? null), 'installer' => new Installer($dataDir, $format), ]; } return new self(...$updates); } /** * Allow the downloader to be injected for testing. * * @return void */ public function setDownloader(Downloader $downloader) { $this->downloader = $downloader; } /** * Get the currently set Downloader or create one based on the capabilities of the php environment. * * @throws ErrorException if a downloader cannot be created for the php environment */ private function getDownloader(): Downloader { if (!isset($this->downloader)) { return Downloader\Factory::getDownloader(); } return $this->downloader; } /** * Update the manual installation. */ public function run(InputInterface $input, OutputInterface $output): int { foreach ($this->updates as $update) { if (!$update['installer']->isDataDirWritable()) { $output->writeln('<error>Data directory is not writable.</error>'); return self::FAILURE; } } $downloader = $this->getDownloader(); $downloader->setTempDir(\sys_get_temp_dir()); $installed = []; // Download and install each format foreach ($this->updates as $update) { $checker = $update['checker']; $installer = $update['installer']; if ($checker->isLatest()) { continue; } $latestVersion = $checker->getLatest(); $downloadUrl = $checker->getDownloadUrl(); $output->write("Downloading manual v{$latestVersion}..."); try { $downloaded = $downloader->download($downloadUrl); } catch (ErrorException $e) { $output->write(' <error>Failed.</error>'); $output->writeln(\sprintf('<error>%s</error>', $e->getMessage())); $downloader->cleanup(); return self::FAILURE; } if (!$downloaded) { $output->writeln(' <error>Download failed.</error>'); $downloader->cleanup(); return self::FAILURE; } $output->write(' <info>OK</info>'.\PHP_EOL); $downloadedFile = $downloader->getFilename(); if (!$installer->install($downloadedFile)) { $downloader->cleanup(); $output->writeln('<error>Failed to install manual.</error>'); return self::FAILURE; } $installed[] = [$installer->getInstallPath(), $latestVersion]; $downloader->cleanup(); } if (empty($installed)) { $output->writeln('<info>Manual is up-to-date.</info>'); } else { foreach ($installed as [$installPath, $version]) { $prettyPath = ConfigPaths::prettyPath($installPath); $output->writeln("Installed manual v{$version} to <info>{$prettyPath}</info>"); } } return self::SUCCESS; } /** * Handle an invalid manual file by prompting the user to remove it. * * @param InvalidManualException $e The exception containing invalid manual details * @param InputInterface $input Input interface * @param OutputInterface $output Output interface * * @throws \RuntimeException if user declines to remove the file or removal fails */ private static function handleInvalidManual(InvalidManualException $e, InputInterface $input, OutputInterface $output): void { $prettyPath = ConfigPaths::prettyPath($e->getManualFile()); $output->writeln(\sprintf('<error>Invalid manual file detected:</error> <info>%s</info>', $prettyPath)); $output->writeln(''); $helper = new QuestionHelper(); $question = new ConfirmationQuestion('Remove this file and continue? [Y/n] ', true); if (!$helper->ask($input, $output, $question)) { throw new \RuntimeException('Manual update cancelled.'); } if (!\unlink($e->getManualFile())) { throw new \RuntimeException(\sprintf('Failed to remove file: %s', $prettyPath)); } $output->writeln('<info>Invalid manual file removed.</info>'); $output->writeln(''); } /** * Prompt user to download PHP format manual when they have/had legacy SQLite. * * @param InputInterface $input Input interface * @param OutputInterface $output Output interface * @param string $manualFile Path to current/former SQLite manual file * @param bool $wasRemoved Whether the file was already removed * * @return bool True if user wants to download PHP format */ private static function promptMigrateToV3(InputInterface $input, OutputInterface $output, string $manualFile, bool $wasRemoved): bool { $prettyPath = ConfigPaths::prettyPath($manualFile); $verb = $wasRemoved ? 'had' : 'have'; $output->writeln(\sprintf('You %s a legacy SQLite manual: <info>%s</info>', $verb, $prettyPath)); $output->writeln(''); $helper = new QuestionHelper(); $question = new ConfirmationQuestion('Download the current manual format? [Y/n] ', true); return $helper->ask($input, $output, $question); } /** * Determine which manual formats should be updated. * * @param InputInterface $input Input interface * @param OutputInterface $output Output interface * @param bool $hasPhpManual Whether PHP manual exists * @param bool $hasSqliteManual Whether SQLite manual exists * @param bool $removedInvalidSqlite Whether we just removed an invalid SQLite manual * @param string $sqliteManualPath Path to SQLite manual file * * @return string[] Array of format names to update ('php', 'sqlite') */ private static function getFormatsToUpdate( InputInterface $input, OutputInterface $output, bool $hasPhpManual, bool $hasSqliteManual, bool $removedInvalidSqlite, string $sqliteManualPath ): array { // Only SQLite exists (or just removed invalid SQLite): offer to add PHP format if (!$hasPhpManual && ($hasSqliteManual || $removedInvalidSqlite)) { if (self::promptMigrateToV3($input, $output, $sqliteManualPath, $removedInvalidSqlite)) { return ['php', 'sqlite']; } return ['sqlite']; } // PHP exists, or neither exist: default to PHP, and include SQLite if it exists $formats = ['php']; if ($hasSqliteManual) { $formats[] = 'sqlite'; } return $formats; } /** * Get manual metadata from a file. * * @param string $path Path to manual file * * @return array|null Metadata array with 'version' and 'lang' keys, or null if unavailable */ private static function getManualMeta(string $path): ?array { if (!\file_exists($path)) { return null; } try { if (\substr($path, -4) === '.php') { $manual = new \Psy\Manual\V3Manual($path); return $manual->getMeta(); } if (\substr($path, -7) === '.sqlite') { $pdo = new \PDO('sqlite:'.$path); $manual = new \Psy\Manual\V2Manual($pdo); return $manual->getMeta(); } } catch (\Exception $e) { // Ignore errors reading manual metadata } return null; } }