forceAppend = $force_append; $this->prepend = $prepend_path; $this->append = $append_path; $this->default = $default_path; $this->managed = TRUE; } /** * {@inheritdoc} */ protected function generateContents() { // Fetch the prepend contents, if provided. $prepend_contents = ''; if (!empty($this->prepend)) { $prepend_contents = file_get_contents($this->prepend->fullPath()) . "\n"; } // Fetch the append contents, if provided. $append_contents = ''; if (!empty($this->append)) { $append_contents = "\n" . file_get_contents($this->append->fullPath()); } // Get the original contents, or the default data if the original is empty. $original_contents = $this->originalContents; if (empty($original_contents) && !empty($this->default)) { $original_contents = file_get_contents($this->default->fullPath()); } // Attach it all together. return $prepend_contents . $original_contents . $append_contents; } /** * {@inheritdoc} */ public function process(ScaffoldFilePath $destination, IOInterface $io, ScaffoldOptions $options) { $destination_path = $destination->fullPath(); $interpolator = $destination->getInterpolator(); // Be extra-noisy of creating a new file or appending to a non-scaffold // file. Note that if the file already has the append contents, then the // OperationFactory will make a SkipOp instead, and we will not get here. if (!$this->managed) { $message = ' - NOTICE Modifying existing file at [dest-rel-path].'; if (!file_exists($destination_path)) { $message = ' - NOTICE Creating a new file at [dest-rel-path].'; } $message .= ' Examine the contents and ensure that it came out correctly.'; $io->write($interpolator->interpolate($message)); } // Notify that we are prepending, if there is prepend data. if (!empty($this->prepend)) { $this->prepend->addInterpolationData($interpolator, 'prepend'); $io->write($interpolator->interpolate(" - Prepend to [dest-rel-path] from [prepend-rel-path]")); } // Notify that we are appending, if there is append data. if (!empty($this->append)) { $this->append->addInterpolationData($interpolator, 'append'); $io->write($interpolator->interpolate(" - Append to [dest-rel-path] from [append-rel-path]")); } // Write the resulting data file_put_contents($destination_path, $this->contents()); // Return a ScaffoldResult with knowledge of whether this file is managed. return new ScaffoldResult($destination, $this->managed); } /** * {@inheritdoc} */ public function scaffoldOverExistingTarget(OperationInterface $existing_target) { $this->originalContents = $existing_target->contents(); return $this; } /** * {@inheritdoc} */ public function scaffoldAtNewLocation(ScaffoldFilePath $destination) { // If there is no existing scaffold file at the target location, then any // append we do will be to an unmanaged file. $this->managed = FALSE; // Default: do not allow an append over a file that was not scaffolded. if (!$this->forceAppend) { $message = " - Skip [dest-rel-path]: cannot append to a path that was not scaffolded unless 'force-append' property is set."; return new SkipOp($message); } // If the target file does not exist, then we will allow the append to // happen if we have default data to provide for it. if (!file_exists($destination->fullPath())) { if (!empty($this->default)) { return $this; } $message = " - Skip [dest-rel-path]: no file exists at the target path, and no default data provided."; return new SkipOp($message); } // If the target file DOES exist, and it already contains the append/prepend // data, then we will skip the operation. $existingData = file_get_contents($destination->fullPath()); if ($this->existingFileHasData($existingData, $this->append) || $this->existingFileHasData($existingData, $this->prepend)) { $message = " - Skip [dest-rel-path]: the file already has the append/prepend data."; return new SkipOp($message); } // Cache the original data to use during append. $this->originalContents = $existingData; return $this; } /** * Check to see if the append/prepend data has already been applied. * * @param string $contents * The contents of the target file. * @param \Drupal\Composer\Plugin\Scaffold\ScaffoldFilePath $data_path * The path to the data to append or prepend * * @return bool * 'TRUE' if the append/prepend data already exists in contents. */ protected function existingFileHasData($contents, $data_path) { if (empty($data_path)) { return FALSE; } $data = file_get_contents($data_path->fullPath()); return strpos($contents, $data) !== FALSE; } }