Open Journal Systems  3.3.0
bagit_utils.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3 
41 function filterArrayMatches($regex, $list)
42 {
43  $ret = array();
44 
45  foreach ($list as $item) {
46  $matches = array();
47  if (preg_match($regex, $item, $matches)) {
48  array_push($ret, $matches);
49  }
50  }
51 
52  return $ret;
53 }
54 
63 function endsWith($main, $suffix)
64 {
65  $len = strlen($suffix);
66  return substr_compare($main, $suffix, -$len, $len) === 0;
67 }
68 
77 function rls($dir)
78 {
79  $files = array();
80  $queue = array($dir);
81 
82  while (count($queue) > 0) {
83  $current = array_shift($queue);
84 
85  foreach (scandir($current) as $item) {
86  if ($item[0] != '.') {
87  $filename = "$current/$item";
88 
89  switch (filetype($filename))
90  {
91  case 'file':
92  array_push($files, $filename);
93  break;
94  case 'dir':
95  array_push($queue, $filename);
96  break;
97  }
98  }
99  }
100  }
101 
102  return $files;
103 }
104 
112 function rrmdir($dir)
113 {
114  if (is_dir($dir)) {
115  $objects = scandir($dir);
116  foreach ($objects as $object) {
117  if ($object != "." && $object != "..") {
118  if (filetype($dir . "/" . $object) == "dir") {
119  rrmdir($dir . "/" . $object);
120  } else {
121  unlink($dir . "/" . $object);
122  }
123  }
124  }
125  reset($objects);
126  rmdir($dir);
127  }
128 }
129 
139 function tmpdir($prefix='bag')
140 {
141  $dir = tempnam(sys_get_temp_dir(), $prefix);
142  unlink($dir);
143  return $dir;
144 }
145 
155 function seenAtKey($array, $key, $item)
156 {
157  $keys = array_keys($array);
158  for ($x=0, $len=count($keys); $x<$len; $x++) {
159  $sub = $array[$keys[$x]];
160  if (array_key_exists($key, $sub) && $sub[$key] == $item) {
161  return true;
162  }
163  }
164  return false;
165 }
166 
175 function saveUrl($url, $filename)
176 {
177  $curl = curl_init($url);
178  $file = fopen($filename, 'w');
179 
180  curl_setopt($curl, CURLOPT_FILE, $file);
181  curl_setopt($curl, CURLOPT_HEADER, 0);
182 
183  curl_exec($curl);
184  curl_close($curl);
185 
186  fclose($file);
187 }
188 
197 function findFirstExisting($fileNames, $default=null)
198 {
199  foreach ($fileNames as $fileName) {
200  if (file_exists($fileName)) {
201  return $fileName;
202  }
203  }
204  return $default;
205 }
206 
217 function readFileText($fileName, $fileEncoding)
218 {
219  $data = iconv($fileEncoding, 'UTF-8', file_get_contents($fileName));
220  return $data;
221 }
222 
233 function readLines($fileName, $fileEncoding)
234 {
235  $data = readFileText($fileName, $fileEncoding);
236  $lines = preg_split('/[\n\r]+/', $data, null, PREG_SPLIT_NO_EMPTY);
237  return $lines;
238 }
239 
250 function writeFileText($fileName, $fileEncoding, $data)
251 {
252  file_put_contents($fileName, iconv('UTF-8', $fileEncoding, $data));
253 }
254 
262 function BagIt_sanitizeFileName($filename)
263 {
264  // White space => underscores.
265  $filename = preg_replace('/\s+/', '_', $filename);
266 
267  // Remove some characters.
268  $filename = preg_replace(
269  '/\.{2}|[~\^@!#%&\*\/:\'?\"<>\|]/',
270  '',
271  $filename
272  );
273 
274  $forbidden = '/^(CON|PRN|AUX|NUL|COM1|COM2|COM3|COM4|COM5| ' .
275  'COM6|COM7|COM8|COM9|LPT1|LPT2|LPT3|LPT4|LPT5|LPT6|' .
276  'LPT7|LPT8|LPT9)$/';
277 
278  if (preg_match($forbidden, $filename)) {
279  $filename = strtolower($filename);
280  $suffix = substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 12);
281  $filename = "{$filename}_{$suffix}";
282  }
283 
284  return $filename;
285 }
294 function BagIt_readBagItFile($filename)
295 {
296  $errors = array();
297 
298  if (file_exists($filename)) {
299  $data = readFileText($filename, 'UTF-8');
300 
301  $versions = BagIt_parseVersionString($data);
302  if ($versions === null) {
303  array_push(
304  $errors,
305  array('bagit',
306  'Error reading version information from bagit.txt file.')
307  );
308  }
309 
310  $fileEncoding = BagIt_parseEncodingString($data);
311 
312  } else {
313  $versions = array('major' => 0, 'minor' => 96);
314  $fileEncoding = 'UTF-8';
315  }
316 
317  return array($versions, $fileEncoding, $errors);
318 }
319 
328 function BagIt_parseVersionString($bagitFileData)
329 {
330  $matches = array();
331  $success = preg_match(
332  "/BagIt-Version: (\d+)\.(\d+)/",
333  $bagitFileData,
334  $matches
335  );
336 
337  if ($success) {
338  $major = (int)$matches[1];
339  $minor = (int)$matches[2];
340  if ($major === null || $minor === null) {
341  throw new Exception("Invalid bagit version: '{$matches[0]}'.");
342  }
343  return array('major' => $major, 'minor' => $minor);
344  }
345 
346  return null;
347 }
348 
356 function BagIt_parseEncodingString($bagitFileData)
357 {
358  $matches = array();
359  $success = preg_match(
360  '/Tag-File-Character-Encoding: (.*)/',
361  $bagitFileData,
362  $matches
363  );
364 
365  if ($success) {
366  return $matches[1];
367  }
368 
369  return null;
370 }
371 
379 function BagIt_uncompressBag($compressedFile)
380 {
381  // Create an output directory.
382  $dir = tempnam(sys_get_temp_dir(), 'bagit_');
383  unlink($dir);
384  mkdir($dir, 0700);
385 
386  // Pull apart the compressed file name.
387  $matches = array();
388  $success = preg_match(
389  '/^(.*)\.(zip|tar\.gz|tgz)$/',
390  basename($compressedFile),
391  $matches
392  );
393  if (!$success) {
394  throw new ErrorException("File not compressed: $compressedFile.");
395  }
396 
397  $bagBase = $matches[1];
398  $ext = $matches[2];
399 
400  if ($ext == 'zip') {
401 
402  $zip = new ZipArchive();
403  $zip->open($compressedFile);
404  $zip->extractTo($dir);
405 
406  $datadir = $dir . '/' . $bagBase . '/data';
407 
408  if (!file_exists($datadir)) {
409  mkdir($datadir, 0700);
410  }
411 
412  } else if ($ext == 'tgz' || $ext == 'tar.gz') {
413 
414  $tar = new Archive_Tar($compressedFile, 'gz');
415  $tar->extract($dir);
416 
417  }
418 
419  return "$dir/$bagBase";
420 }
421 
431 function BagIt_compressBag($dirname, $output, $method='tgz')
432 {
433  $base = basename($dirname);
434  $stripLen = strlen($dirname) - strlen($base);
435 
436  if ($method == 'zip') {
437  $zip = new ZipArchive();
438  $zip->open($output, ZIPARCHIVE::CREATE);
439 
440  foreach (rls($dirname) as $file) {
441  $zip->addFile($file, substr($file, $stripLen));
442  }
443 
444  $zip->close();
445 
446  } else if ($method == 'tgz') {
447  $tar = new Archive_Tar($output, 'gz');
448  $tar->createModify($dirname, $base, $dirname);
449 
450  }
451 }
452 
462 function BagIt_validateExists($filename, &$errors)
463 {
464  if (! file_exists($filename)) {
465  $basename = basename($filename);
466  array_push(
467  $errors,
468  array($basename, "$basename does not exist.")
469  );
470  return false;
471  }
472  return true;
473 }
474 
482 function BagIt_parseBagInfo($lines)
483 {
484  $bagInfo = array();
485 
486  $prevKey = null;
487  foreach ($lines as $line) {
488  if (strlen($line) <= 1) {
489  // Skip.
490  } else if ($line[0] == ' ' || $line[0] == "\t") {
491  // Continued line.
492  $val = $bagInfo[$prevKey];
493  if (is_array($val)) {
494  $val[count($val) - 1] .= ' '. trim($line);
495  } else {
496  $val .= ' ' . trim($line);
497  }
498  $bagInfo[$prevKey] = $val;
499  } else {
500  list($key, $val) = preg_split('/:\s*/', $line, 2);
501  $val = trim($val);
502  $prevKey = $key;
503  $bagInfo[$prevKey] = BagIt_getAccumulatedValue(
504  $bagInfo, $prevKey, $val
505  );
506  }
507  }
508 
509  return $bagInfo;
510 }
511 
527 function BagIt_getAccumulatedValue($map, $key, $val)
528 {
529  if (array_key_exists($key, $map)) {
530  $pval = $map[$key];
531  if (is_array($pval)) {
532  $pval[] = $val;
533  } else {
534  $pval = array( $pval, $val );
535  }
536  $val = $pval;
537  }
538  return $val;
539 }
540 
541 /*
542  * Local variables:
543  * tab-width: 4
544  * c-basic-offset: 4
545  * c-hanging-comment-ender-p: nil
546  * End:
547  */
548 
549 ?>
Seboettg\Collection\count
count()
Definition: ArrayListTrait.php:253
Archive_Tar