View source
<?php
namespace Drupal\filebrowser\File;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Link;
use Drupal\filebrowser\Events\MetadataEvent;
use Drupal\filebrowser\ServerFileList;
use Drupal\node\NodeInterface;
class DisplayFileList extends ControllerBase {
protected $data;
protected $files;
protected $node;
protected $items;
protected $serverFileList;
protected $common;
protected $validator;
protected $storage;
protected $user;
protected $filebrowser;
protected $fid;
protected $relativePath;
protected $isSubDir;
protected $fsRoot;
public function __construct(NodeInterface $node, $fid) {
$this->data = null;
$this->files = [];
$this->node = $node;
$this->filebrowser = $node->filebrowser;
$this->common = \Drupal::service('filebrowser.common');
$this->storage = \Drupal::service('filebrowser.storage');
$this->validator = \Drupal::service('filebrowser.validator');
$this->user = \Drupal::currentUser();
$this->fid = $fid;
$this
->createFileDisplayList();
}
public function get() {
return [
'data' => $this->data,
'files' => $this->files,
];
}
protected function createFileDisplayList() {
$cid = 'filebrowser/' . $this->node
->id() . '/' . $this->fid;
if ($this->fid) {
$content = $this->storage
->nodeContentLoadMultiple([
$this->fid,
]);
if (empty($content[$this->fid])) {
return false;
}
$this->relativePath = $content[$this->fid]['path'];
$this->fsRoot = $this->relativePath;
}
else {
$this->relativePath = '/';
}
$this->isSubDir = $this->relativePath != '/';
if ($this->isSubDir && !$this->common
->canExploreSubFolders($this->node)) {
\Drupal::messenger()
->addError($this
->t('You\'re not allowed to browse sub folders.'));
return false;
}
if ($this->fsRoot === false) {
\Drupal::messenger()
->addError($this
->t('Configured folder is not readable or is not a directory.'));
return false;
}
$list = new ServerFileList($this->node, $this->relativePath);
$this->serverFileList = $list
->getList();
$result = $this
->processServerFileList();
$this->files = $result;
$this->data['fid'] = $this->fid;
$cache = [
'files' => $this->files,
'data' => $this->data,
];
\Drupal::cache()
->set($cid, $cache, -1, [
'filebrowser:node:' . $this->node
->id(),
]);
return $this;
}
protected function processServerFileList() {
$stats = [
'folders_count' => 0,
'files_count' => 0,
'total_size' => 0,
];
$encoding = $this->node->filebrowser->encoding;
$db_content = $this->storage
->loadRecordsFromRoot($this->node
->id(), $this->relativePath);
if (!is_null($this->serverFileList)) {
foreach ($this->serverFileList as $key => $fs_file) {
$file_relative_path = $this
->buildFileRelativePath($fs_file->filename, $encoding);
if (!isset($db_content[$file_relative_path])) {
$db_content[$file_relative_path] = [
'exists' => true,
'nid' => $this->node
->id(),
'root' => $this->relativePath,
'path' => $file_relative_path,
'description' => $this
->t('No description.'),
'file_data' => $fs_file,
];
}
$db_content[$file_relative_path]['exists'] = true;
$db_content[$file_relative_path]['display_name'] = $fs_file->filename;
$result_file = new DisplayFile($this->node
->id());
$result_file
->fileSetData($file_relative_path, $fs_file, $stats, $db_content[$file_relative_path], $this->fsRoot);
$result_list[$fs_file->filename] = $result_file;
}
}
if ($this->isSubDir) {
$subDir = new DisplayFile($this->node
->id());
$result_list['..'] = $subDir
->createSubdir($this->relativePath);
$file = new DisplayFile($this->node
->id());
$result_list['.'] = $file
->createUpDir($this->relativePath);
$this
->createUpDirContent($db_content['/']);
if (!isset($db_content[$this->relativePath])) {
$db_content[$this->relativePath] = [
'exists' => TRUE,
'nid' => $this->node
->id(),
'root' => $this->relativePath,
'path' => $this->relativePath,
];
}
$db_content[$this->relativePath]['exists'] = true;
$db_content[$this->relativePath]['display_name'] = '.';
}
else {
if (!isset($db_content['/'])) {
$db_content['/'] = [
'nid' => $this->node
->id(),
'root' => '/',
'path' => '/',
];
}
$db_content['/']['exists'] = true;
$db_content['/']['display_name'] = '.';
$result_file = new DisplayFile($this->node
->id());
$result_list['.'] = $result_file
->createUpDir($this->relativePath);
}
$this->data['stats'] = $this
->buildStatistics($result_list);
$this->data['relative_path'] = $this->relativePath;
$this
->dbSync($db_content, $result_list, $this->data);
return $result_list;
}
protected function dbSync(&$db_content, &$files, $subdir_fid = null) {
$to_delete = [];
$theme = \Drupal::theme()
->getActiveTheme()
->getName();
$fragment = 'block-' . str_replace('_', '-', $theme) . '-page-title';
foreach ($db_content as $path => &$record) {
if (!isset($record['nid'])) {
}
if (!isset($record['exists'])) {
$to_delete[] = $record['fid'];
}
else {
if (!isset($record['fid'])) {
$record['fid'] = $this->storage
->insertRecord($record);
}
$key = $record['display_name'];
$files[$key]->fid = $record['fid'];
$link = $this
->makeLink($files[$key], $record['fid'], $fragment);
$files[$key]->link = $link
->toRenderable();
$files[$key]->href = $link
->getUrl();
$dispatcher = \Drupal::service('event_dispatcher');
$e = new MetadataEvent($this->node
->id(), $record['fid'], $files[$key], $subdir_fid, $this->filebrowser->visibleColumns);
$dispatcher
->dispatch('filebrowser.metadata_event', $e);
}
}
if (count($to_delete)) {
$this->storage
->deleteFileRecords($to_delete);
}
}
protected function makeLink(DisplayFile $file, $fid = null, $fragment = null) {
$options = [
'query' => [
'fid' => $fid,
],
];
if (isset($fragment)) {
$options['fragment'] = $fragment;
}
if ($file->displayName == '..') {
$display_name = $this
->t('Go up');
return Link::createFromRoute($display_name, 'entity.node.canonical', [
'node' => $this->node
->id(),
], $options);
}
$name = $this->filebrowser->hideExtension ? pathinfo($file->displayName, PATHINFO_FILENAME) : $file->displayName;
if ($file->fileData->type != 'file') {
return Link::createFromRoute($name, 'entity.node.canonical', [
'node' => $this->node
->id(),
], $options);
}
else {
return Link::createFromRoute($name, 'filebrowser.page_download', [
'fid' => $fid,
]);
}
}
protected function makeAnchor(DisplayFile $file, $fid = null) {
}
protected function buildFileRelativePath($fs_filename, $encoding) {
$filename = $this->validator
->encodingToFs($encoding, $fs_filename);
return $this->relativePath . ($this->relativePath != '/' ? '/' : '') . $filename;
}
protected function createUpDirContent(&$array) {
$parent_path = $this
->parentFolder();
$content = $this->storage
->loadRecordFromPath($this->node
->id(), $parent_path);
if ($content) {
foreach ($content as $key => $value) {
$array[$key] = $value;
}
}
else {
\Drupal::messenger()
->addError($this
->t('No content in method LoadRecordFromPath'));
}
$array['exists'] = true;
$array['display_name'] = '..';
}
protected function parentFolder() {
$array = explode('/', $this->relativePath);
if (count($array) < 3) {
return '/';
}
else {
unset($array[count($array) - 1]);
return $result = implode('/', $array);
}
}
protected function buildStatistics($list) {
$files = 0;
$folders = 0;
$total_size = 0;
foreach ($list as $key => $item) {
if (in_array($key, [
'.',
'..',
])) {
}
else {
if ($item->fileData->type == 'file') {
$files++;
$total_size = $total_size + $item->fileData->size;
}
else {
$folders++;
}
}
}
return [
'files' => $files,
'folders' => $folders,
'size' => $total_size,
];
}
}