Beispiel #1
0
 /**
  * Импорт файла из внешнего источника.
  *
  * Используется как для обработки полученных от браузера файлов, так и для
  * ручного добавления файлов в архив.  Путь к файловому архиву определяется
  * конфигурационным файлом (параметр files).
  *
  * Внутреннее имя файла при копировании в архив формируется с использованием
  * md5-суммы его содержимого, поэтому в архив нельзя два раза добавить один
  * файл.  При обнаружении попытки повторной загрузки файла (с таким же
  * filepath) метод прозрачно подменяет содержимое текущей ноды содержимым
  * уже существующей, новую не создаёт.
  *
  * При невозможности скопировать файл в архив возникает UserErrorException.
  *
  * @return void
  * @param array $file описание файла
  * @param bool $uploaded проверять, действительно ли файл пришёл от браузера.
  *
  * Обязательные ключи: tmp_name (полный путь к фалу, который нужно
  * скопировать в архив), опциональные: type, name, size, parent_id.  При
  * отсутствии type, тип файла определяется эвристически.
  *
  * При указании parent_id файл автоматически прикрепляется к указанной в этом
  * параметре ноде, с помощью Node::linkAddParent().
  */
 public function import(array $file, $uploaded = true)
 {
     if (!empty($file['tmp_name'])) {
         $storage = os::path(MCMS_SITE_FOLDER, Context::last()->config->get('modules/files/storage'));
         // Немного валидации.
         if (!file_exists($file['tmp_name'])) {
             throw new Exception(t('Загружаемый файл перестал существовать.'));
         }
         // Угадваем значения некоторых полей, для упрощения скриптинга.
         if (!isset($file['size'])) {
             $file['size'] = filesize($file['tmp_name']);
         }
         if (!isset($file['name'])) {
             $file['name'] = basename($file['tmp_name']);
         }
         if (!isset($file['type'])) {
             $file['type'] = os::getFileType($file['tmp_name']);
         }
         if ($this->id === null and FileNode::isUnzipable($file)) {
             if (null === ($node = $this->unzip($file['tmp_name']))) {
                 throw new InvalidArgumentException("ZIP file was empty");
             }
             $this->data = $node->getRaw();
             return $this;
         }
         $this->filepath = os::mkunique($this->getCleanFileName($file), $storage);
     } elseif (!empty($file['url'])) {
         $this->remoteurl = $file['url'];
     }
     $file = array_merge(array('name' => 'unnamed.bin', 'type' => 'application/octet-stream', 'size' => 0), $file);
     $this->filename = $this->name = $file['name'];
     $this->filetype = $file['type'];
     $this->filesize = $file['size'];
     if ($this->filepath and !empty($file['tmp_name'])) {
         // Сюда будем копировать файл.
         $dest = os::path($storage, $this->filepath);
         if (file_exists($dest)) {
             throw new RuntimeException(t('Такой файл уже есть.'));
         }
         // Создаём каталог для него.
         os::mkdir(dirname($dest), 'Файл не удалось сохранить, т.к. отсутствуют права на запись в каталог, где этот файл должен был бы храниться (%path).  Сообщите об этой проблеме администратору сайта.', array('%path' => dirname($dest)));
         // Копируем файл.
         if (!os::copy($file['tmp_name'], $dest)) {
             throw new RuntimeException(t('Не удалось скопировать файл %src в %dst.', array('%src' => $file['tmp_name'], '%dst' => $dest)));
         }
     }
     // Прикрепляем файл к родительскому объекту.
     if (!empty($file['parent_id'])) {
         $this->linkAddParent($file['parent_id']);
     }
     return $this;
 }