/web/concrete/core/models/file_list.php
PHP | 448 lines | 341 code | 50 blank | 57 comment | 61 complexity | 3d932c84da566ee3351f437d91357efa MD5 | raw file
Possible License(s): MIT, LGPL-2.1, BSD-3-Clause
- <?php defined('C5_EXECUTE') or die("Access Denied.");
- /**
- *
- * An object that allows a filtered list of files to be returned.
- * @package Files
- *
- */
- class Concrete5_Model_FileList extends DatabaseItemList {
- protected $attributeFilters = array();
- protected $autoSortColumns = array('fvFilename', 'fvAuthorName','fvTitle', 'fDateAdded', 'fvDateAdded', 'fvSize');
- protected $itemsPerPage = 10;
- protected $attributeClass = 'FileAttributeKey';
- protected $permissionLevel = 'search_file_set';
- protected $filteredFileSetIDs = array();
-
- /* magic method for filtering by attributes. */
- public function __call($nm, $a) {
- if (substr($nm, 0, 8) == 'filterBy') {
- $txt = Loader::helper('text');
- $attrib = $txt->uncamelcase(substr($nm, 8));
- if (count($a) == 2) {
- $this->filterByAttribute($attrib, $a[0], $a[1]);
- } else {
- $this->filterByAttribute($attrib, $a[0]);
- }
- }
- }
- /**
- * Filters by file extension
- * @param mixed $extension
- */
- public function filterByExtension($ext) {
- $this->filter('fv.fvExtension', $ext, '=');
- }
- /**
- * Filters by type of file
- * @param mixed $type
- */
- public function filterByType($type) {
- $this->filter('fv.fvType', $type, '=');
- }
-
- /**
- * Filters by "keywords" (which searches everything including filenames, title, tags, users who uploaded the file, tags)
- */
- public function filterByKeywords($keywords) {
- $db = Loader::db();
- $keywordsExact = $db->quote($keywords);
- $qkeywords = $db->quote('%' . $keywords . '%');
- $keys = FileAttributeKey::getSearchableIndexedList();
- $attribsStr = '';
- foreach ($keys as $ak) {
- $cnt = $ak->getController();
- $attribsStr.=' OR ' . $cnt->searchKeywords($keywords);
- }
- $this->filter(false, '(fvFilename like ' . $qkeywords . ' or fvDescription like ' . $qkeywords . ' or fvTitle like ' . $qkeywords . ' or fvTags like ' . $qkeywords . ' or u.uName = ' . $keywordsExact . $attribsStr . ')');
- }
-
- public function filterBySet($fs) {
- if ($fs != false) {
- $this->filteredFileSetIDs[] = intval($fs->getFileSetID());
- } else {
- // this is what we do when we are filtering by files in NO sets.
- $s1 = FileSet::getMySets();
- $sets = array();
- foreach($s1 as $fs) {
- $sets[] = $fs->getFileSetID();
- }
- if (count($sets) == 0) {
- return false;
- }
- $db = Loader::db();
- $setStr = implode(',', $sets);
- $this->addToQuery("left join FileSetFiles fsfex on fsfex.fID = f.fID");
- $this->filter(false, '(fsfex.fID is null or (select count(fID) from FileSetFiles where fID = fsfex.fID and fsID in (' . $setStr . ')) = 0)');
- }
- }
- public static function export($xml) {
- $fl = new FileList();
- $files = $fl->get();
- if (count($files) > 0) {
- $pkgs = $xml->addChild("files");
- foreach($files as $f) {
- $node = $pkgs->addChild('file');
- $node->addAttribute('filename', $f->getFileName());
- }
- }
- }
- public static function exportArchive($archive) {
- $fl = new FileList();
- $files = $fl->get();
- $filestring = '';
- $fh = Loader::helper('file');
- $filenames = array();
- $filename = $fh->getTemporaryDirectory() . '/' . $archive . '.zip';
- if (count($files) > 0) {
- try {
- if (class_exists('ZipArchive', false)) {
- $zip = new ZipArchive;
- $res = $zip->open($filename, ZipArchive::CREATE);
- if ($res === TRUE) {
- foreach($files as $f) {
- $file = $f->getPath();
- if (!in_array(basename($file), $filenames)) {
- $filenames[] = basename($file);
- $zip->addFile(addslashes($file), basename($file));
- }
- }
- $zip->close();
- } else {
- throw new Exception(t('Could not open with ZipArchive::CREATE'));
- }
- } else {
- $filestring = "'" . addslashes($filename) . "' ";
- foreach($files as $f) {
- $file = $f->getPath();
- if (!in_array(basename($file), $filenames)) {
- $filenames[] = basename($file);
- $filestring .= "'" . addslashes($file) . "' ";
- }
- }
- exec(DIR_FILES_BIN_ZIP . ' -j ' . $filestring);
- }
- } catch(Exception $e) {
- throw new Exception(t('Failed to create zip file as "%s": %s', $filename, $e->getMessage()));
- }
- }
- }
-
- protected function setupFileSetFilters() {
- $fsIDs = array_unique($this->filteredFileSetIDs);
- $fsIDs = array_filter($fsIDs,'is_numeric');
-
- $db = Loader::db();
- $i = 0;
- $_fsIDs = array();
- if(is_array($fsIDs) && count($fsIDs)) {
- foreach($fsIDs as $fsID) {
- if($fsID > 0) {
- $_fsIDs[] = $fsID;
- }
- }
- }
-
- if (count($_fsIDs) > 1) {
- foreach($_fsIDs as $fsID) {
- if($fsID > 0) {
- if ($i == 0) {
- $this->addToQuery("left join FileSetFiles fsfl on fsfl.fID = f.fID");
- }
- $this->filter(false,'f.fID IN (SELECT DISTINCT fID FROM FileSetFiles WHERE fsID = '.$db->quote($fsID).')');
- $i++;
- }
- }
- } else if (count($_fsIDs) > 0) {
- $this->addToQuery("inner join FileSetFiles fsfl on fsfl.fID = f.fID");
- $this->filter('fsfl.fsID', $fsID);
- $i++;
- }
-
- // add FileSetFiles if we had a file set filter but
- // couldn't add it because it has been removed
- if ($i == 0 && count($this->filteredFileSetIDs)>0) {
- $this->addToQuery("inner join FileSetFiles fsfl on 1=2");
- }
- }
-
-
- /**
- * Filters the file list by file size (in kilobytes)
- */
- public function filterBySize($from, $to) {
- $this->filter('fv.fvSize', $from * 1024, '>=');
- $this->filter('fv.fvSize', $to * 1024, '<=');
- }
-
- /**
- * Filters by public date
- * @param string $date
- */
- public function filterByDateAdded($date, $comparison = '=') {
- $this->filter('f.fDateAdded', $date, $comparison);
- }
-
- public function filterByOriginalPageID($ocID) {
- $this->filter('f.ocID', $ocID);
- }
-
- /**
- * filters a FileList by the uID of the approving User
- * @param int $uID
- * @return void
- * @since 5.4.1.1+
- */
- public function filterByApproverUID($uID) {
- $this->filter('fv.fvApproverUID', $uID);
- }
-
- /**
- * filters a FileList by the uID of the owning User
- * @param int $uID
- * @return void
- * @since 5.4.1.1+
- */
- public function filterByAuthorUID($uID) {
- $this->filter('fv.fvAuthorUID', $uID);
- }
-
- public function setPermissionLevel($plevel) {
- $this->permissionLevel = $plevel;
- }
-
- /**
- * Filters by tag
- * @param string $tag
- */
- public function filterByTag($tag='') {
- $db=Loader::db();
- $this->filter(false, "( fv.fvTags like ".$db->qstr("%\n".$tag."\n%")." )");
- }
-
- protected function setBaseQuery() {
- $this->setQuery('SELECT DISTINCT f.fID, u.uName as fvAuthorName
- FROM Files f INNER JOIN FileVersions fv ON f.fID = fv.fID
- LEFT JOIN Users u on u.uID = fv.fvAuthorUID
- ');
- }
- protected function setupFilePermissions() {
- $u = new User();
- if ($this->permissionLevel == false || $u->isSuperUser()) {
- return false;
- }
- $accessEntities = $u->getUserAccessEntityObjects();
- foreach($accessEntities as $pae) {
- $peIDs[] = $pae->getAccessEntityID();
- }
- $db = Loader::db();
- // figure out which sets can read files in, not read files in, and read only my files in.
- $fsIDs = $db->GetCol('select fsID from FileSets where fsOverrideGlobalPermissions = 1');
- $viewableSets = array(-1);
- $nonviewableSets = array(-1);
- $myviewableSets = array(-1);
- $owpae = FileUploaderPermissionAccessEntity::getOrCreate();
-
- if (count($fsIDs) > 0) {
- $pk = PermissionKey::getByHandle($this->permissionLevel);
- foreach($fsIDs as $fsID) {
- $fs = FileSet::getByID($fsID);
- $pk->setPermissionObject($fs);
- $list = $pk->getAccessListItems(PermissionKey::ACCESS_TYPE_ALL, $accessEntities);
- $list = PermissionDuration::filterByActive($list);
- if (count($list) > 0) {
- foreach($list as $l) {
- $pae = $l->getAccessEntityObject();
- if ($pae->getAccessEntityID() == $owpae->getAccessEntityID()) {
- $myviewableSets[] = $fs->getFileSetID();
- } else {
- if ($l->getAccessType() == PermissionKey::ACCESS_TYPE_INCLUDE) {
- $viewableSets[] = $fs->getFileSetID();
- }
- if ($l->getAccessType() == PermissionKey::ACCESS_TYPE_EXCLUDE) {
- $nonviewableSets[] = $fs->getFileSetID();
- }
- }
- }
- } else {
- $nonviewableSets[] = $fs->getFileSetID();
- }
- }
- }
- $fs = FileSet::getGlobal();
- $fk = PermissionKey::getByHandle('search_file_set');
- $fk->setPermissionObject($fs);
- $accessEntities[] = $owpae;
- $list = $fk->getAccessListItems(PermissionKey::ACCESS_TYPE_ALL, $accessEntities);
- $list = PermissionDuration::filterByActive($list);
- foreach($list as $l) {
- $pae = $l->getAccessEntityObject();
- if ($pae->getAccessEntityID() == $owpae->getAccessEntityID()) {
- $valid = 'mine';
- } else {
- if ($l->getAccessType() == PermissionKey::ACCESS_TYPE_INCLUDE) {
- $valid = PermissionKey::ACCESS_TYPE_INCLUDE;
- }
- if ($l->getAccessType() == PermissionKey::ACCESS_TYPE_EXCLUDE) {
- $valid = PermissionKey::ACCESS_TYPE_EXCLUDE;
- }
- }
- }
-
- $uID = ($u->isRegistered()) ? $u->getUserID() : 0;
- // This excludes all files found in sets where I may only read mine, and I did not upload the file
- $this->filter(false, '(f.uID = ' . $uID . ' or (select count(fID) from FileSetFiles where FileSetFiles.fID = f.fID and fsID in (' . implode(',',$myviewableSets) . ')) = 0)');
-
- if ($valid == 'mine') {
- // this means that we're only allowed to read files we've uploaded (unless, of course, those files are in previously covered sets)
- $this->filter(false, '(f.uID = ' . $uID . ' or (select count(fID) from FileSetFiles where FileSetFiles.fID = f.fID and fsID in (' . implode(',',$viewableSets) . ')) > 0)');
- }
-
- // this excludes all file that are found in sets that I can't find
- $this->filter(false, '((select count(fID) from FileSetFiles where FileSetFiles.fID = f.fID and fsID in (' . implode(',', $nonviewableSets) . ')) = 0)');
-
- $uID = ($u->isRegistered()) ? $u->getUserID() : 0;
- // This excludes all files found in sets where I may only read mine, and I did not upload the file
- $this->filter(false, '(f.uID = ' . $uID . ' or (select count(fID) from FileSetFiles where FileSetFiles.fID = f.fID and fsID in (' . implode(',',$myviewableSets) . ')) = 0)');
- $db = Loader::db();
- $vpvPKID = $db->GetOne('select pkID from PermissionKeys where pkHandle = \'view_file\'');
- if ($this->permissionLevel == 'search_file_set') {
- $vpPKID = $db->GetOne('select pkID from PermissionKeys where pkHandle = \'view_file_in_file_manager\'');
- } else {
- $vpPKID = $vpvPKID;
- }
- $pdIDs = $db->GetCol("select distinct pdID from FilePermissionAssignments fpa inner join PermissionAccessList pal on fpa.paID = pal.paID where pkID in (?, ?) and pdID > 0", array($vpPKID, $vpvPKID));
- $activePDIDs = array();
- if (count($pdIDs) > 0) {
- // then we iterate through all of them and find any that are active RIGHT NOW
- foreach($pdIDs as $pdID) {
- $pd = PermissionDuration::getByID($pdID);
- if ($pd->isActive()) {
- $activePDIDs[] = $pd->getPermissionDurationID();
- }
- }
- }
- $activePDIDs[] = 0;
-
- // exclude files where its overridden but I don't have the ability to read
- $this->filter(false, "(f.fOverrideSetPermissions = 0 or (select count(fID) from FilePermissionAssignments fpa inner join PermissionAccessList fpal on fpa.paID = fpal.paID where fpa.fID = f.fID and fpal.accessType = " . PermissionKey::ACCESS_TYPE_INCLUDE . " and fpal.pdID in (" . implode(',', $activePDIDs) . ") and fpal.peID in (" . implode(',', $peIDs) . ") and (if(fpal.peID = " . $owpae->getAccessEntityID() . " and f.uID <> " . $uID . ", false, true)) and (fpa.pkID = " . $vpPKID . ")) > 0)");
-
- // exclude detail files where read is excluded
- $this->filter(false, "f.fID not in (select ff.fID from Files ff inner join FilePermissionAssignments fpaExclude on ff.fID = fpaExclude.fID inner join PermissionAccessList palExclude on fpaExclude.paID = palExclude.paID where fOverrideSetPermissions = 1 and palExclude.accessType = " . PermissionKey::ACCESS_TYPE_EXCLUDE . " and palExclude.pdID in (" . implode(',', $activePDIDs) . ")
- and palExclude.peID in (" . implode(',', $peIDs) . ") and fpaExclude.pkID in (" . $vpPKID . "," . $vpvPKID . "))");
- }
-
-
- /**
- * Returns an array of file objects based on current settings
- */
- public function get($itemsToGet = 0, $offset = 0) {
- $files = array();
- Loader::model('file');
- $this->createQuery();
- $r = parent::get($itemsToGet, $offset);
- foreach($r as $row) {
- $f = File::getByID($row['fID']);
- $files[] = $f;
- }
- return $files;
- }
-
- public function getTotal(){
- $files = array();
- Loader::model('file');
- $this->createQuery();
- return parent::getTotal();
- }
-
- //this was added because calling both getTotal() and get() was duplicating some of the query components
- protected function createQuery(){
- if(!$this->queryCreated){
- $this->setBaseQuery();
- $this->filter('fvIsApproved', 1);
- $this->setupAttributeFilters("left join FileSearchIndexAttributes on (fv.fID = FileSearchIndexAttributes.fID)");
- $this->setupFilePermissions();
- $this->setupFileSetFilters();
- $this->queryCreated=1;
- }
- }
-
- //$key can be handle or fak id
- public function sortByAttributeKey($key,$order='asc') {
- $this->sortBy($key, $order); // this is handled natively now
- }
-
- public function sortByFileSetDisplayOrder() {
- $this->sortByMultiple('fsDisplayOrder asc', 'fID asc');
- }
-
- public static function getExtensionList() {
- $db = Loader::db();
- $col = $db->GetCol('select distinct(trim(fvExtension)) as extension from FileVersions where fvIsApproved = 1 and fvExtension <> ""');
- return $col;
- }
- public static function getTypeList() {
- $db = Loader::db();
- $col = $db->GetCol('select distinct(trim(fvType)) as type from FileVersions where fvIsApproved = 1 and fvType <> 0');
- return $col;
- }
- }
- class Concrete5_Model_FileManagerDefaultColumnSet extends DatabaseItemListColumnSet {
- protected $attributeClass = 'FileAttributeKey';
-
- public static function getFileDateAdded($f) {
- return date(DATE_APP_DASHBOARD_SEARCH_RESULTS_FILES, strtotime($f->getDateAdded()));
- }
- public static function getFileDateActivated($f) {
- $fv = $f->getVersion();
- return date(DATE_APP_DASHBOARD_SEARCH_RESULTS_FILES, strtotime($fv->getDateAdded()));
- }
-
- public function __construct() {
- $this->addColumn(new DatabaseItemListColumn('fvType', t('Type'), 'getType', false));
- $this->addColumn(new DatabaseItemListColumn('fvTitle', t('Title'), 'getTitle'));
- $this->addColumn(new DatabaseItemListColumn('fDateAdded', t('Added'), array('FileManagerDefaultColumnSet', 'getFileDateAdded')));
- $this->addColumn(new DatabaseItemListColumn('fvDateAdded', t('Active'), array('FileManagerDefaultColumnSet', 'getFileDateActivated')));
- $this->addColumn(new DatabaseItemListColumn('fvSize', t('Size'), 'getSize'));
- $title = $this->getColumnByKey('fDateAdded');
- $this->setDefaultSortColumn($title, 'desc');
- }
- }
- class Concrete5_Model_FileManagerAvailableColumnSet extends Concrete5_Model_FileManagerDefaultColumnSet {
- protected $attributeClass = 'FileAttributeKey';
- public function __construct() {
- parent::__construct();
- $this->addColumn(new DatabaseItemListColumn('fvAuthorName', t('Author'), 'getAuthorName'));
- }
- }
- class Concrete5_Model_FileManagerColumnSet extends DatabaseItemListColumnSet {
- protected $attributeClass = 'FileAttributeKey';
- public function getCurrent() {
- $u = new User();
- $fldc = $u->config('FILE_LIST_DEFAULT_COLUMNS');
- if ($fldc != '') {
- $fldc = @unserialize($fldc);
- }
- if (!($fldc instanceof DatabaseItemListColumnSet)) {
- $fldc = new FileManagerDefaultColumnSet();
- }
- return $fldc;
- }
- }