Skip to content
This repository was archived by the owner on Nov 25, 2020. It is now read-only.

Commit c5700d3

Browse files
committed
Merge branch 'jscore-deprototype' of https://github.com/pydio/pydio-core into jscore-deprototype
2 parents c2322a3 + 93afb31 commit c5700d3

File tree

7 files changed

+561
-12
lines changed

7 files changed

+561
-12
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
<?php
2+
/*
3+
* Copyright 2007-2013 Charles du Jeu - Abstrium SAS <team (at) pyd.io>
4+
* This file is part of Pydio.
5+
*
6+
* Pydio is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Pydio is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Affero General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with Pydio. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
* The latest code can be found at <http://pyd.io/>.
20+
*/
21+
22+
defined('AJXP_EXEC') or die('Access not allowed');
23+
24+
/**
25+
* Plugin to compress to TAR or TAR.GZ or TAR.BZ2... He can also extract your archives
26+
* @package AjaXplorer_Plugins
27+
* @subpackage Action
28+
*/
29+
class PluginCompression extends AJXP_Plugin
30+
{
31+
/**
32+
* @param String $action
33+
* @param Array $httpVars
34+
* @param Array $fileVars
35+
* @throws Exception
36+
*/
37+
public function receiveAction($action, $httpVars, $fileVars)
38+
{
39+
//TODO : DESTROY THE PROGRESS FILE AT THE END OF THE PROCESS + POSSIBILITY TO CANCEL COMPRESS TO HAVE JUST THE TAR FILE
40+
//VAR CREATION OUTSIDE OF ALL CONDITIONS, THEY ARE MUST HAVE VAR !!
41+
$messages = ConfService::getMessages();
42+
$repository = ConfService::getRepository();
43+
$userSelection = new UserSelection($repository, $httpVars);
44+
$nodes = $userSelection->buildNodes();
45+
$currentDirPath = AJXP_Utils::safeDirname($userSelection->getUniqueNode()->getPath());
46+
$currentDirPath = rtrim($currentDirPath, "/") . "/";
47+
$currentDirUrl = $userSelection->currentBaseUrl().$currentDirPath;
48+
if (empty($httpVars["compression_id"])) {
49+
$compressionId = sha1(rand());
50+
$httpVars["compression_id"] = $compressionId;
51+
} else {
52+
$compressionId = $httpVars["compression_id"];
53+
}
54+
$progressCompressionFileName = $this->getPluginCacheDir(false, true) . DIRECTORY_SEPARATOR . "progressCompressionID-" . $compressionId . ".txt";
55+
if (empty($httpVars["extraction_id"])) {
56+
$extractId = sha1(rand());
57+
$httpVars["extraction_id"] = $extractId;
58+
} else {
59+
$extractId = $httpVars["extraction_id"];
60+
}
61+
$progressExtractFileName = $this->getPluginCacheDir(false, true) . DIRECTORY_SEPARATOR . "progressExtractID-" . $extractId . ".txt";
62+
if ($action == "compression") {
63+
$archiveName = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic($httpVars["archiveName"]), AJXP_SANITIZE_FILENAME);
64+
$archiveFormat = $httpVars["type_archive"];
65+
$tabTypeArchive = [".tar", ".tar.gz", ".tar.bz2"];
66+
$acceptedExtension = false;
67+
foreach ($tabTypeArchive as $extensionArchive) {
68+
if ($extensionArchive == $archiveFormat) {
69+
$acceptedExtension = true;
70+
break;
71+
}
72+
}
73+
if ($acceptedExtension == false) {
74+
throw new AJXP_Exception($messages["compression.16"]);
75+
}
76+
$typeArchive = $httpVars["type_archive"];
77+
//if we can run in background we do it
78+
if (ConfService::backgroundActionsSupported() && !ConfService::currentContextIsCommandLine()) {
79+
$archivePath = $currentDirPath.$archiveName;
80+
file_put_contents($progressCompressionFileName, $messages["compression.5"]);
81+
AJXP_Controller::applyActionInBackground($repository->getId(), "compression", $httpVars);
82+
AJXP_XMLWriter::header();
83+
AJXP_XMLWriter::triggerBgAction("check_compression_status", array(
84+
"repository_id" => $repository->getId(),
85+
"compression_id" => $compressionId,
86+
"archive_path" => SystemTextEncoding::toUTF8($archivePath)
87+
), $messages["compression.5"], true, 4);
88+
AJXP_XMLWriter::close();
89+
return null;
90+
} else {
91+
$maxAuthorizedSize = 4294967296;
92+
$currentDirUrlLength = strlen($currentDirUrl);
93+
$tabFolders = [];
94+
$tabAllRecursiveFiles = [];
95+
$tabFilesNames = [];
96+
foreach ($nodes as $node) {
97+
$nodeUrl = $node->getUrl();
98+
if (is_file($nodeUrl) && filesize($nodeUrl) < $maxAuthorizedSize) {
99+
array_push($tabAllRecursiveFiles, $nodeUrl);
100+
array_push($tabFilesNames, substr($nodeUrl, $currentDirUrlLength));
101+
}
102+
if (is_dir($nodeUrl)) {
103+
array_push($tabFolders, $nodeUrl);
104+
}
105+
}
106+
//DO A FOREACH OR IT'S GONNA HAVE SOME SAMES FILES NAMES
107+
foreach ($tabFolders as $value) {
108+
$dossiers = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($value));
109+
foreach ($dossiers as $file) {
110+
if ($file->isDir()) {
111+
continue;
112+
}
113+
array_push($tabAllRecursiveFiles, $file->getPathname());
114+
array_push($tabFilesNames, substr($file->getPathname(), $currentDirUrlLength));
115+
}
116+
}
117+
try {
118+
$tmpArchiveName = tempnam(AJXP_Utils::getAjxpTmpDir(), "tar-compression") . ".tar";
119+
$archive = new PharData($tmpArchiveName);
120+
} catch (Exception $e) {
121+
throw $e;
122+
}
123+
$counterCompression = 0;
124+
//THE TWO ARRAY ARE MERGED FOR THE FOREACH LOOP
125+
$tabAllFiles = array_combine($tabAllRecursiveFiles, $tabFilesNames);
126+
foreach ($tabAllFiles as $fullPath => $fileName) {
127+
try {
128+
$archive->addFile(AJXP_MetaStreamWrapper::getRealFSReference($fullPath), $fileName);
129+
$counterCompression++;
130+
file_put_contents($progressCompressionFileName, sprintf($messages["compression.6"], ($counterCompression / count($tabAllFiles)) * 100 . " %"));
131+
} catch (Exception $e) {
132+
unlink($tmpArchiveName);
133+
throw $e;
134+
}
135+
}
136+
$finalArchive = $tmpArchiveName;
137+
if ($typeArchive != ".tar") {
138+
$archiveTypeCompress = substr(strrchr($typeArchive, "."), 1);
139+
file_put_contents($progressCompressionFileName, sprintf($messages["compression.7"], strtoupper($archiveTypeCompress)));
140+
if ($archiveTypeCompress == "gz") {
141+
$archive->compress(Phar::GZ);
142+
} elseif ($archiveTypeCompress == "bz2") {
143+
$archive->compress(Phar::BZ2);
144+
}
145+
$finalArchive = $tmpArchiveName . "." . $archiveTypeCompress;
146+
}
147+
$destArchive = AJXP_MetaStreamWrapper::getRealFSReference($currentDirUrl . $archiveName);
148+
rename($finalArchive, $destArchive);
149+
AJXP_Controller::applyHook("node.before_create", array($destArchive, filesize($destArchive)));
150+
if (file_exists($tmpArchiveName)) {
151+
unlink($tmpArchiveName);
152+
unlink(substr($tmpArchiveName, 0, -4));
153+
}
154+
$newNode = new AJXP_Node($currentDirUrl . $archiveName);
155+
AJXP_Controller::applyHook("node.change", array(null, $newNode, false));
156+
file_put_contents($progressCompressionFileName, "SUCCESS");
157+
}
158+
}
159+
elseif ($action == "check_compression_status") {
160+
$archivePath = AJXP_Utils::decodeSecureMagic($httpVars["archive_path"]);
161+
$progressCompression = file_get_contents($progressCompressionFileName);
162+
if ($progressCompression != "SUCCESS") {
163+
AJXP_XMLWriter::header();
164+
AJXP_XMLWriter::triggerBgAction("check_compression_status", array(
165+
"repository_id" => $repository->getId(),
166+
"compression_id" => $compressionId,
167+
"archive_path" => SystemTextEncoding::toUTF8($archivePath)
168+
), $progressCompression, true, 3);
169+
AJXP_XMLWriter::close();
170+
} else {
171+
$newNode = new AJXP_Node($userSelection->currentBaseUrl() . $archivePath);
172+
$nodesDiffs = array("ADD" => array($newNode), "REMOVE" => array(), "UPDATE" => array());
173+
AJXP_Controller::applyHook("node.change", array(null, $newNode, false));
174+
AJXP_XMLWriter::header();
175+
AJXP_XMLWriter::sendMessage($messages["compression.8"], null);
176+
AJXP_XMLWriter::writeNodesDiff($nodesDiffs, false);
177+
AJXP_XMLWriter::close();
178+
unlink($progressCompressionFileName);
179+
}
180+
}
181+
elseif ($action == "extraction") {
182+
$fileArchive = AJXP_Utils::sanitize(AJXP_Utils::decodeSecureMagic($httpVars["file"]), AJXP_SANITIZE_DIRNAME);
183+
$fileArchive = substr(strrchr($fileArchive, DIRECTORY_SEPARATOR), 1);
184+
$authorizedExtension = ["tar" => 4, "gz" => 7, "bz2" => 8];
185+
$acceptedArchive = false;
186+
$extensionLength = 0;
187+
$counterExtract = 0;
188+
$currentAllPydioPath = $currentDirUrl . $fileArchive;
189+
$pharCurrentAllPydioPath = "phar://" . AJXP_MetaStreamWrapper::getRealFSReference($currentAllPydioPath);
190+
$pathInfoCurrentAllPydioPath = pathinfo($currentAllPydioPath)["extension"];
191+
//WE TAKE ONLY TAR, TAR.GZ AND TAR.BZ2 ARCHIVES
192+
foreach ($authorizedExtension as $extension => $strlenExtension) {
193+
if ($pathInfoCurrentAllPydioPath == $extension) {
194+
$acceptedArchive = true;
195+
$extensionLength = $strlenExtension;
196+
break;
197+
}
198+
}
199+
if ($acceptedArchive == false) {
200+
throw new AJXP_Exception($messages["compression.15"]);
201+
}
202+
$onlyFileName = substr($fileArchive, 0, -$extensionLength);
203+
$lastPosOnlyFileName = strrpos($onlyFileName, "-");
204+
$tmpOnlyFileName = substr($onlyFileName, 0, $lastPosOnlyFileName);
205+
$counterDuplicate = substr($onlyFileName, $lastPosOnlyFileName + 1);
206+
if ($lastPosOnlyFileName == false) {
207+
$tmpOnlyFileName = $onlyFileName;
208+
$counterDuplicate = 1;
209+
}
210+
while (file_exists($currentDirUrl . $onlyFileName)) {
211+
$onlyFileName = $tmpOnlyFileName . "-" . $counterDuplicate;
212+
$counterDuplicate++;
213+
}
214+
if (ConfService::backgroundActionsSupported() && !ConfService::currentContextIsCommandLine()) {
215+
file_put_contents($progressExtractFileName, $messages["compression.12"]);
216+
AJXP_Controller::applyActionInBackground($repository->getId(), "extraction", $httpVars);
217+
AJXP_XMLWriter::header();
218+
AJXP_XMLWriter::triggerBgAction("check_extraction_status", array(
219+
"repository_id" => $repository->getId(),
220+
"extraction_id" => $extractId,
221+
"currentDirUrl" => $currentDirUrl,
222+
"onlyFileName" => $onlyFileName
223+
), $messages["compression.12"], true, 3);
224+
AJXP_XMLWriter::close();
225+
return null;
226+
}
227+
mkdir($currentDirUrl . $onlyFileName, 0777, true);
228+
chmod(AJXP_MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), 0777);
229+
try {
230+
$archive = new PharData(AJXP_MetaStreamWrapper::getRealFSReference($currentAllPydioPath));
231+
$fichiersArchive = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pharCurrentAllPydioPath));
232+
foreach ($fichiersArchive as $file) {
233+
$fileGetPathName = $file->getPathname();
234+
if($file->isDir()) {
235+
continue;
236+
}
237+
$fileNameInArchive = substr(strstr($fileGetPathName, $fileArchive), strlen($fileArchive) + 1);
238+
var_dump($currentDirUrl . $onlyFileName . DIRECTORY_SEPARATOR . $fileNameInArchive);
239+
$archive->extractTo(AJXP_MetaStreamWrapper::getRealFSReference($currentDirUrl . $onlyFileName), $fileNameInArchive, false);
240+
$newNode = new AJXP_Node($currentDirUrl . $onlyFileName . DIRECTORY_SEPARATOR . $fileNameInArchive);
241+
AJXP_Controller::applyHook("node.change", array(null, $newNode, false));
242+
$counterExtract++;
243+
file_put_contents($progressExtractFileName, sprintf($messages["compression.12"], ($counterExtract / $archive->count()) * 100 . " %"));
244+
}
245+
} catch (Exception $e) {
246+
throw new AJXP_Exception($e);
247+
}
248+
file_put_contents($progressExtractFileName, "SUCCESS");
249+
}
250+
elseif ($action == "check_extraction_status") {
251+
$currentDirUrl = $httpVars["currentDirUrl"];
252+
$onlyFileName = $httpVars["onlyFileName"];
253+
$progressExtract = file_get_contents($progressExtractFileName);
254+
if ($progressExtract != "SUCCESS") {
255+
AJXP_XMLWriter::header();
256+
AJXP_XMLWriter::triggerBgAction("check_extraction_status", array(
257+
"repository_id" => $repository->getId(),
258+
"extraction_id" => $extractId,
259+
"currentDirUrl" => $currentDirUrl,
260+
"onlyFileName" => $onlyFileName
261+
), $progressExtract, true, 3);
262+
AJXP_XMLWriter::close();
263+
} else {
264+
$newNode = new AJXP_Node($currentDirUrl . $onlyFileName);
265+
$nodesDiffs = array("ADD" => array($newNode), "REMOVE" => array(), "UPDATE" => array());
266+
AJXP_Controller::applyHook("node.change", array(null, $newNode, false));
267+
AJXP_XMLWriter::header();
268+
AJXP_XMLWriter::sendMessage(sprintf($messages["compression.14"], $onlyFileName), null);
269+
AJXP_XMLWriter::writeNodesDiff($nodesDiffs, false);
270+
AJXP_XMLWriter::close();
271+
if (file_exists($progressExtractFileName)) {
272+
unlink($progressExtractFileName);
273+
}
274+
}
275+
}
276+
}
277+
}

0 commit comments

Comments
 (0)