/concrete/models/file.php
PHP | 526 lines | 403 code | 82 blank | 41 comment | 54 complexity | c3de54ea988075e61dc4a5c9b89afffe MD5 | raw file
- <?php
- Loader::model('file_version');
- class File extends Object {
- const CREATE_NEW_VERSION_THRESHOLD = 300; // in seconds (5 minutes)
- const F_ERROR_INVALID_FILE = 1;
- const F_ERROR_FILE_NOT_FOUND = 2;
-
- /**
- * returns a file object for the given file ID
- * @param int $fID
- * @return File
- */
- public function getByID($fID) {
- $f = Cache::get('file_approved', $fID);
- if (is_object($f)) {
- return $f;
- }
-
- Loader::model('file_set');
- $db = Loader::db();
- $f = new File();
- $row = $db->GetRow("SELECT Files.*, FileVersions.fvID
- FROM Files LEFT JOIN FileVersions on Files.fID = FileVersions.fID and FileVersions.fvIsApproved = 1
- WHERE Files.fID = ?", array($fID));
- if ($row['fID'] == $fID) {
- $f->setPropertiesFromArray($row);
- Cache::set('file_approved', $fID, $f);
- } else {
- $f->error = File::F_ERROR_INVALID_FILE;
- }
- return $f;
- }
-
- /**
- * For all methods that file does not implement, we pass through to the currently active file version object
- */
- public function __call($nm, $a) {
- $fv = $this->getApprovedVersion();
- return call_user_func_array(array($fv, $nm), $a);
- }
- public function getPath() {
- $fv = $this->getVersion();
- return $fv->getPath();
- }
- public function getPassword() {
- return $this->fPassword;
- }
-
- public function getStorageLocationID() {
- return $this->fslID;
- }
-
- public function refreshCache() {
- $db = Loader::db();
- Cache::delete('file_relative_path', $this->getFileID());
- Cache::delete('file_approved', $this->getFileID());
- $r = $db->GetCol('select fvID from FileVersions where fID = ?', array($this->getFileID()));
- foreach($r as $fvID) {
- Cache::delete('file_version_' . $this->getFileID(), $fvID);
- }
- }
-
- public function reindex() {
- Loader::model('attribute/categories/file');
- $attribs = FileAttributeKey::getAttributes($this->getFileID(), $this->getFileVersionID(), 'getSearchIndexValue');
- $db = Loader::db();
- $db->Execute('delete from FileSearchIndexAttributes where fID = ?', array($this->getFileID()));
- $searchableAttributes = array('fID' => $this->getFileID());
- $rs = $db->Execute('select * from FileSearchIndexAttributes where fID = -1');
- AttributeKey::reindex('FileSearchIndexAttributes', $searchableAttributes, $attribs, $rs);
- }
- public static function getRelativePathFromID($fID) {
- $path = Cache::get('file_relative_path', $fID);
- if ($path != false) {
- return $path;
- }
-
- $f = File::getByID($fID);
- $path = $f->getRelativePath();
-
- Cache::set('file_relative_path', $fID, $path);
- return $path;
- }
-
- public function setStorageLocation($item) {
- if ($item == 0) {
- // set to default
- $itemID = 0;
- $path = DIR_FILES_UPLOADED;
- } else {
- $itemID = $item->getID();
- $path = $item->getDirectory();
- }
-
- if ($itemID != $this->getStorageLocationID()) {
- // retrieve all versions of a file and move its stuff
- $list = $this->getVersionList();
- $fh = Loader::helper('concrete/file');
- foreach($list as $fv) {
- $newPath = $fh->mapSystemPath($fv->getPrefix(), $fv->getFileName(), true, $path);
- $currPath = $fv->getPath();
- rename($currPath, $newPath);
- }
- $db = Loader::db();
- $db->Execute('update Files set fslID = ? where fID = ?', array($itemID, $this->fID));
- }
- $this->refreshCache();
- }
-
- public function setPassword($pw) {
- Events::fire('on_file_set_password', $this, $pw);
- $db = Loader::db();
- $db->Execute("update Files set fPassword = ? where fID = ?", array($pw, $this->getFileID()));
- $this->fPassword = $pw;
- $this->refreshCache();
- }
-
- public function setOriginalPage($ocID) {
- if ($ocID < 1) {
- return false;
- }
-
- $db = Loader::db();
- $db->Execute("update Files set ocID = ? where fID = ?", array($ocID, $this->getFileID()));
- $this->refreshCache();
- }
-
- public function getOriginalPageObject() {
- if ($this->ocID > 0) {
- $c = Page::getByID($this->ocID);
- if (is_object($c) && !$c->isError()) {
- return $c;
- }
- }
- }
-
- public function overrideFileSetPermissions() {
- return $this->fOverrideSetPermissions;
- }
-
- public function resetPermissions($fOverrideSetPermissions = 0) {
- $db = Loader::db();
- $db->Execute("delete from FilePermissions where fID = ?", array($this->fID));
- $db->Execute("update Files set fOverrideSetPermissions = ? where fID = ?", array($fOverrideSetPermissions, $this->fID));
- $this->refreshCache();
- }
-
- public function setPermissions($obj, $canRead, $canSearch, $canWrite, $canAdmin) {
- $fID = $this->fID;
- $uID = 0;
- $gID = 0;
- $db = Loader::db();
- if (is_a($obj, 'UserInfo')) {
- $uID = $obj->getUserID();
- } else {
- $gID = $obj->getGroupID();
- }
-
- if ($canRead < 1) {
- $canRead = 0;
- }
-
- if ($canSearch < 1) {
- $canSearch = 0;
- }
-
- if ($canWrite < 1) {
- $canWrite = 0;
- }
-
- if ($canAdmin < 1) {
- $canAdmin = 0;
- }
-
- $db->Replace('FilePermissions', array(
- 'fID' => $fID,
- 'uID' => $uID,
- 'gID' => $gID,
- 'canRead' => $canRead,
- 'canSearch' => $canSearch,
- 'canWrite' => $canWrite,
- 'canAdmin' => $canAdmin
- ),
- array('fID', 'gID', 'uID'), true);
- $this->refreshCache();
-
- }
-
- public function getUserID() {
- return $this->uID;
- }
-
- public function setUserID($uID) {
- $this->uID = $uID;
- $db = Loader::db();
- $db->Execute("update Files set uID = ? where fID = ?", array($uID, $this->fID));
- }
-
- public function getFileSets() {
- $db = Loader::db();
- Loader::model('file_set');
- $fsIDs = $db->Execute("select fsID from FileSetFiles where fID = ?", array($this->getFileID()));
- $filesets = array();
- foreach($fsIDs as $fsID) {
- $filesets[] = FileSet::getByID($fsID);
- }
- return $filesets;
- }
-
- public function isStarred($u = false) {
- if (!$u) {
- $u = new User();
- }
- $db = Loader::db();
- Loader::model('file_set');
- $r = $db->GetOne("select fsfID from FileSetFiles fsf inner join FileSets fs on fs.fsID = fsf.fsID where fsf.fID = ? and fs.uID = ? and fs.fsType = ?",
- array($this->getFileID(), $u->getUserID(), FileSet::TYPE_STARRED));
- return $r > 0;
- }
-
- public function getDateAdded() {
- return $this->fDateAdded;
- }
-
- /**
- * Returns a file version object that is to be written to. Computes whether we can use the current most recent version, OR a new one should be created
- */
- public function getVersionToModify($forceCreateNew = false) {
- $u = new User();
- $createNew = false;
-
- $fv = $this->getRecentVersion();
- $fav = $this->getApprovedVersion();
-
- // first test. Does the user ID of the most recent version match ours? If not, then we create new
- if ($u->getUserID() != $fv->getAuthorUserID()) {
- $createNew = true;
- }
-
- // second test. If the date the version was added is older than File::CREATE_NEW_VERSION_THRESHOLD, we create new
- $unixTime = strtotime($fv->getDateAdded());
- $diff = time() - $unixTime;
- if ($diff > File::CREATE_NEW_VERSION_THRESHOLD) {
- $createNew = true;
- }
-
- if ($forceCreateNew) {
- $createNew = true;
- }
-
- if ($createNew) {
- $fv2 = $fv->duplicate();
-
- // Are the recent and active versions the same? If so, we approve this new version we just made
- if ($fv->getFileVersionID() == $fav->getFileVersionID()) {
- $fv2->approve();
- }
- return $fv2;
- } else {
- return $fv;
- }
- }
-
- public function getFileID() { return $this->fID;}
-
- public function duplicate() {
- $dh = Loader::helper('date');
- $db = Loader::db();
- $date = $dh->getSystemDateTime();
- $far = new ADODB_Active_Record('Files');
- $far->Load('fID=?', array($this->fID));
-
- $far2 = clone $far;
- $far2->fID = null;
- $far2->fDateAdded = $date;
- $far2->Insert();
- $fIDNew = $db->Insert_ID();
- $fvIDs = $db->GetCol('select fvID from FileVersions where fID = ?', $this->fID);
- foreach($fvIDs as $fvID) {
- $farv = new ADODB_Active_Record('FileVersions');
- $farv->Load('fID=? and fvID = ?', array($this->fID, $fvID));
-
- $farv2 = clone $farv;
- $farv2->fID = $fIDNew;
- $farv2->fvActivateDatetime = $date;
- $farv2->fvDateAdded = $date;
- $farv2->Insert();
- }
- $r = $db->Execute('select fvID, akID, avID from FileAttributeValues where fID = ?', array($this->getFileID()));
- while ($row = $r->fetchRow()) {
- $db->Execute("insert into FileAttributeValues (fID, fvID, akID, avID) values (?, ?, ?, ?)", array(
- $fIDNew,
- $row['fvID'],
- $row['akID'],
- $row['avID']
- ));
- }
-
- // return the new file object
- return File::getByID($fIDNew);
-
- }
-
- public static function add($filename, $prefix, $data = array()) {
- $db = Loader::db();
- $dh = Loader::helper('date');
- $date = $dh->getSystemDateTime();
-
- $uID = 0;
- $u = new User();
- if (isset($data['uID'])) {
- $uID = $data['uID'];
- } else if ($u->isRegistered()) {
- $uID = $u->getUserID();
- }
-
- $db->Execute('insert into Files (fDateAdded, uID) values (?, ?)', array($date, $uID));
-
- $fID = $db->Insert_ID();
-
- $f = File::getByID($fID);
-
- $fv = $f->addVersion($filename, $prefix, $data);
- Events::fire('on_file_add', $f, $fv);
-
- return $fv;
- }
-
- public function addVersion($filename, $prefix, $data = array()) {
- $u = new User();
- $uID = (isset($data['uID']) && $data['uID'] > 0) ? $data['uID'] : $u->getUserID();
-
- if ($uID < 1) {
- $uID = 0;
- }
-
- $fvTitle = (isset($data['fvTitle'])) ? $data['fvTitle'] : '';
- $fvDescription = (isset($data['fvDescription'])) ? $data['fvDescription'] : '';
- $fvTags = (isset($data['fvTags'])) ? FileVersion::cleanTags($data['fvTags']) : '';
- $fvIsApproved = (isset($data['fvIsApproved'])) ? $data['fvIsApproved'] : '1';
- $db = Loader::db();
- $dh = Loader::helper('date');
- $date = $dh->getSystemDateTime();
-
- $fvID = $db->GetOne("select max(fvID) from FileVersions where fID = ?", array($this->fID));
- if ($fvID > 0) {
- $fvID++;
- } else {
- $fvID = 1;
- }
-
- $db->Execute('insert into FileVersions (fID, fvID, fvFilename, fvPrefix, fvDateAdded, fvIsApproved, fvApproverUID, fvAuthorUID, fvActivateDateTime, fvTitle, fvDescription, fvTags, fvExtension)
- values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', array(
- $this->fID,
- $fvID,
- $filename,
- $prefix,
- $date,
- $fvIsApproved,
- $uID,
- $uID,
- $date,
- $fvTitle,
- $fvDescription,
- $fvTags,
- ''));;
-
- $fv = $this->getVersion($fvID);
- Events::fire('on_file_version_add', $fv);
- return $fv;
- }
-
- public function getApprovedVersion() {
- return $this->getVersion();
- }
-
- public function inFileSet($fs) {
- $db = Loader::db();
- $r = $db->GetOne("select fsfID from FileSetFiles where fID = ? and fsID = ?", array($this->getFileID(), $fs->getFileSetID()));
- return $r > 0;
- }
-
- /**
- * Removes a file, including all of its versions
- */
- public function delete() {
- // first, we remove all files from the drive
- $db = Loader::db();
- $pathbase = false;
- $r = $db->GetAll('select fvFilename, fvPrefix from FileVersions where fID = ?', array($this->fID));
- $h = Loader::helper('concrete/file');
- Loader::model('file_storage_location');
- if ($this->getStorageLocationID() > 0) {
- $fsl = FileStorageLocation::getByID($this->getStorageLocationID());
- $pathbase = $fsl->getDirectory();
- }
- foreach($r as $val) {
-
- // Now, we make sure this file isn't referenced by something else. If it is we don't delete the file from the drive
- $cnt = $db->GetOne('select count(*) as total from FileVersions where fID <> ? and fvFilename = ? and fvPrefix = ?', array(
- $this->fID,
- $val['fvFilename'],
- $val['fvPrefix']
- ));
- if ($cnt == 0) {
- if ($pathbase != false) {
- $path = $h->mapSystemPath($val['fvPrefix'], $val['fvFilename'], false, $pathbase);
- } else {
- $path = $h->mapSystemPath($val['fvPrefix'], $val['fvFilename'], false);
- }
- $t1 = $h->getThumbnailSystemPath($val['fvPrefix'], $val['fvFilename'], 1);
- $t2 = $h->getThumbnailSystemPath($val['fvPrefix'], $val['fvFilename'], 2);
- $t3 = $h->getThumbnailSystemPath($val['fvPrefix'], $val['fvFilename'], 3);
- if (file_exists($path)) {
- unlink($path);
- }
- if (file_exists($t1)) {
- unlink($t1);
- }
- if (file_exists($t2)) {
- unlink($t2);
- }
- if (file_exists($t3)) {
- unlink($t3);
- }
- }
- }
-
- // now from the DB
- $db->Execute("delete from Files where fID = ?", array($this->fID));
- $db->Execute("delete from FileVersions where fID = ?", array($this->fID));
- $db->Execute("delete from FileAttributeValues where fID = ?", array($this->fID));
- $db->Execute("delete from FileSetFiles where fID = ?", array($this->fID));
- $db->Execute("delete from FileVersionLog where fID = ?", array($this->fID));
- $this->refreshCache();
- }
-
- /**
- * returns the most recent FileVersion object
- * @return FileVersion
- */
- public function getRecentVersion() {
- $db = Loader::db();
- $fvID = $db->GetOne("select fvID from FileVersions where fID = ? order by fvID desc", array($this->fID));
- return $this->getVersion($fvID);
- }
-
- /**
- * returns the FileVersion object for the provided fvID
- * if none provided returns the approved version
- * @param int $fvID
- * @return FileVersion
- */
- public function getVersion($fvID = null) {
- if ($fvID == null) {
- $fvID = $this->fvID; // approved version
- }
-
- $fv = Cache::get('file_version_' . $this->getFileID(), $fvID);
- if (is_object($fv)) {
- return $fv;
- }
-
- $db = Loader::db();
- $row = $db->GetRow("select * from FileVersions where fvID = ? and fID = ?", array($fvID, $this->fID));
- $row['fvAuthorName'] = $db->GetOne("select uName from Users where uID = ?", array($row['fvAuthorUID']));
-
- $fv = new FileVersion();
- $row['fslID'] = $this->fslID;
- $fv->setPropertiesFromArray($row);
- $fv->populateAttributes();
-
- Cache::set('file_version_' . $this->getFileID(), $fvID, $fv);
- return $fv;
- }
-
- /**
- * Returns an array of all FileVersion objects owned by this file
- */
- public function getVersionList() {
- $db = Loader::db();
- $r = $db->Execute("select fvID from FileVersions where fID = ? order by fvDateAdded desc", array($this->getFileID()));
- $files = array();
- while ($row = $r->FetchRow()) {
- $files[] = $this->getVersion($row['fvID']);
- }
- return $files;
- }
-
- public function getDownloadStatistics(){
- $db = Loader::db();
- return $db->getAll("SELECT * FROM DownloadStatistics WHERE fID = ? ORDER BY timestamp desc", array($this->getFileID()));
- }
-
-
- /**
- * Tracks File Download, takes the cID of the page that the file was downloaded from
- * @param int $rcID
- * @return void
- */
- public function trackDownload($rcID=NULL){
- $u = new User();
- $uID = intval( $u->getUserID() );
- $fv = $this->getVersion();
- $fvID = $fv->getFileVersionID();
- if(!isset($rcID) || !is_numeric($rcID)) {
- $rcID = 0;
- }
- Events::fire('on_file_download', $fv, $u);
- $db = Loader::db();
- $db->Execute('insert into DownloadStatistics (fID, fvID, uID, rcID) values (?, ?, ?, ?)', array( $this->fID, intval($fvID), $uID, $rcID ) );
- }
- }