openfed-8.x-8.5/scripts/composer/OpenfedUpdate.php

scripts/composer/OpenfedUpdate.php
<?php

namespace OpenfedProject\composer;

use Composer\Script\Event;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\DrupalKernel;
use Symfony\Component\HttpFoundation\Request;

/**
 * A class to update composer files to the newer version of Openfed.
 */
class OpenfedUpdate {

  /**
   * Openfed project github URL.
   *
   * @var string
   */
  protected static $openfedRepo = 'https://github.com/openfed/openfed-project';

  /**
   * Openfed project github archive tags URL.
   *
   * @var string
   */
  protected static $openfedZip = 'https://github.com/openfed/openfed-project/archive/refs/tags/';

  /**
   * The latest Openfed version.
   *
   * @var string
   */
  protected static $latestOpenfedVersion;

  /**
   * @var string
   */
  protected static $currentOpenfedVersion;

  /**
   * Update current openfed project files.
   *
   * @param \Composer\Script\Event $event
   *   The composer script event.
   */
  public static function update(Event $event) {
    self::getCurrentVersion();
    self::setLatestOpenfedVersion();

    // Check if there's a new Openfed version and update if so.
    if (self::newVersionExists()) {
      self::overwriteFiles();
    }
  }

  /**
   * Update current openfed project files.
   *
   * @param \Composer\Script\Event $event
   *   The composer script event.
   */
  public static function upgrade(Event $event) {
    self::getCurrentVersion();
    self::setLatestOpenfedVersion(true);

    // Check if there's a new Openfed version and update if so.
    if (self::newVersionExists()) {
      self::overwriteFiles();
    }
  }

  private static function overwriteFiles() {
    echo "\n\n---- Project files will be updated to Openfed version " . self::$latestOpenfedVersion . "\n";

    $url = self::$openfedZip . self::$latestOpenfedVersion . '.zip';
    $zipFile = self::$latestOpenfedVersion . '.zip';
    $extractPath = self::$latestOpenfedVersion;

    $zip_resource = fopen($zipFile, "w");

    self::initDrupalContainer();
    /** @var GuzzleHttp\Psr\Response $response */
    $response = \Drupal::httpClient()->get($url, ['sink' => $zip_resource]);

    if (!$response) {
      echo "Error :- Cannot connect.";
    }

    $zip = new \ZipArchive();
    if ($zip->open($zipFile) != "true") {
      throw new \ErrorException("Error :- Unable to open the Zip File.");
    }

    $zip->extractTo($extractPath);
    $zip->close();

    // We'll merge the contents of the zip archive, but we'll ignore some
    // files. Those files will be removed/unlink.
    unlink($zipFile);
    unlink($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion . DIRECTORY_SEPARATOR . '.gitignore');
    unlink($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion . DIRECTORY_SEPARATOR . 'README.md');

    // Composer.json and composer.patches.json, if exists, will be merged.
    // This is a best effort merge and should be manually confirmed.
    self::mergeComposer($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion . DIRECTORY_SEPARATOR . 'composer.json', '.' . DIRECTORY_SEPARATOR . 'composer.json');
    unlink($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion . DIRECTORY_SEPARATOR . 'composer.json');
    self::mergeComposer($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion . DIRECTORY_SEPARATOR . 'composer.patches.json', '.' . DIRECTORY_SEPARATOR . 'composer.patches.json');
    unlink($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion . DIRECTORY_SEPARATOR . 'composer.patches.json');

    // All the remaining files will be copied as is (i.e.
    // composer.openfed.json)
    self::recurseCopy($extractPath . DIRECTORY_SEPARATOR . 'openfed-project-' . self::$latestOpenfedVersion, '.');
    self::deleteDirectory($extractPath);

    echo "---- Files updated. You still have to check your composer.json manually.\n\n";
  }

