annotate vendor/chi-teck/drupal-code-generator/src/Helper/Dumper.php @ 4:a9cd425dd02b

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:11:55 +0000
parents c75dbcec494b
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace DrupalCodeGenerator\Helper;
Chris@0 4
Chris@0 5 use DrupalCodeGenerator\Utils;
Chris@0 6 use Symfony\Component\Console\Formatter\OutputFormatterStyle;
Chris@0 7 use Symfony\Component\Console\Helper\Helper;
Chris@0 8 use Symfony\Component\Console\Input\InputInterface;
Chris@0 9 use Symfony\Component\Console\Output\OutputInterface;
Chris@0 10 use Symfony\Component\Console\Question\ConfirmationQuestion;
Chris@0 11 use Symfony\Component\Filesystem\Filesystem;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Output dumper form generators.
Chris@0 15 */
Chris@0 16 class Dumper extends Helper {
Chris@0 17
Chris@0 18 /**
Chris@0 19 * The file system utility.
Chris@0 20 *
Chris@0 21 * @var \Symfony\Component\Filesystem\Filesystem
Chris@0 22 */
Chris@0 23 public $filesystem;
Chris@0 24
Chris@0 25 /**
Chris@0 26 * Input instance.
Chris@0 27 *
Chris@0 28 * @var \Symfony\Component\Console\Input\InputInterface
Chris@0 29 */
Chris@0 30 protected $input;
Chris@0 31
Chris@0 32 /**
Chris@0 33 * Output instance.
Chris@0 34 *
Chris@0 35 * @var \Symfony\Component\Console\Output\OutputInterface
Chris@0 36 */
Chris@0 37 protected $output;
Chris@0 38
Chris@0 39 /**
Chris@0 40 * Replace flag.
Chris@0 41 *
Chris@0 42 * @var bool
Chris@0 43 */
Chris@0 44 protected $replace;
Chris@0 45
Chris@0 46 /**
Chris@0 47 * Constructs a generator command.
Chris@0 48 *
Chris@0 49 * @param \Symfony\Component\Filesystem\Filesystem $filesystem
Chris@0 50 * The file system utility.
Chris@0 51 * @param bool $replace
Chris@0 52 * (optional) Indicates weather or not existing files can be replaced.
Chris@0 53 */
Chris@0 54 public function __construct(Filesystem $filesystem, $replace = NULL) {
Chris@0 55 $this->filesystem = $filesystem;
Chris@0 56 $this->replace = $replace;
Chris@0 57 }
Chris@0 58
Chris@0 59 /**
Chris@0 60 * {@inheritdoc}
Chris@0 61 */
Chris@0 62 public function getName() {
Chris@0 63 return 'dcg_dumper';
Chris@0 64 }
Chris@0 65
Chris@0 66 /**
Chris@0 67 * Dumps the generated code to file system.
Chris@0 68 *
Chris@0 69 * @param \Symfony\Component\Console\Input\InputInterface $input
Chris@0 70 * Input instance.
Chris@0 71 * @param \Symfony\Component\Console\Output\OutputInterface $output
Chris@0 72 * Output instance.
Chris@0 73 *
Chris@0 74 * @return array
Chris@0 75 * List of created or updated files.
Chris@0 76 */
Chris@0 77 public function dump(InputInterface $input, OutputInterface $output) {
Chris@0 78 $this->input = $input;
Chris@0 79 $this->output = $output;
Chris@0 80 $formatter_style = new OutputFormatterStyle('black', 'cyan', []);
Chris@0 81 $this->output->getFormatter()->setStyle('title', $formatter_style);
Chris@0 82
Chris@0 83 $interactive = $input->isInteractive();
Chris@0 84
Chris@0 85 // NULL means we should ask user for confirmation.
Chris@0 86 if ($this->replace !== NULL) {
Chris@0 87 $input->setInteractive(FALSE);
Chris@0 88 }
Chris@0 89
Chris@0 90 /** @var \DrupalCodeGenerator\Command\GeneratorInterface $command */
Chris@0 91 $command = $this->getHelperSet()->getCommand();
Chris@0 92
Chris@0 93 $dumped_files = $this->doDump($command->getAssets(), $command->getDirectory());
Chris@0 94
Chris@0 95 $input->setInteractive($interactive);
Chris@0 96 return $dumped_files;
Chris@0 97 }
Chris@0 98
Chris@0 99 /**
Chris@0 100 * Dumps assets.
Chris@0 101 *
Chris@0 102 * @param \DrupalCodeGenerator\Asset[] $assets
Chris@0 103 * Files to dump.
Chris@0 104 * @param string $directory
Chris@0 105 * Directory where to dump the assets.
Chris@0 106 *
Chris@0 107 * @return array
Chris@0 108 * List of created or updated assets.
Chris@0 109 */
Chris@0 110 protected function doDump(array $assets, $directory) {
Chris@0 111 $dumped_files = [];
Chris@0 112
Chris@0 113 foreach ($assets as $asset) {
Chris@0 114
Chris@0 115 $content = $asset->getContent();
Chris@0 116 $path = $asset->getPath();
Chris@0 117
Chris@0 118 $file_path = "$directory/$path";
Chris@0 119 if ($this->filesystem->exists($file_path) && !$asset->isDirectory()) {
Chris@0 120 $action = $asset->getAction();
Chris@0 121 if ($action == 'replace') {
Chris@0 122 $question_text = sprintf('<info>The file <comment>%s</comment> already exists. Would you like to replace it?</info> [<comment>Yes</comment>]:', $file_path);
Chris@0 123 if (!$this->confirm($question_text)) {
Chris@0 124 continue;
Chris@0 125 }
Chris@0 126 }
Chris@0 127 else {
Chris@0 128 $original_content = file_get_contents($file_path);
Chris@0 129 if ($action == 'append') {
Chris@0 130 $header_size = $asset->getHeaderSize();
Chris@0 131 // Do not remove header if original file is empty.
Chris@0 132 if ($original_content && $header_size > 0) {
Chris@0 133 $content = Utils::removeHeader($content, $header_size);
Chris@0 134 }
Chris@0 135 $content = $original_content . "\n" . $content;
Chris@0 136 }
Chris@0 137 elseif (is_callable($action)) {
Chris@0 138 $content = $action($original_content, $content);
Chris@0 139 }
Chris@0 140 else {
Chris@0 141 throw new \LogicException("Unsupported action: $action.");
Chris@0 142 }
Chris@0 143 }
Chris@0 144 }
Chris@0 145
Chris@0 146 // Default mode for all parent directories is 0777. It can be modified by
Chris@0 147 // changing umask.
Chris@0 148 $mode = $asset->getMode();
Chris@0 149
Chris@0 150 // Save data to file system.
Chris@0 151 if ($asset->isDirectory()) {
Chris@0 152 $this->filesystem->mkdir([$file_path], $mode);
Chris@0 153 }
Chris@0 154 else {
Chris@0 155 $this->filesystem->dumpFile($file_path, $content);
Chris@0 156 $this->filesystem->chmod($file_path, $mode);
Chris@0 157 }
Chris@0 158
Chris@0 159 $dumped_files[] = $asset->getPath();
Chris@0 160 }
Chris@0 161
Chris@0 162 return $dumped_files;
Chris@0 163 }
Chris@0 164
Chris@0 165 /**
Chris@0 166 * Asks a user for confirmation.
Chris@0 167 *
Chris@0 168 * @param string $question_text
Chris@0 169 * The question to ask to the user.
Chris@0 170 *
Chris@0 171 * @return bool
Chris@0 172 * User confirmation.
Chris@0 173 */
Chris@0 174 protected function confirm($question_text) {
Chris@0 175 $question_text = "\n $question_text\n ➤ ";
Chris@0 176 // If the input is not interactive print the question with default answer.
Chris@0 177 if ($this->replace !== NULL) {
Chris@0 178 $this->output->writeln($question_text . ($this->replace ? 'Yes' : 'No'));
Chris@0 179 }
Chris@0 180 $question = new ConfirmationQuestion($question_text, $this->replace !== FALSE);
Chris@0 181 /** @var \Symfony\Component\Console\Helper\QuestionHelper $question_helper */
Chris@0 182 $question_helper = $this->getHelperSet()->get('question');
Chris@0 183 return $question_helper->ask($this->input, $this->output, $question);
Chris@0 184 }
Chris@0 185
Chris@0 186 }