'/.gitignore',
'/.editorconfig' => '/.editorconfig',
'/CHANGELOG.md' => '/CHANGELOG.md',
'/LICENSE.txt' => '/LICENSE.txt',
'/README.md' => '/README.md',
'/CONTRIBUTING.md' => '/CONTRIBUTING.md',
'/index.php' => '/index.php',
'/composer.json' => '/composer.json',
'/bin' => '/bin',
'/system' => '/system',
'/vendor' => '/vendor',
'/webserver-configs' => '/webserver-configs',
];
/** @var string */
protected $source;
/** @var string */
protected $destination;
/**
* @return void
*/
protected function configure(): void
{
$this
->setName('sandbox')
->setDescription('Setup of a base Grav system in your webroot, good for development, playing around or starting fresh')
->addArgument(
'destination',
InputArgument::REQUIRED,
'The destination directory to symlink into'
)
->addOption(
'symlink',
's',
InputOption::VALUE_NONE,
'Symlink the base grav system'
)
->setHelp("The sandbox command help create a development environment that can optionally use symbolic links to link the core of grav to the git cloned repository.\nGood for development, playing around or starting fresh");
$source = getcwd();
if ($source === false) {
throw new RuntimeException('Internal Error');
}
$this->source = $source;
}
/**
* @return int
*/
protected function serve(): int
{
$input = $this->getInput();
$this->destination = $input->getArgument('destination');
// Create Some core stuff if it doesn't exist
$error = $this->createDirectories();
if ($error) {
return $error;
}
// Copy files or create symlinks
$error = $input->getOption('symlink') ? $this->symlink() : $this->copy();
if ($error) {
return $error;
}
$error = $this->pages();
if ($error) {
return $error;
}
$error = $this->initFiles();
if ($error) {
return $error;
}
$error = $this->perms();
if ($error) {
return $error;
}
return 0;
}
/**
* @return int
*/
private function createDirectories(): int
{
$io = $this->getIO();
$io->newLine();
$io->writeln('Creating Directories');
$dirs_created = false;
if (!file_exists($this->destination)) {
Folder::create($this->destination);
}
foreach ($this->directories as $dir) {
if (!file_exists($this->destination . $dir)) {
$dirs_created = true;
$io->writeln(' ' . $dir . '');
Folder::create($this->destination . $dir);
}
}
if (!$dirs_created) {
$io->writeln(' Directories already exist');
}
return 0;
}
/**
* @return int
*/
private function copy(): int
{
$io = $this->getIO();
$io->newLine();
$io->writeln('Copying Files');
foreach ($this->mappings as $source => $target) {
if ((string)(int)$source === (string)$source) {
$source = $target;
}
$from = $this->source . $source;
$to = $this->destination . $target;
$io->writeln(' ' . $source . ' -> ' . $to);
@Folder::rcopy($from, $to);
}
return 0;
}
/**
* @return int
*/
private function symlink(): int
{
$io = $this->getIO();
$io->newLine();
$io->writeln('Resetting Symbolic Links');
// Symlink also tests if using git.
if (is_dir($this->source . '/tests')) {
$this->mappings['/tests'] = '/tests';
}
foreach ($this->mappings as $source => $target) {
if ((string)(int)$source === (string)$source) {
$source = $target;
}
$from = $this->source . $source;
$to = $this->destination . $target;
$io->writeln(' ' . $source . ' -> ' . $to);
if (is_dir($to)) {
@Folder::delete($to);
} else {
@unlink($to);
}
symlink($from, $to);
}
return 0;
}
/**
* @return int
*/
private function pages(): int
{
$io = $this->getIO();
$io->newLine();
$io->writeln('Pages Initializing');
// get pages files and initialize if no pages exist
$pages_dir = $this->destination . '/user/pages';
$pages_files = array_diff(scandir($pages_dir), ['..', '.']);
if (count($pages_files) === 0) {
$destination = $this->source . '/user/pages';
Folder::rcopy($destination, $pages_dir);
$io->writeln(' ' . $destination . ' -> Created');
}
return 0;
}
/**
* @return int
*/
private function initFiles(): int
{
if (!$this->check()) {
return 1;
}
$io = $this->getIO();
$io->newLine();
$io->writeln('File Initializing');
$files_init = false;
// Copy files if they do not exist
foreach ($this->files as $source => $target) {
if ((string)(int)$source === (string)$source) {
$source = $target;
}
$from = $this->source . $source;
$to = $this->destination . $target;
if (!file_exists($to)) {
$files_init = true;
copy($from, $to);
$io->writeln(' ' . $target . ' -> Created');
}
}
if (!$files_init) {
$io->writeln(' Files already exist');
}
return 0;
}
/**
* @return int
*/
private function perms(): int
{
$io = $this->getIO();
$io->newLine();
$io->writeln('Permissions Initializing');
$dir_perms = 0755;
$binaries = glob($this->destination . DS . 'bin' . DS . '*');
foreach ($binaries as $bin) {
chmod($bin, $dir_perms);
$io->writeln(' bin/' . Utils::basename($bin) . ' permissions reset to ' . decoct($dir_perms));
}
$io->newLine();
return 0;
}
/**
* @return bool
*/
private function check(): bool
{
$success = true;
$io = $this->getIO();
if (!file_exists($this->destination)) {
$io->writeln(' file: ' . $this->destination . ' does not exist!');
$success = false;
}
foreach ($this->directories as $dir) {
if (!file_exists($this->destination . $dir)) {
$io->writeln(' directory: ' . $dir . ' does not exist!');
$success = false;
}
}
foreach ($this->mappings as $target => $link) {
if (!file_exists($this->destination . $target)) {
$io->writeln(' mappings: ' . $target . ' does not exist!');
$success = false;
}
}
if (!$success) {
$io->newLine();
$io->writeln('install should be run with --symlink|--s to symlink first');
}
return $success;
}
}