  /**
   * Merge composer files, keeping existing values.
   *
   * @param string $new
   *   New composer file, from github repo.
   * @param string $old
   *   Old composer file, the one in the filesystem.
   */
  private static function mergeComposer($new, $old) {
    $new_composer = json_decode(file_get_contents($new), TRUE);
    $old_composer = json_decode(file_get_contents($old), TRUE);

    $updated_composer = NestedArray::mergeDeepArray([
      $old_composer,
      $new_composer,
    ], TRUE);
    file_put_contents($old, json_encode($updated_composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
  }

  /**
   * Copy files from one dir to another.
   *
   * @param string $src
   *   Source directory.
   * @param string $dst
   *   Destination directory.
   */
  private static function recurseCopy($src, $dst) {
    $dir = opendir($src);
    @mkdir($dst);
    while (FALSE !== ($file = readdir($dir))) {
      if (($file != '.') && ($file != '..')) {
        if (is_dir($src . DIRECTORY_SEPARATOR . $file)) {
          self::recurseCopy($src . DIRECTORY_SEPARATOR . $file, $dst . DIRECTORY_SEPARATOR . $file);
        }
        else {
          copy($src . DIRECTORY_SEPARATOR . $file, $dst . DIRECTORY_SEPARATOR . $file);
        }
      }
    }
    closedir($dir);
  }

  /**
   * Delete directory from filesystem.
   *
   * @param string $dir
   *   The directory to remove.
   *
   * @return bool
   *   True on success, false otherwise.
   */
  public static function deleteDirectory($dir) {
    if (!file_exists($dir)) {
      return TRUE;
    }
    if (!is_dir($dir)) {
      return unlink($dir);
    }
    foreach (scandir($dir) as $item) {
      if ($item == '.' || $item == '..') {
        continue;
      }
      if (!self::deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
        return FALSE;
      }
    }
    return rmdir($dir);
  }

  /**
   * Checks if there's a more recent version of Openfed.
   *
   * @return bool
   *   True if there's a new version, false otherwise.
   */
  private static function newVersionExists() {
    $current_version = self::$currentOpenfedVersion;

    // If current version is dev, we don't need to check if there's a newer
    // version.
    if (strpos($current_version, 'dev') !== FALSE) {
      return FALSE;
    }

    return version_compare(self::$latestOpenfedVersion, $current_version, '>');
  }

  /**
   * Checks if there's a more recent version of Openfed.
   *
   * @return bool
   *   True if there's a new version, false otherwise.
   */
  private static function getCurrentVersion() {
    $composer_openfed = json_decode(file_get_contents('composer.openfed.json'), TRUE);
    $current_version = $composer_openfed['require']['openfed/openfed'];

    self::$currentOpenfedVersion = $current_version;
  }

  /**
   * Set the latest openfed version variable.
   */
  private static function setLatestOpenfedVersion($upgrade = false) {
    $available_openfed_version = $latest_openfed_version = explode("\n", trim(shell_exec("git -c 'versionsort.suffix=-' ls-remote --tags --sort='-v:refname' " . self::$openfedRepo . " | cut -d '/' -f 3 | grep -v -")));

    // If this is an upgrade, we don't need to filter by the current major
    // version.
    if (!$upgrade) {
      // Get the current major version.
      $current_major_version = strstr(self::$currentOpenfedVersion,'.', true) . '.';

      // On updates we need to filter openfed versions that match the current
      // major version.
      $latest_openfed_version = array_filter($available_openfed_version, function($version) use ($current_major_version) {
        return (strpos($version, $current_major_version) === 0 ? true : false);
      });
    }

    self::$latestOpenfedVersion = current($latest_openfed_version);
  }

  /**
   * Initiates Drupal container.
   *
   * @throws \Exception
   */
  private static function initDrupalContainer() {
    $autoloader = require_once getcwd() . '/docroot/autoload.php';
    $request = Request::createFromGlobals();
    $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
    $kernel->boot();
    $kernel->preHandle($request);
    if (PHP_SAPI !== 'cli') {
      $request->setSession($kernel->getContainer()->get('session'));
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc