Pull merge.
[yaffs-website] / web / modules / contrib / hacked / src / hackedProjectWebFilesDownloader.php
1 <?php
2
3 namespace Drupal\hacked;
4
5 use Drupal\Component\Utility\Unicode;
6 use Exception;
7
8 /**
9  * Downloads a project using a standard Drupal method.
10  */
11 class hackedProjectWebFilesDownloader extends hackedProjectWebDownloader {
12   function download_link() {
13     if (!empty($this->project->project_info['releases'][$this->project->existing_version])) {
14       $this_release = $this->project->project_info['releases'][$this->project->existing_version];
15       return $this_release['download_link'];
16     }
17   }
18
19   function download() {
20     $dir = $this->get_destination();
21     if (!($release_url = $this->download_link())) {
22       return FALSE;
23     }
24
25     // If our directory already exists, we can just return the path to this cached version
26     if (file_exists($dir) && count(hacked_file_scan_directory($dir, '/.*/', [
27         '.',
28         '..',
29         'CVS',
30         '.svn',
31         '.git'
32       ]))
33     ) {
34       return $dir;
35     }
36
37     // Build the destination folder tree if it doesn't already exists.
38     if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY) && !mkdir($dir, 0775, TRUE)) {
39       $message = $this->t('Failed to create temp directory: %dir', ['%dir' => $dir]);
40       \Drupal::logger('hacked')->error($message->render());
41       return FALSE;
42     }
43
44     if (!($local_file = $this->file_get($release_url))) {
45       $message = $this->t('Could not download the project: @name from URL: @url', [
46         '@name' => $this->project->title(),
47         '@url'  => $release_url
48       ]);
49       \Drupal::logger('hacked')->error($message->render());
50       return FALSE;
51     }
52     try {
53       $this->archive_extract($local_file, $dir);
54     }
55     catch (Exception $e) {
56       $message = $this->t('Could not extract the project: @name. Error was: !error', [
57         '@name'  => $this->project->title(),
58         '!error' => $e->getMessage()
59       ]);
60       \Drupal::logger('hacked')->error($message->render());
61       return FALSE;
62     }
63
64     return TRUE;
65   }
66
67   /**
68    * Copies a file from $url to the temporary directory for updates.
69    *
70    * If the file has already been downloaded, returns the the local path.
71    *
72    * @param $url
73    *   The URL of the file on the server.
74    *
75    * @return string
76    *   Path to local file.
77    */
78   function file_get($url) {
79     $parsed_url = parse_url($url);
80     $remote_schemes = ['http', 'https', 'ftp', 'ftps', 'smb', 'nfs'];
81     if (!in_array($parsed_url['scheme'], $remote_schemes)) {
82       // This is a local file, just return the path.
83       return \Drupal::service('file_system')->realpath($url);
84     }
85
86     // Check the cache and download the file if needed.
87     $cache_directory = 'temporary://hacked-cache';
88     $local = $cache_directory . '/' . basename($parsed_url['path']);
89
90     if (!file_exists($cache_directory)) {
91       mkdir($cache_directory);
92     }
93
94     return system_retrieve_file($url, $local, FALSE, FILE_EXISTS_REPLACE);
95   }
96
97   /**
98    * Unpack a downloaded archive file.
99    *
100    * @param string $file
101    *   The filename of the archive you wish to extract.
102    * @param string $directory
103    *   The directory you wish to extract the archive into.
104    * @return Archiver
105    *   The Archiver object used to extract the archive.
106    * @throws Exception on failure.
107    */
108   function archive_extract($file, $directory) {
109     $archiver = archiver_get_archiver($file);
110     if (!$archiver) {
111       throw new Exception(t('Cannot extract %file, not a valid archive.', ['%file' => $file]));
112     }
113
114     // Remove the directory if it exists, otherwise it might contain a mixture of
115     // old files mixed with the new files (e.g. in cases where files were removed
116     // from a later release).
117     $files = $archiver->listContents();
118     // Unfortunately, we can only use the directory name for this. :(
119     $project = Unicode::substr($files[0], 0, -1);
120     $extract_location = $directory . '/' . $project;
121     if (file_exists($extract_location)) {
122       file_unmanaged_delete_recursive($extract_location);
123     }
124
125     $archiver->extract($directory);
126     return $archiver;
127   }
128
129
130 }