mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Add status flag to File and Image Edit Form
API extension hook "getIsModifiedOnStage" renamed to "updateIsModifiedOnStage", also moved "getIsDeletedFromStage", "getIsModifiedOnStage" and "getIsAddedToStage" from SiteTree class to Versioned data extension class
This commit is contained in:
parent
60247a9fbd
commit
d7ded0fb4a
@ -475,10 +475,14 @@ class File extends DataObject implements ShortcodeHandler, AssetContainer, Thumb
|
|||||||
|
|
||||||
$previewLink = Convert::raw2att($this->PreviewLink());
|
$previewLink = Convert::raw2att($this->PreviewLink());
|
||||||
$image = "<img src=\"{$previewLink}\" class=\"editor__thumbnail\" />";
|
$image = "<img src=\"{$previewLink}\" class=\"editor__thumbnail\" />";
|
||||||
|
|
||||||
|
$statusTitle = $this->getStatusTitle();
|
||||||
|
$statusFlag = ($statusTitle) ? "<span class=\"editor__status-flag\">{$statusTitle}</span>" : '';
|
||||||
|
|
||||||
$content = Tab::create('Main',
|
$content = Tab::create('Main',
|
||||||
HeaderField::create('TitleHeader', $this->Title, 1)
|
HeaderField::create('TitleHeader', $this->Title, 1)
|
||||||
->addExtraClass('editor__heading'),
|
->addExtraClass('editor__heading'),
|
||||||
|
LiteralField::create('StatusFlag', $statusFlag),
|
||||||
LiteralField::create("IconFull", $image)
|
LiteralField::create("IconFull", $image)
|
||||||
->addExtraClass('editor__file-preview'),
|
->addExtraClass('editor__file-preview'),
|
||||||
TabSet::create('Editor',
|
TabSet::create('Editor',
|
||||||
@ -511,7 +515,18 @@ class File extends DataObject implements ShortcodeHandler, AssetContainer, Thumb
|
|||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getStatusTitle() {
|
||||||
|
$statusTitle = '';
|
||||||
|
if ($this->getIsAddedToStage()) {
|
||||||
|
$statusTitle = _t('File.DRAFT', 'Draft');
|
||||||
|
} elseif ($this->getIsModifiedOnStage()) {
|
||||||
|
$statusTitle = _t('File.MODIFIED', 'Modified');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $statusTitle;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a category based on the file extension.
|
* Returns a category based on the file extension.
|
||||||
* This can be useful when grouping files by type,
|
* This can be useful when grouping files by type,
|
||||||
|
@ -51,6 +51,9 @@ class Image extends File implements ShortcodeHandler {
|
|||||||
$image = "<img src=\"{$previewLink}\" class=\"editor__thumbnail\" />";
|
$image = "<img src=\"{$previewLink}\" class=\"editor__thumbnail\" />";
|
||||||
|
|
||||||
$link = $this->Link();
|
$link = $this->Link();
|
||||||
|
|
||||||
|
$statusTitle = $this->getStatusTitle();
|
||||||
|
$statusFlag = "<span class=\"editor__status-flag\">{$statusTitle}</span>";
|
||||||
|
|
||||||
$content = Tab::create('Main',
|
$content = Tab::create('Main',
|
||||||
HeaderField::create('TitleHeader', $this->Title, 1)
|
HeaderField::create('TitleHeader', $this->Title, 1)
|
||||||
@ -92,10 +95,15 @@ class Image extends File implements ShortcodeHandler {
|
|||||||
'TitleHeader',
|
'TitleHeader',
|
||||||
LiteralField::create(
|
LiteralField::create(
|
||||||
"DisplaySize",
|
"DisplaySize",
|
||||||
sprintf('<div class="editor__specs">%spx, %s</div>',
|
sprintf('<div class="editor__specs">%spx, %s %s</div>',
|
||||||
$dimensions, $this->getSize())
|
$dimensions, $this->getSize(), $statusFlag)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
$content->insertAfter(
|
||||||
|
'TitleHeader',
|
||||||
|
LiteralField::create('StatusFlag', $statusFlag)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields = FieldList::create(TabSet::create('Root', $content));
|
$fields = FieldList::create(TabSet::create('Root', $content));
|
||||||
|
@ -2328,8 +2328,56 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
|||||||
);
|
);
|
||||||
return (bool)$result->value();
|
return (bool)$result->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares current draft with live version, and returns true if no draft version of this page exists but the page
|
||||||
|
* is still published (eg, after triggering "Delete from draft site" in the CMS).
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getIsDeletedFromStage() {
|
||||||
|
if(!$this->owner->ID) return true;
|
||||||
|
|
||||||
|
$stageVersion = Versioned::get_versionnumber_by_stage($this->owner->class, Versioned::DRAFT, $this->owner->ID);
|
||||||
|
|
||||||
|
// Return true for both completely deleted pages and for pages just deleted from stage
|
||||||
|
return !($stageVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares current draft with live version, and returns true if these versions differ, meaning there have been
|
||||||
|
* unpublished changes to the draft site.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getIsModifiedOnStage() {
|
||||||
|
// New unsaved pages could be never be published
|
||||||
|
if(!$this->owner->ID) return false;
|
||||||
|
|
||||||
|
$stageVersion = Versioned::get_versionnumber_by_stage($this->owner->class, 'Stage', $this->owner->ID);
|
||||||
|
$liveVersion = Versioned::get_versionnumber_by_stage($this->owner->class, 'Live', $this->owner->ID);
|
||||||
|
|
||||||
|
$isModified = ($stageVersion && $stageVersion != $liveVersion);
|
||||||
|
$this->owner->extend('updateIsModifiedOnStage', $isModified);
|
||||||
|
|
||||||
|
return $isModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares current draft with live version, and returns true if no live version exists, meaning the page was never
|
||||||
|
* published.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getIsAddedToStage() {
|
||||||
|
// New unsaved pages could be never be published
|
||||||
|
if(!$this->owner->ID) return false;
|
||||||
|
|
||||||
|
$stageVersion = Versioned::get_versionnumber_by_stage($this->owner->class, 'Stage', $this->owner->ID);
|
||||||
|
$liveVersion = Versioned::get_versionnumber_by_stage($this->owner->class, 'Live', $this->owner->ID);
|
||||||
|
|
||||||
|
return ($stageVersion && !$liveVersion);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the equivalent of a DataList::create() call, querying the latest
|
* Return the equivalent of a DataList::create() call, querying the latest
|
||||||
|
@ -7,6 +7,9 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
|
|||||||
} else {
|
} else {
|
||||||
ss.i18n.addDictionary('en', {
|
ss.i18n.addDictionary('en', {
|
||||||
"FormField.NONE": "None",
|
"FormField.NONE": "None",
|
||||||
|
"File.DRAFT": "Draft",
|
||||||
|
"File.MODIFIED": "Modified",
|
||||||
|
"File.PUBLISHED": "Published",
|
||||||
"FILEIFRAMEFIELD.CONFIRMDELETE": "Are you sure you want to delete this file?",
|
"FILEIFRAMEFIELD.CONFIRMDELETE": "Are you sure you want to delete this file?",
|
||||||
"FILEIFRAMEFIELD.DELETEFILE": "Delete File",
|
"FILEIFRAMEFIELD.DELETEFILE": "Delete File",
|
||||||
"FILEIFRAMEFIELD.DELETEIMAGE": "Delete Image",
|
"FILEIFRAMEFIELD.DELETEIMAGE": "Delete Image",
|
||||||
@ -47,4 +50,4 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
|
|||||||
"UploadField.WRITEFAILED": "Failed to write file to disk",
|
"UploadField.WRITEFAILED": "Failed to write file to disk",
|
||||||
"VALIDATOR.FIELDREQUIRED": "Please fill out \"%s\", it is required."
|
"VALIDATOR.FIELDREQUIRED": "Please fill out \"%s\", it is required."
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
{
|
{
|
||||||
"FormField.NONE": "None",
|
"FormField.NONE": "None",
|
||||||
|
"File.DRAFT": "Draft",
|
||||||
|
"File.MODIFIED": "Modified",
|
||||||
|
"File.PUBLISHED": "Published",
|
||||||
"FILEIFRAMEFIELD.CONFIRMDELETE": "Are you sure you want to delete this file?",
|
"FILEIFRAMEFIELD.CONFIRMDELETE": "Are you sure you want to delete this file?",
|
||||||
"FILEIFRAMEFIELD.DELETEFILE": "Delete File",
|
"FILEIFRAMEFIELD.DELETEFILE": "Delete File",
|
||||||
"FILEIFRAMEFIELD.DELETEIMAGE": "Delete Image",
|
"FILEIFRAMEFIELD.DELETEIMAGE": "Delete Image",
|
||||||
|
@ -202,6 +202,7 @@ en:
|
|||||||
CssType: 'CSS file'
|
CssType: 'CSS file'
|
||||||
DmgType: 'Apple disk image'
|
DmgType: 'Apple disk image'
|
||||||
DocType: 'Word document'
|
DocType: 'Word document'
|
||||||
|
DRAFT: 'Draft'
|
||||||
Filename: Filename
|
Filename: Filename
|
||||||
GifType: 'GIF image - good for diagrams'
|
GifType: 'GIF image - good for diagrams'
|
||||||
GzType: 'GZIP compressed file'
|
GzType: 'GZIP compressed file'
|
||||||
@ -212,6 +213,7 @@ en:
|
|||||||
IcoType: 'Icon image'
|
IcoType: 'Icon image'
|
||||||
JpgType: 'JPEG image - good for photos'
|
JpgType: 'JPEG image - good for photos'
|
||||||
JsType: 'Javascript file'
|
JsType: 'Javascript file'
|
||||||
|
MODIFIED: 'Modified'
|
||||||
Mp3Type: 'MP3 audio file'
|
Mp3Type: 'MP3 audio file'
|
||||||
MpgType: 'MPEG video file'
|
MpgType: 'MPEG video file'
|
||||||
NOFILESIZE: 'Filesize is zero bytes.'
|
NOFILESIZE: 'Filesize is zero bytes.'
|
||||||
@ -220,6 +222,7 @@ en:
|
|||||||
PLURALNAME: Files
|
PLURALNAME: Files
|
||||||
PdfType: 'Adobe Acrobat PDF file'
|
PdfType: 'Adobe Acrobat PDF file'
|
||||||
PngType: 'PNG image - good general-purpose format'
|
PngType: 'PNG image - good general-purpose format'
|
||||||
|
PUBLISHED: 'Published'
|
||||||
SINGULARNAME: File
|
SINGULARNAME: File
|
||||||
TOOLARGE: 'Filesize is too large, maximum {size} allowed'
|
TOOLARGE: 'Filesize is too large, maximum {size} allowed'
|
||||||
TOOLARGESHORT: 'File size exceeds {size}'
|
TOOLARGESHORT: 'File size exceeds {size}'
|
||||||
|
Loading…
Reference in New Issue
Block a user