1
|
|
|
<?php |
2
|
|
|
class VersionedFileUploadField extends UploadField |
3
|
|
|
{ |
4
|
|
|
private static $allowed_actions = array( |
|
|
|
|
5
|
|
|
'upload' |
6
|
|
|
); |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* The file to upload a new version of |
10
|
|
|
* @var File |
11
|
|
|
*/ |
12
|
|
|
public $currentVersionFile; |
13
|
|
|
|
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Action to handle upload of a single file |
17
|
|
|
* |
18
|
|
|
* @param SS_HTTPRequest $request |
19
|
|
|
* @return string json |
20
|
|
|
*/ |
21
|
|
|
public function upload(SS_HTTPRequest $request) |
22
|
|
|
{ |
23
|
|
|
if (!$this->currentVersionFile) { |
24
|
|
|
return; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
|
28
|
|
|
if ($this->isDisabled() || $this->isReadonly()) { |
29
|
|
|
return $this->httpError(403); |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
// Protect against CSRF on destructive action |
33
|
|
|
$token = $this->getForm()->getSecurityToken(); |
34
|
|
|
if (!$token->checkRequest($request)) { |
35
|
|
|
return $this->httpError(400); |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
$name = $this->getName(); |
39
|
|
|
$tmpfile = $request->postVar($name); |
40
|
|
|
$record = $this->getRecord(); |
41
|
|
|
|
42
|
|
|
// Check if the file has been uploaded into the temporary storage. |
43
|
|
|
if (!$tmpfile) { |
44
|
|
|
$return = array('error' => _t('UploadField.FIELDNOTSET', 'File information not found')); |
45
|
|
|
} else { |
46
|
|
|
$return = array( |
47
|
|
|
'name' => $tmpfile['name'], |
48
|
|
|
'size' => $tmpfile['size'], |
49
|
|
|
'type' => $tmpfile['type'], |
50
|
|
|
'error' => $tmpfile['error'] |
51
|
|
|
); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
// Check for constraints on the record to which the file will be attached. |
55
|
|
|
if (!$return['error'] && $this->relationAutoSetting && $record && $record->exists()) { |
56
|
|
|
$tooManyFiles = false; |
57
|
|
|
// Some relationships allow many files to be attached. |
58
|
|
|
if ($this->getConfig('allowedMaxFileNumber') && ($record->has_many($name) || $record->many_many($name))) { |
59
|
|
|
if (!$record->isInDB()) { |
60
|
|
|
$record->write(); |
61
|
|
|
} |
62
|
|
|
$tooManyFiles = $record->{$name}()->count() >= $this->getConfig('allowedMaxFileNumber'); |
63
|
|
|
// has_one only allows one file at any given time. |
64
|
|
|
} elseif ($record->has_one($name)) { |
65
|
|
|
$tooManyFiles = $record->{$name}() && $record->{$name}()->exists(); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
// Report the constraint violation. |
69
|
|
|
if ($tooManyFiles) { |
70
|
|
|
if (!$this->getConfig('allowedMaxFileNumber')) { |
71
|
|
|
$this->setConfig('allowedMaxFileNumber', 1); |
72
|
|
|
} |
73
|
|
|
$return['error'] = _t( |
74
|
|
|
'UploadField.MAXNUMBEROFFILES', |
75
|
|
|
'Max number of {count} file(s) exceeded.', |
76
|
|
|
array('count' => $this->getConfig('allowedMaxFileNumber')) |
77
|
|
|
); |
78
|
|
|
} |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
// Process the uploaded file |
82
|
|
|
if (!$return['error']) { |
83
|
|
|
// Get the uploaded file into a new file object. |
84
|
|
|
try { |
85
|
|
|
$currentFilePath = $this->currentVersionFile->getFullPath(); |
86
|
|
|
if (file_exists($currentFilePath)) { |
87
|
|
|
unlink($this->currentVersionFile->getFullPath()); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
// If $folderName == assets (by default), then this will try and create a file inside assets/assets |
91
|
|
|
// instead of creating it in the root. This check ensures that the newly uploaded files overwrites the |
92
|
|
|
// old file in the assets root directory. |
93
|
|
|
$folderName = $this->folderName; |
94
|
|
|
if ($folderName == basename(ASSETS_PATH)) { |
95
|
|
|
$folderName = "/"; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
$this->upload->loadIntoFile( |
99
|
|
|
array_merge($tmpfile, array('name' => $this->currentVersionFile->Name)), |
100
|
|
|
$this->currentVersionFile, |
101
|
|
|
$folderName |
102
|
|
|
); |
103
|
|
|
} catch (Exception $e) { |
104
|
|
|
// we shouldn't get an error here, but just in case |
105
|
|
|
$return['error'] = $e->getMessage(); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
if (!$return['error']) { |
109
|
|
|
if ($this->upload->isError()) { |
110
|
|
|
$return['error'] = implode(' '.PHP_EOL, $this->upload->getErrors()); |
111
|
|
|
} else { |
112
|
|
|
$file = $this->upload->getFile(); |
113
|
|
|
|
114
|
|
|
$file->createVersion(); |
115
|
|
|
|
116
|
|
|
// Attach the file to the related record. |
117
|
|
|
if ($this->relationAutoSetting) { |
118
|
|
|
$this->attachFile($file); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
// Collect all output data. |
122
|
|
|
$file = $this->customiseFile($file); |
123
|
|
|
$return = array_merge($return, array( |
124
|
|
|
'id' => $file->ID, |
125
|
|
|
'name' => $file->getTitle() . '.' . $file->getExtension(), |
126
|
|
|
'url' => $file->getURL(), |
127
|
|
|
'thumbnail_url' => $file->UploadFieldThumbnailURL, |
128
|
|
|
'edit_url' => $file->UploadFieldEditLink, |
129
|
|
|
'size' => $file->getAbsoluteSize(), |
130
|
|
|
'buttons' => $file->UploadFieldFileButtons |
131
|
|
|
)); |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
$response = new SS_HTTPResponse(Convert::raw2json(array($return))); |
136
|
|
|
$response->addHeader('Content-Type', 'text/plain'); |
137
|
|
|
return $response; |
138
|
|
|
} |
139
|
|
|
} |
140
|
|
|
|