This repository was archived by the owner on Nov 25, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 288
/
Copy pathS3AccessDriver.php
213 lines (185 loc) · 6.77 KB
/
S3AccessDriver.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<?php
/*
* Copyright 2007-2013 Charles du Jeu - Abstrium SAS <team (at) pyd.io>
* This file is part of Pydio.
*
* Pydio is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Pydio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Pydio. If not, see <http://www.gnu.org/licenses/>.
*
* The latest code can be found at <https://pydio.com>.
*
*/
namespace Pydio\Access\Driver\StreamProvider\S3;
use DOMNode;
use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Access\Core\RecycleBinManager;
use Pydio\Access\Driver\StreamProvider\FS\FsAccessDriver;
use Pydio\Core\Model\ContextInterface;
use Pydio\Core\Services\ConfService;
use Pydio\Core\Exception\PydioException;
defined('AJXP_EXEC') or die( 'Access not allowed');
/**
* Plugin to access a webdav enabled server
* @package AjaXplorer_Plugins
* @subpackage Access
*/
class S3AccessDriver extends FsAccessDriver
{
/**
* @var \Pydio\Access\Core\Model\Repository
*/
public $repository;
public $driverConf;
protected $wrapperClassName;
protected $urlBase;
protected $s3Client;
public function performChecks()
{
// Check CURL, OPENSSL & AWS LIBRARY
if(!extension_loaded("curl")) throw new \Exception("Cannot find php_curl extension!");
}
/**
* @param ContextInterface $contextInterface
* @throws PydioException
* @throws \Exception
*/
protected function initRepository(ContextInterface $contextInterface)
{
if (is_array($this->pluginConf)) {
$this->driverConf = $this->pluginConf;
} else {
$this->driverConf = array();
}
$recycle = $contextInterface->getRepository()->getContextOption($contextInterface, "RECYCLE_BIN");
ConfService::setConf("PROBE_REAL_SIZE", false);
$this->urlBase = $contextInterface->getUrlBase();
if ($recycle!= "" && !is_dir($contextInterface->getUrlBase(). "/" . $recycle . "/")) {
@mkdir($contextInterface->getUrlBase(). "/" . $recycle . "/", 0777, true);
if(!is_dir($contextInterface->getUrlBase(). "/" . $recycle . "/")) {
throw new PydioException("Cannot create recycle bin folder. Please check repository configuration or that your folder is writeable!");
} else {
$this->setHiddenAttribute(new AJXP_Node($contextInterface->getUrlBase(). "/" . $recycle . "/"));
}
}
if ($recycle != "") {
RecycleBinManager::init($contextInterface->getUrlBase(), "/".$recycle);
}
}
/**
* @return Aws\Common\Client\AbstractClient
*/
public function getS3Service(){
return $this->s3Client;
}
/**
* @param AJXP_Node $node
* @return int
*/
public function directoryUsage(AJXP_Node $node){
$client = $this->getS3Service();
$bucket = $node->getRepository()->getContextOption($node->getContext(), "CONTAINER"); //(isSet($repositoryResolvedOptions["CONTAINER"])?$repositoryResolvedOptions["CONTA$
$path = rtrim($node->getRepository()->getContextOption($node->getContext(), "PATH"), "/").$node->getPath(); //(isSet($repositoryResolvedOptions["PATH"])?$repositoryRes$
$usage = 0;
if(!empty($client)){
$objects = $client->getIterator('ListObjects', array(
'Bucket' => $bucket,
'Prefix' => $path
));
foreach ($objects as $object) {
$usage += (double)$object['Size'];
}
}
return $usage;
}
/**
* @inheritdoc
*/
protected function parseSpecificContributions(ContextInterface $ctx, \DOMNode &$contribNode)
{
parent::parseSpecificContributions($ctx, $contribNode);
if($contribNode->nodeName != "actions") return ;
$this->disableArchiveBrowsingContributions($contribNode);
}
/**
* We have to overwrite original FS function as S3 wrapper does not support "a+" open mode.
*
* @param String $folder Folder destination
* @param String $source Maybe updated by the function
* @param String $target Existing part to append data
* @return bool If the target file already existed or not.
* @throws \Exception
*/
protected function appendUploadedData($folder, $source, $target){
$already_existed = false;
if($source == $target){
throw new \Exception("Something nasty happened: trying to copy $source into itself, it will create a loop!");
}
// S3 does not really support append. Let's grab the remote target first.
if (file_exists($folder ."/" . $target)) {
$already_existed = true;
$this->logDebug("Should copy stream from $source to $target - folder is ($folder)");
$partO = fopen($folder."/".$source, "r");
$appendF = fopen($folder ."/". $target, 'a');
while (!feof($partO)) {
$buf = fread($partO, 1024);
fwrite($appendF, $buf);
}
fclose($partO);
fclose($appendF);
$this->logDebug("Done, closing streams!");
}
@unlink($folder."/".$source);
return $already_existed;
}
/**
* @param AJXP_Node $dir
* @param string $type
* @return bool
*/
public function isWriteable(AJXP_Node $node)
{
return true;
}
/**
* @return bool
*/
public static function isRemote()
{
return true;
}
/**
* @param \Pydio\Access\Core\Model\AJXP_Node $ajxpNode
* @param bool $parentNode
* @param bool $details
* @return void
*/
public function loadNodeInfo(&$node, $parentNode = false, $details = false)
{
parent::loadNodeInfo($node, $parentNode, $details);
if (!$node->isLeaf()) {
$node->setLabel(rtrim($node->getLabel(), "/"));
}
}
/**
* @param ContextInterface $ctx
* @param array $httpVars
* @return array
* @throws \Exception
*/
public function makeSharedRepositoryOptions(ContextInterface $ctx, $httpVars)
{
$newOptions = parent::makeSharedRepositoryOptions($ctx, $httpVars);
$newOptions["CONTAINER"] = "AJXP_PARENT_OPTION:CONTAINER"; //$ctx->getRepository()->getContextOption($ctx, "CONTAINER");
return $newOptions;
}
}