5

I need to programmatically download projects from drupal.org, and then eventually enable it with modules_enable. Anyone knows how to do it?

Here's the final solution : I'm sharing the code i used for those who'll face the same problem.

    /**
     * 
     * Function downloading the last version of the module in MY_MODULE_MODULE_DIRECTORY
     * $modulename correspond au nom system du module
     *
     * @param string $modulename
     */
    function MY_MODULE_download_module($modulename) {
      // DEBUT CODE TELECHARGEMENT

      $base_url = 'http://updates.drupal.org/release-history/' . $modulename . '/7.x';
      // @TODO MODULE NAME

      $xml = drupal_http_request($base_url);
      if (!isset($xml->error) && isset($xml->data)) {
        $data = $xml->data;
      }
      try {
        $xml = new SimpleXMLElement($data);
      }
      catch (Exception $e) {
        // SimpleXMLElement::__construct produces an E_WARNING error message for
        // each error found in the XML data and throws an exception if errors
        // were detected. Catch any exception and return failure (NULL).
        return;
      }
      $json = json_encode($xml);
      $array = json_decode($json, TRUE);
      $download_link = $array['releases']['release'][0]['download_link'];

      $path = MY_MODULE_contrib_dowload($download_link);
      MY_MODULE_archive_extract($path, MY_MODULE_MODULE_DIRECTORY);

      // FIN CODE TELECHARGEMENT
    }

    /**
     * Fonction downloading a file
     * Inspired from update_manager_file_get($url).
     * Upload the file in the temporary folder
     *
     * @param url $url
     */
    function MY_MODULE_contrib_dowload($url) {
      $parsed_url = parse_url($url);
      $remote_schemes = array(
        'http',
        'https',
        'ftp',
        'ftps',
        'smb',
        'nfs'
      );
      if (!in_array($parsed_url['scheme'], $remote_schemes)) {
        // This is a local file, just return the path.
        return drupal_realpath($url);
      }

      $cache_directory = _update_manager_cache_directory();
      $local = $cache_directory . '/' . drupal_basename($parsed_url['path']);
      // load the file in the right directory

      return system_retrieve_file($url, $local, FALSE, FILE_EXISTS_REPLACE);
    }

    /**
     * Function inspired from update_manager_archive_extract($file, $directory)
     * extracts a file to a directory
     *
     * @param path_to_file $file
     * @param path_to_directory $directory
     * @throws Exception
     * @return A path
     */
    function MY_MODULE_archive_extract($file, $directory) {
      $archiver = archiver_get_archiver($file);
      if (!$archiver) {
        throw new Exception(t('Cannot extract %file, not a valid archive.', array(
          '%file' => $file
        )));
      }

      // Remove the directory if it exists, otherwise it might contain a mixture of
      // old files mixed with the new files (e.g. in cases where files were removed
      // from a later release).
      $files = $archiver->listContents();

      // Unfortunately, we can only use the directory name to determine the project
      // name. Some archivers list the first file as the directory (i.e., MODULE/)
      // and others list an actual file (i.e., MODULE/README.TXT).
      $project = strtok($files[0], '/\\');

      $extract_location = $directory . '/' . $project;
      if (file_exists($extract_location)) {
        file_unmanaged_delete_recursive($extract_location);
      }

      $archiver->extract($directory);
      return $archiver;
    }

2 Answers 2

10

Normally you want to use drush, e.g.

drush -y en module_name

which would download, install and enable your module of interest.

Check drush.api.php to use appropriate API hooks which could be useful.

If you don't want to use Drush, check how Update Manager does that in update/update.manager.inc, e.g.

To get the list of available files to download for specific project you've to fetch and parse the release history which is available at:

https://updates.drupal.org/release-history/project_name/7.x

the same as drush does that (check by drush -vd dl foo) and get the links from there.

0
2

With drupal 8 I fell in love with drupal console.

The output is much clearer and it provides you with suggestion (and sometimes completion) on the arguments.

To download a module using console the long command is: drupal module:download module_name and the short command is: drupal m:download module_name

Console provides you with the downloadable versions of that module and asks you which you want to download.

To install a module using console the long command is: drupal module:install module_name. and the short command is drupal m:i

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.