silverstripe-dms/code/model/DMSDocument_versions.php

257 lines
6.6 KiB
PHP
Raw Normal View History

2012-11-21 06:24:46 +01:00
<?php
2012-11-21 06:24:46 +01:00
/**
* DataObject to store versions of uploaded Documents.
*
* Versions are only created when replacing a document, not on every save of the
* DMSDocument dataobject. So, versions store the various versions of the
* underlying Document, not the DataObject with information about that object.
*
* @package dms
2012-11-21 06:24:46 +01:00
*/
class DMSDocument_versions extends DataObject {
/**
* @var bool $enable_versions Flag that turns on or off versions of
* documents when replacing them
*/
public static $enable_versions = true;
2012-11-21 06:24:46 +01:00
2013-08-22 13:38:26 +02:00
private static $db = array(
2012-11-21 06:24:46 +01:00
'VersionCounter' => 'Int',
'VersionViewCount' => 'Int'
);
2012-11-21 06:24:46 +01:00
2013-08-22 13:38:26 +02:00
private static $has_one = array(
'Document' => 'DMSDocument'
2012-11-21 06:24:46 +01:00
);
2013-08-22 13:38:26 +02:00
private static $defaults = array(
2012-11-21 06:24:46 +01:00
'VersionCounter' => 0
);
2013-08-22 13:38:26 +02:00
private static $display_fields = array(
2012-11-22 01:42:03 +01:00
'VersionCounter' => 'Version Counter',
2012-11-21 06:24:46 +01:00
'FilenameWithoutID' => 'Filename',
2012-11-22 01:42:03 +01:00
'LastChanged' => 'Last Changed'
2012-11-21 06:24:46 +01:00
);
2013-08-22 13:38:26 +02:00
private static $summary_fields = array(
2012-11-21 06:24:46 +01:00
'VersionCounter',
'FilenameWithoutID'
);
2013-08-22 13:38:26 +02:00
private static $field_labels = array(
2012-11-21 06:24:46 +01:00
'FilenameWithoutID'=>'Filename'
);
2013-08-22 13:38:26 +02:00
private static $default_sort = array(
2012-11-21 06:24:46 +01:00
'LastChanged' => 'DESC'
);
/**
* Creates a new version of a document by moving the current file and
* renaming it to the versioned filename.
*
* This method assumes that the method calling this is just about to upload
* a new file to replace the old file.
*
2012-11-21 06:24:46 +01:00
* @static
* @param DMSDocument $doc
*
2012-11-21 06:24:46 +01:00
* @return bool Success or failure
*/
public static function create_version(DMSDocument $doc) {
2012-11-21 06:24:46 +01:00
$success = false;
$existingPath = $doc->getFullPath();
if (is_file($existingPath)) {
$docData = $doc->toMap();
unset($docData['ID']);
$version = new DMSDocument_versions($docData); //create a copy of the current DMSDocument as a version
2012-11-21 06:24:46 +01:00
$previousVersionCounter = 0;
$newestExistingVersion = self::get_versions($doc)->sort(array('Created'=>'DESC','ID'=>'DESC'))->limit(1);
if ($newestExistingVersion && $newestExistingVersion->Count() > 0) {
$previousVersionCounter = $newestExistingVersion->first()->VersionCounter;
}
//change the filename field to a field containing the new soon-to-be versioned file
$version->VersionCounter = $previousVersionCounter + 1; //start versions at 1
$newFilename = $version->generateVersionedFilename($doc, $version->VersionCounter);
$version->Filename = $newFilename;
//add a relation back to the origin ID;
$version->DocumentID = $doc->ID;
$id = $version->write();
if (!empty($id)) {
rename($existingPath, $version->getFullPath());
$success = true;
}
}
return $success;
}
public function delete() {
$path = $this->getFullPath();
2012-11-21 06:24:46 +01:00
if (file_exists($path)) unlink($path);
parent::delete();
}
/**
* Returns a DataList of all previous Versions of a document (check the
* LastEdited date of each object to find the correct one).
*
2012-11-21 06:24:46 +01:00
* @static
* @param DMSDocument $doc
*
2012-11-21 06:24:46 +01:00
* @return DataList List of Document objects
*/
static function get_versions(DMSDocument $doc) {
if (!DMSDocument_versions::$enable_versions) user_error("DMSDocument versions are disabled",E_USER_WARNING);
return DMSDocument_versions::get()->filter(array('DocumentID' => $doc->ID));
}
public function __construct($record = null, $isSingleton = false, $model = null) {
//check what the constructor was passed
$dmsObject = null;
if ($record && is_subclass_of($record,'DMSDocumentInterface')) {
$dmsObject = $record;
$record = null; //cancel the record creation to just create an empty object
}
//create the object
parent::__construct($record, $isSingleton, $model);
//copy the DMSDocument object, if passed into the constructor
if ($dmsObject) {
foreach(array_keys(DataObject::custom_database_fields($dmsObject->ClassName)) as $key) {
$this->$key = $dmsObject->$key;
}
}
}
/**
* Returns a link to download this document from the DMS store.
*
* @return string
2012-11-21 06:24:46 +01:00
*/
public function getLink() {
2012-11-21 06:24:46 +01:00
return Controller::join_links(Director::baseURL(),'dmsdocument/version'.$this->ID);
}
/**
* Document versions are always hidden from outside viewing. Only admins can
* download them.
*
2012-11-21 06:24:46 +01:00
* @return bool
*/
public function isHidden() {
2012-11-21 06:24:46 +01:00
return true;
}
/**
* Returns the full filename of the document stored in this object. Can
* optionally specify which filename to use at the end.
*
* @param string
*
2012-11-21 06:24:46 +01:00
* @return string
*/
public function getFullPath($filename = null) {
2012-11-21 06:24:46 +01:00
if (!$filename) $filename = $this->Filename;
return DMS::get_dms_path() . DIRECTORY_SEPARATOR . $this->Folder . DIRECTORY_SEPARATOR . $filename;
}
/**
* @return string
*/
public function getFilenameWithoutID() {
2012-11-21 06:24:46 +01:00
$filenameParts = explode('~',$this->Filename);
$filename = array_pop($filenameParts);
2012-11-21 06:24:46 +01:00
return $filename;
}
/**
* Creates a new filename for the current Document's file when replacing the
* current file with a new file.
*
* @param DMSDocument $filename The original filename
*
* @return string The new filename
2012-11-21 06:24:46 +01:00
*/
protected function generateVersionedFilename(DMSDocument $doc, $versionCounter) {
$filename = $doc->Filename;
do {
$versionPaddingString = str_pad($versionCounter, 4, '0', STR_PAD_LEFT); //add leading zeros to make sorting accurate up to 10,000 documents
$newVersionFilename = preg_replace('/([0-9]+~)(.*?)/','$1~'.$versionPaddingString.'~$2',$filename);
if ($newVersionFilename == $filename || empty($newVersionFilename)) { //sanity check for crazy document names
user_error('Cannot generate new document filename for file: '.$filename,E_USER_ERROR);
}
$versionCounter++; //increase the counter for the next loop run, if necessary
} while(file_exists($this->getFullPath($newVersionFilename)));
return $newVersionFilename;
}
/**
* Return the extension of the file associated with the document.
*
* @return string
2012-11-21 06:24:46 +01:00
*/
public function getExtension() {
2012-11-21 06:24:46 +01:00
return strtolower(pathinfo($this->Filename, PATHINFO_EXTENSION));
}
/**
* @return string
*/
public function getSize() {
2012-11-21 06:24:46 +01:00
$size = $this->getAbsoluteSize();
2012-11-21 06:24:46 +01:00
return ($size) ? File::format_size($size) : false;
}
/**
* Return the size of the file associated with the document.
*
* @return string
2012-11-21 06:24:46 +01:00
*/
public function getAbsoluteSize() {
2012-11-21 06:24:46 +01:00
return filesize($this->getFullPath());
}
/**
* An alias to DMSDocument::getSize()
*
* @return string
2012-11-21 06:24:46 +01:00
*/
public function getFileSizeFormatted() {
2012-11-21 06:24:46 +01:00
return $this->getSize();
}
/**
* @return DMSDocument_versions
2012-11-21 06:24:46 +01:00
*/
public function trackView() {
2012-11-21 06:24:46 +01:00
if ($this->ID > 0) {
$this->VersionViewCount++;
$count = $this->VersionViewCount;
2012-11-21 06:24:46 +01:00
DB::query("UPDATE \"DMSDocument_versions\" SET \"VersionViewCount\"='$count' WHERE \"ID\"={$this->ID}");
}
return $this;
}
2012-11-21 06:24:46 +01:00
}