Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
Class.VaultDiskStorage.php
Go to the documentation of this file.
1 <?php
2 /*
3  * @author Anakeen
4  * @package FDL
5 */
6 /**
7  * Retrieve and store file in Vault for unix fs
8  *
9  * @author Anakeen
10  * @version $Id: Class.VaultDiskStorage.php,v 1.8 2007/11/14 09:53:37 eric Exp $
11  * @package FDL
12  */
13 /**
14  */
15 
16 include_once ("VAULT/Class.VaultDiskFsStorage.php");
17 include_once ("VAULT/Class.VaultDiskFsCache.php");
18 include_once ("VAULT/Class.VaultDiskDirStorage.php");
19 include_once ("VAULT/Lib.VaultCommon.php");
20 
21 class VaultDiskStorage extends DbObj
22 {
23  var $fields = array(
24  "id_file",
25  "id_fs",
26  "id_dir",
27  "public_access",
28  "size",
29  "name",
30  "id_tmp",
31 
32  "mime_t", // file mime type text
33  "mime_s", // file mime type system
34  "cdate", // creation date
35  "mdate", // modification date
36  "adate", // access date
37  "teng_state", // Transformation Engine state
38  "teng_lname", // Transformation Engine logical name (VIEW, THUMBNAIL, ....)
39  "teng_id_file", // Transformation Engine source file id
40  "teng_comment", // Comment for transformation
41 
42  );
43  var $id_fields = array(
44  "id_file"
45  );
46  var $dbtable = "vaultdiskstorage";
47  var $sqlcreate = "create table vaultdiskstorage (
48  id_file bigint not null, primary key (id_file),
49  id_fs int,
50  id_dir int,
51  public_access bool,
52  size int,
53  name text,
54  id_tmp text,
55  mime_t text DEFAULT '',
56  mime_s text DEFAULT '',
57 
58  cdate timestamp DEFAULT null,
59  mdate timestamp DEFAULT null,
60  adate timestamp DEFAULT null,
61 
62  teng_state int DEFAULT 0,
63  teng_lname text DEFAULT '',
64  teng_id_file bigint DEFAULT -1,
65  teng_comment text DEFAULT ''
66 
67  );
68  CREATE INDEX vault_iddir on vaultdiskstorage (id_dir);
69  CREATE INDEX vault_teng on vaultdiskstorage (teng_state);
70  CREATE INDEX vault_tengid on vaultdiskstorage (teng_id_file);";
71  public $id_file;
72  public $id_fs;
73  public $id_dir;
74  public $name;
75  /**
76  * Indicate if file is a temporary file : set to session user id
77  * @var string
78  */
79  public $id_tmp;
80  public $size;
82  public $mime_t;
83  public $mime_s;
84  public $cdate;
85  public $mdate;
86  public $adate;
87  public $teng_state;
88  public $teng_lname;
89  public $teng_id_file;
90  public $teng_comment;
91  /**
92  * @var Log
93  */
94  protected $logger;
95  var $storage = 1;
96  /**
97  * @var VaultDiskFsStorage
98  */
99  public $fs;
100  // --------------------------------------------------------------------
101  function __construct($dbaccess = '', $id = '', $res = '', $dbid = 0)
102  {
104  $this->logger = new Log("", "vault", $this->name);
105  $this->fs = new VaultDiskFsStorage($this->dbaccess);
106  }
107  /**
108  * set fs object
109  */
110  function Complete()
111  {
112  if ($this->storage == 1) {
113  if (!$this->fs) {
114  $this->fs = new VaultDiskFsStorage($this->dbaccess);
115  }
116  $this->fs->Select($this->id_fs);
117  } else {
118  // not implemented
119  $this->fs = new VaultDiskFsCache($this->dbaccess, $this->id_fs);
120  }
121  }
122 
123  function PreInsert()
124  {
125  $this->id_file = $this->getNewVaultId();
126  return '';
127  }
128  /**
129  * Get a new cryptographically random id for vault identifier
130  *
131  * Throws an exception:
132  * - if no cryptographically random bytes could be obtained from openssl:
133  * this might occurs on broken or old system.
134  * - if architecture int size is not supported.
135  *
136  * @return int The new id (bigint)
137  * @throws \Dcp\Exception
138  */
139  public function getNewVaultId()
140  {
141  $newId = '';
142  while (empty($newId)) {
143  $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE);
144  if ($bytes === false) {
145  throw new \Dcp\Exception(sprintf("Unable to get cryptographically strong random bytes from openssl: your system might be broken or too old."));
146  }
147  /*
148  * We are going to perform a bitmask operation, so we should ensure
149  * that the correct number of requested bytes have been returned.
150  */
151  if (strlen($bytes) !== PHP_INT_SIZE) {
152  throw new \Dcp\Exception(sprintf("Unable to get cryptographically strong random bytes from openssl: your system might be broken or too old."));
153  }
154  /*
155  * Set leftmost bit to 0 to prevent having negative values
156  */
157  if (PHP_INT_SIZE == 4) {
158  $bytes = ($bytes & "\x7f\xff\xff\xff");
159  $int = unpack("Nint4", $bytes);
160  $int = $int['int4'];
161  } elseif (PHP_INT_SIZE == 8) {
162  $bytes = ($bytes & "\x7f\xff\xff\xff" . "\xff\xff\xff\xff");
163  /*
164  * "J" format is only supported on PHP >= 5.6.2, so we need to
165  * manually unpack 2 int4 (with format "N") and reconstruct the
166  * final int8.
167  */
168  $upper_int = unpack("Nint4", substr($bytes, 0, 4));
169  $lower_int = unpack("Nint4", substr($bytes, 4, 4));
170  $int = ($upper_int['int4'] << 32) + $lower_int['int4'];
171  } else {
172  throw new \Dcp\Exception(sprintf("Unsupported PHP_INT_SIZE '%d'.", PHP_INT_SIZE));
173  }
174  /*
175  * If the integer is negative, then something is wrong
176  * with this code...
177  */
178  if ($int < 0) {
179  throw new \Dcp\Exception(sprintf("Unexpected negative integer value with PHP_INT_SIZE '%d' and binary data '0x%s'.", PHP_INT_SIZE, bin2hex($bytes)));
180  }
181  /*
182  * Check if this id is already in use
183  */
184  $sql = <<<'SQL'
185 SELECT id_file FROM %s WHERE id_file = %d LIMIT 1
186 SQL;
187 
188  $err = $this->exec_query(sprintf($sql, pg_escape_identifier($this->dbtable) , $int));
189  if ($err) {
190  throw new \Dcp\Db\Exception("DB0104", $err);
191  }
192  if ($this->numrows() === 0) {
193  /*
194  * The id is not already in use, so we can use it
195  */
196  $newId = $int;
197  }
198  }
199  return $newId;
200  }
201  // --------------------------------------------------------------------
202  function ListFiles(&$list)
203  {
204  // --------------------------------------------------------------------
205  $query = new QueryDb($this->dbaccess, $this->dbtable);
206  $list = $query->Query(0, 0, "TABLE");
207  $fc = $query->nb;
208  return $fc;
209  }
210 
211  function seems_utf8($Str)
212  {
213  return preg_match('!!u', $Str);
214  }
215  /**
216  * Add new file in VAULT
217  * @param string $infile complete server path of file to store
218  * @param bool $public_access set true if can be access without any permission
219  * @param int &$idf new file identifier
220  * @param string $fsname name of the VAULT to store (can be empty=>store in one of available VAULT)
221  * @param string $te_lname transformation engine name
222  * @param int $te_id_file transformation engine file result identifier
223  * @return string error message (empty if OK)
224  */
225  function Store($infile, $public_access, &$idf, $fsname = "", $te_lname = "", $te_id_file = 0)
226  {
227  // --------------------------------------------------------------------
228  include_once ("WHAT/Lib.FileMime.php");
229 
230  if (!is_file($infile)) {
231  return ErrorCode::getError('FILE0007', $infile);
232  }
233  if (!is_readable($infile)) {
234  return ErrorCode::getError('FILE0008', $infile);
235  }
236  $this->size = filesize($infile);
237  $msg = $this->fs->SetFreeFs($this->size, $id_fs, $id_dir, $f_path, $fsname);
238  if ($msg != '') {
239  $this->logger->error("Can't find free entry in vault. [reason $msg]");
240  return ($msg);
241  }
242  $this->id_fs = $id_fs;
243  $this->id_dir = $id_dir;
244  // printf("\nDIR:%s\n", $id_dir);
245  $this->public_access = $public_access;
246  $this->name = my_basename($infile);
247  if (!$this->seems_utf8($this->name)) $this->name = utf8_encode($this->name);
248 
249  $this->mime_t = getTextMimeFile($infile);
250  $this->mime_s = getSysMimeFile($infile, $this->name);
251  $this->cdate = $this->mdate = $this->adate = date("c", time());
252 
253  $this->teng_state = '';
254  $this->teng_lname = $te_lname;
255  $this->teng_id_file = $te_id_file;
256 
257  $msg = $this->Add();
258  if ($msg != '') return ($msg);
259 
260  $this->fs->closeCurrentDir();
261  $idf = $this->id_file;
262 
263  $f = vaultfilename($f_path, $infile, $this->id_file);
264  if (!@copy($infile, $f)) {
265  // Free entry
266  $this->logger->error(sprintf(_("Failed to copy %s to %s") , $infile, $f));
267  return (sprintf(_("Failed to copy %s to vault") , $infile));
268  }
269 
270  $this->logger->debug("File $infile stored in $f");
271  return "";
272  }
273  /**
274  * Get the VaultDiskStorage transforming object corresponding to the current object
275  * @param string $te_name transformation engine name
276  * @param VaultDiskStorage &$ngf returned object
277  * @return string error message (empty if OK)
278  *
279  * @deprecated no usage
280  * @throws \Dcp\Db\Exception
281  */
282  function GetEngineObject($te_name, &$ngf)
283  {
284 
285  if (!$this->isAffected()) return _("vault file is not initialized");
286  $err = '';
287  $q = new QueryDb($this->dbaccess, "VaultDiskStorage");
288  $q->AddQuery("teng_id_file=" . $this->id_file);
289  $q->AddQuery("teng_lname='" . pg_escape_string($te_name) . "'");
290  $tn = $q->Query();
291  if ($q->nb == 0) {
292  $ngf = new VaultDiskStorage($this->dbaccess);
293  $ngf->teng_id_file = $this->id_file;
294  $ngf->teng_lname = $te_name;
295  $size = 1;
296  $ngf->fs->SetFreeFs($size, $id_fs, $id_dir, $f_path, $fsname = '');
297  $ngf->cdate = $ngf->mdate = $ngf->adate = date("c", time());
298  $ngf->id_fs = $id_fs;
299  $ngf->id_dir = $id_dir;
300  $ngf->size = 0;
301  $err = $ngf->Add();
302  if ($err) return $err;
303  } else {
304  $ngf = $tn[0];
305  }
306  return $err;
307  }
308  /**
309  * @param int $id_file vault file identifier
310  * @param VaultFileInfo $f_infos
311  * @param string $teng_lname engine name
312  * @return string
313  */
314  function show($id_file, &$f_infos, $teng_lname = "")
315  {
316  // --------------------------------------------------------------------
317  $this->id_file = - 1;
318  if ($teng_lname != "") {
319  $query = new QueryDb($this->dbaccess, $this->dbtable);
320  $query->AddQuery(sprintf("teng_id_file = E'%s'::bigint", pg_escape_string($id_file)));
321  $query->AddQuery(sprintf("teng_lname = E'%s'", pg_escape_string($teng_lname)));
322 
323  $t = $query->Query(0, 0, "TABLE");
324 
325  if ($query->nb > 0) {
326  DbObj::Select($t[0]["id_file"]);
327  }
328  }
329 
330  if (($this->id_file == - 1) && ($teng_lname == "")) {
332  }
333 
334  if ($this->id_file != - 1) {
335  $this->fs->Show($this->id_fs, $this->id_dir, $f_path);
336  $f_infos = new VaultFileInfo();
337  $f_infos->id_file = $this->id_file;
338  $f_infos->name = $this->name;
339  $f_infos->size = $this->size;
340  $f_infos->public_access = $this->public_access;
341  $f_infos->mime_t = $this->mime_t;
342  $f_infos->mime_s = $this->mime_s;
343  $f_infos->cdate = $this->cdate;
344  $f_infos->mdate = $this->mdate;
345  $f_infos->adate = $this->adate;
346  $f_infos->id_tmp = $this->id_tmp;
347  $f_infos->teng_state = $this->teng_state;
348  $f_infos->teng_lname = $this->teng_lname;
349  $f_infos->teng_vid = $this->teng_id_file;
350  $f_infos->teng_comment = $this->teng_comment;
351  $f_infos->path = vaultfilename($f_path, $this->name, $this->id_file);
352 
353  return '';
354  } else {
355  return (_("file does not exist in vault"));
356  }
357  }
358 
360  {
361  $err = '';
362  if ($this->id_file != $id_file) {
364  }
365  if ($this->isAffected()) {
366  $this->adate = date("c", time());
367  $err = $this->modify(true, array(
368  "adate"
369  ) , true);
370  }
371  return $err;
372  }
373  /**
374  * return the complete path in file system
375  * @return string the path
376  */
377  function getPath()
378  {
379  $this->fs->Show($this->id_fs, $this->id_dir, $f_path);
380  return vaultfilename($f_path, $this->name, $this->id_file);
381  }
382  // --------------------------------------------------------------------
383  function Destroy($id)
384  {
385  // --------------------------------------------------------------------
386  $msg = $this->Show($id, $inf);
387  if ($msg == '') {
388  @unlink($inf->path);
389  $msg = $this->fs->DelEntry($this->id_fs, $this->id_dir, $inf->size);
390  $this->Delete();
391  }
392 
393  return $msg;
394  }
395  // --------------------------------------------------------------------
396  function save($infile, $public_access, $idf)
397  {
398  $err = '';
399  $vf = new VaultFile($this->dbaccess);
400  if ($vf->Show($idf, $info) == "") {
401  /*
402  * @var VaultFileInfo $info
403  */
404  $path = str_replace("//", "/", $info->path);
405 
406  $size = $this->size;
407  $this->size = filesize($infile);
408  $newsize = $this->size - $size;
409  // Verifier s'il y a assez de places ???
410  $this->public_access = $public_access;
411 
412  $this->mdate = date("c", time());
413 
414  $msg = $this->modify();
415  if ($msg != '') return ($msg);
416 
417  if (!copy($infile, $path)) {
418  $err = sprintf(_("Cannot copy file %s to %s") , $infile, $path);
419  } else {
420  $this->fs->select($this->id_fs);
421  $this->logger->debug("File $infile saved in $path");
422 
423  $this->resetTEFiles();
424  }
425  } else {
426  $err = sprintf("cannot save file : invalid vault descriptor %s", $idf);
427  }
428  return $err;
429  }
430  /**
431  * reset all files product by transform engine
432  */
433  function resetTEFiles()
434  {
435  if (\Dcp\Autoloader::classExists('Dcp\TransformationEngine\Client')) {
436  $sql = <<<SQL
437 UPDATE %s SET teng_state = %d WHERE teng_id_file = %s
438 SQL;
439 
440  $up = sprintf($sql, pg_escape_identifier($this->dbtable) , pg_escape_literal(\Dcp\TransformationEngine\Client::status_inprogress) , pg_escape_literal($this->id_file));
441  $this->exec_query($up);
442  }
443  }
444 } // End Class.VaultFileDisk.php
445 class VaultFileInfo
446 {
447  /**
448  * @var int vault identifier
449  */
450  public $id_file;
451  /**
452  * @var string file basename
453  */
454  public $name;
455  /**
456  * @var int file size in bytes
457  */
458  public $size;
459  public $public_access;
460  public $mime_t;
461  /**
462  * @var string system mime file
463  */
464  public $mime_s;
465  /**
466  * @var string creation date (YYYY-MM-DD HH:MM:SS)
467  */
468  public $cdate;
469  /**
470  * @var string modification date (YYYY-MM-DD HH:MM:SS)
471  */
472  public $mdate;
473  /**
474  * @var string last access date (YYYY-MM-DD HH:MM:SS)
475  */
476  public $adate;
477  public $teng_state;
478  public $teng_lname;
479  public $teng_vid;
481  /**
482  * @var string complete path to file
483  */
484  public $path;
485  public $id_tmp;
486 }
getTextMimeFile($f, $fn= '')
exec_query($sql, $lvl=0, $prepare=false)
print $fam getTitle() $fam name
Add($nopost=false, $nopre=false)
vaultfilename($fspath, $name, $id)
getSysMimeFile($f, $fn="")
Select($id)
static getError($code, $args=null)
Definition: ErrorCode.php:27
isAffected()
$fsname
Definition: vault_init.php:26
__construct($dbaccess= '', $id= '', $res= '', $dbid=0)
modify($nopost=false, $sfields="", $nopre=false)
Store($infile, $public_access, &$idf, $fsname="", $te_lname="", $te_id_file=0)
show($id_file, &$f_infos, $teng_lname="")
$path
Definition: dav.php:39
my_basename($p)
$vf
Definition: geticon.php:28
$info
Definition: geticon.php:30
if(($docid!==0)&&(!is_numeric($docid))) $query
if($file) if($subject==""&&$file) if($subject=="") $err
GetEngineObject($te_name, &$ngf)
__construct($dbaccess= '', $id= '', $res= '', $dbid=0)
save($infile, $public_access, $idf)
← centre documentaire © anakeen