Вход Регистрация
Файл: concrete5.7.5.6/concrete/src/Legacy/FileList.php
Строк: 343
<?php 
namespace ConcreteCoreLegacy;
use 
File as ConcreteFile;
use 
User;
use 
FileAttributeKey;

/**
*
* An object that allows a filtered list of files to be returned.
* @package Files
*
*/
class 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();
        
$fh = Loader::helper('file');
        
$filename = $fh->getTemporaryDirectory() . '/' . $archive . '.zip';
        if (
count($files) > 0) {
            try {
                
$zip = new ZipArchive;
                
$res = $zip->open($filename, ZipArchive::CREATE);
                if (
$res === TRUE) {
                    foreach(
$files as $f) {
                        
$zip->addFromString($f->getFilename(), $f->getFileContents());
                    }
                    
$zip->close();
                    
$fh->forceDownload($filename);
                } else {
                    throw new 
Exception(t('Could not open with ZipArchive::CREATE'));
                }
            } 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();
        
$this->createQuery();
        
$r = parent::get($itemsToGet, $offset);
        foreach(
$r as $row) {
            
$f = ConcreteFile::getByID($row['fID']);            
            
$files[] = $f;
        }
        return 
$files;
    }
    
    public function 
getTotal(){
        
$files = array();
        
$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');
    }

}
Онлайн: 2
Реклама