forked from osTicket/osTicket-plugins
-
Notifications
You must be signed in to change notification settings - Fork 1
/
storage.php
143 lines (127 loc) · 4.67 KB
/
storage.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
<?php
/**
* FilesystemStorage plugin
*
* Allows attachment data to be written to the disk rather than in the
* database
*/
class FilesystemStorage extends FileStorageBackend {
var $fp = null;
static $base;
function read($bytes=32768, $offset=false) {
$hash = $this->meta->getKey();
$filename = $this->getPath($hash);
if (!$this->fp)
$this->fp = @fopen($filename, 'rb');
if (!$this->fp)
throw new IOException($filename.': Unable to open for reading');
if ($offset)
fseek($this->fp, $offset);
if (($status = @fread($this->fp, $bytes)) === false)
throw new IOException($filename.': Unable to read from file');
return $status;
}
function passthru() {
$hash = $this->meta->getKey();
$filename = $this->getPath($hash);
// TODO: Raise IOException on failure
if (($status = @readfile($filename)) === false)
throw new IOException($filename.': Unable to read from file');
return $status;
}
function write($data) {
$hash = $this->meta->getKey();
$filename = $this->getPath($hash);
if (!$this->fp)
$this->fp = @fopen($filename, 'wb');
if (!$this->fp)
throw new IOException($filename.':Unable to open for reading');
if (($status = @fwrite($this->fp, $data)) === false)
throw new IOException($filename.': Unable to write to file');
return $status;
}
function upload($filepath) {
$destination = $this->getPath($this->meta->getKey());
if (!@move_uploaded_file($filepath, $destination))
throw new IOException($filepath.': Unable to move file');
// TODO: Consider CHMOD on the file
return true;
}
function unlink() {
$filename = $this->getPath($this->meta->getKey());
if (!@unlink($filename))
throw new IOException($filename.': Unable to delete file');
return true;
}
function getPath($hash) {
// TODO: Make this configurable
$prefix = $hash[0];
$base = static::$base;
if ($base[0] != '/' && $base[1] != ':')
$base = ROOT_DIR . $base;
// Auto-create the subfolders
$base .= '/'.$prefix;
if (!is_dir($base))
mkdir($base, 751);
return $base.'/'.$hash;
}
}
class FsStoragePluginConfig extends PluginConfig {
// Provide compatibility function for versions of osTicket prior to
// translation support (v1.9.4)
function translate() {
if (!method_exists('Plugin', 'translate')) {
return array(
function($x) { return $x; },
function($x, $y, $n) { return $n != 1 ? $y : $x; },
);
}
return Plugin::translate('storage-fs');
}
function getOptions() {
list($__, $_N) = self::translate();
return array(
'uploadpath' => new TextboxField(array(
'label'=>$__('Base folder for attachment files'),
'hint'=>$__('The path must already exist and be writeable by the
web server. If the path starts with neither a `/` nor a
drive letter, the path will be assumed to be relative to
the root of osTicket'),
'configuration'=>array('size'=>60, 'length'=>255),
'required'=>true,
)),
);
}
function pre_save($config, &$errors) {
list($__, $_N) = self::translate();
$path = $config['uploadpath'];
if ($path[0] != '/' && $path[1] != ':')
$path = ROOT_DIR . $path;
$field = $this->getForm()->getField('uploadpath');
$file = md5(microtime());
if (!@is_dir($path))
$field->addError($__('Path does not exist'));
elseif (!@opendir($path))
$field->addError($__('Unable to access directory'));
elseif (!@touch("$path/$file"))
$field->addError($__('Unable to write to directory'));
elseif (!@unlink("$path/$file"))
$field->addError($__('Unable to remove files from directory'));
else
touch("$path/.keep");
return true;
}
}
class FsStoragePlugin extends Plugin {
var $config_class = 'FsStoragePluginConfig';
function bootstrap() {
$config = $this->getConfig();
$uploadpath = $config->get('uploadpath');
list($__, $_N) = $config::translate();
if ($uploadpath) {
FileStorageBackend::register('F', 'FilesystemStorage');
FilesystemStorage::$base = $uploadpath;
FilesystemStorage::$desc = $__('Filesystem') .': '.$uploadpath;
}
}
}