3 namespace wcf\system\setup
;
5 use wcf\system\exception\SystemException
;
10 * Extracts files and directories from a tar archive.
13 * @copyright 2001-2019 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
19 * directory the files are installed into
25 * name of the source tar archive
31 * folder within source that limits the installed files to those within
38 * file handler of the installed files
39 * @var \wcf\system\setup\IFileHandler
41 protected $fileHandler;
44 * Creates a new Installer object.
46 * @param string $targetDir
47 * @param string $source
48 * @param IFileHandler $fileHandler
49 * @param string $folder
51 public function __construct($targetDir, $source, $fileHandler = null, $folder = '')
53 $this->targetDir
= FileUtil
::addTrailingSlash($targetDir);
54 $this->source
= $source;
55 $this->folder
= $folder;
56 $this->fileHandler
= $fileHandler;
61 * Creates the target directory if necessary.
63 protected function createTargetDir()
65 if (!@\
is_dir($this->targetDir
)) {
66 if (!FileUtil
::makePath($this->targetDir
)) {
67 throw new SystemException("Could not create dir '" . $this->targetDir
. "'");
70 if (FileUtil
::isApacheModule() ||
!\
is_writable($this->targetDir
)) {
71 $this->makeWriteable($this->targetDir
);
76 * Creates a directory in the target directory.
79 * @throws SystemException
81 protected function createDir($dir)
83 if (!@\
is_dir($this->targetDir
. $dir)) {
84 $oldumask = \
umask(0);
85 if (!@\
mkdir($this->targetDir
. $dir, 0755, true)) {
86 throw new SystemException("Could not create dir '" . $this->targetDir
. $dir . "'");
90 if (FileUtil
::isApacheModule() ||
!\
is_writable($this->targetDir
. $dir)) {
91 $this->makeWriteable($this->targetDir
. $dir);
96 * Touches a file in the target directory.
100 public function touchFile($file)
102 @\touch
($this->targetDir
. $file);
103 $this->makeWriteable($this->targetDir
. $file);
107 * Creates a file in the target directory.
109 * @param string $file
113 protected function createFile($file, $index, Tar
$tar)
115 $tar->extract($index, $this->targetDir
. $file);
116 if (FileUtil
::isApacheModule() ||
!\
is_writable($this->targetDir
. $file)) {
117 $this->makeWriteable($this->targetDir
. $file);
122 * Starts the extracting of the files.
124 protected function install()
126 $this->createTargetDir();
128 // open source archive
129 $tar = $this->getTar($this->source
);
131 // distinct directories and files
134 foreach ($tar->getContentList() as $index => $file) {
135 if (empty($this->folder
) || \
str_starts_with($file['filename'], $this->folder
)) {
136 if (!empty($this->folder
)) {
137 $file['filename'] = \
str_replace($this->folder
, '', $file['filename']);
140 // remove leading slash
141 $file['filename'] = FileUtil
::getRealPath(FileUtil
::removeLeadingSlash($file['filename']));
142 if ($file['type'] == 'folder') {
143 // remove trailing slash
144 $directories[] = FileUtil
::removeTrailingSlash($file['filename']);
146 $files[$index] = $file['filename'];
151 $this->checkFiles($files);
153 // now create the directories
155 foreach ($directories as $dir) {
157 $this->createDir($dir);
158 } catch (SystemException
$e) {
159 $errors[] = $e->getMessage();
163 // now untar all files
164 foreach ($files as $index => $file) {
166 $this->createFile($file, $index, $tar);
167 } catch (SystemException
$e) {
168 $errors[] = $e->getMessage();
171 if (!empty($errors)) {
172 throw new SystemException('error(s) during the installation of the files.', 0, \
implode("<br>", $errors));
175 $this->logFiles($files);
182 * Opens a new tar archive.
184 * @param string $source
187 protected function getTar($source)
189 return new Tar($source);
193 * Checks whether the given files overwriting locked existing files.
195 * @param array $files
197 protected function checkFiles(&$files)
199 if ($this->fileHandler
!= null && $this->fileHandler
instanceof IFileHandler
) {
200 $this->fileHandler
->checkFiles($files);
205 * Logs the given files.
207 * @param array $files
209 protected function logFiles(&$files)
211 if ($this->fileHandler
!= null && $this->fileHandler
instanceof IFileHandler
) {
212 $this->fileHandler
->logFiles($files);
217 * Makes a file or directory writeable.
219 * @param string $target
221 protected function makeWriteable($target)
223 FileUtil
::makeWritable($target);