ENHANCEMENT [file_link id=n] shortcode support for file links in HtmlEditorField

This commit is contained in:
Sean Harvey 2012-03-01 21:13:42 +13:00
parent 586ca7374f
commit 898c8f5497
6 changed files with 88 additions and 13 deletions

View File

@ -49,6 +49,8 @@ Object::useCustomClass('Datetime', 'SS_Datetime', true);
*/
define('MCE_ROOT', 'sapphire/thirdparty/tinymce/');
ShortcodeParser::get('default')->register('file_link', array('File', 'link_shortcode_handler'));
/**
* The secret key that needs to be sent along with pings to /Email_BounceHandler
*
@ -81,4 +83,4 @@ SS_Cache::pick_backend('aggregatestore', 'aggregate', 1000);
Deprecation::notification_version('3.0.0');
// TODO Remove once new ManifestBuilder with submodule support is in place
require_once('admin/_config.php');
require_once('admin/_config.php');

View File

@ -137,7 +137,44 @@ class File extends DataObject {
* @var array
*/
protected static $cache_file_fields = null;
/**
* Replace "[file_link id=n]" shortcode with an anchor tag or link to the file.
* @param $arguments array Arguments to the shortcode
* @param $content string Content of the returned link (optional)
* @param $parser object Specify a parser to parse the content (see {@link ShortCodeParser})
* @return string anchor HTML tag if content argument given, otherwise file path link
*/
public static function link_shortcode_handler($arguments, $content = null, $parser = null) {
if(!isset($arguments['id']) || !is_numeric($arguments['id'])) return;
if (
!($record = DataObject::get_by_id('File', $arguments['id'])) // Get the file by ID.
&& !($record = DataObject::get_one('ErrorPage', '"ErrorCode" = \'404\'')) // Link to 404 page directly.
) {
return; // There were no suitable matches at all.
}
// build the HTML tag
if($content) {
// build some useful meta-data (file type and size) as data attributes
$attrs = ' ';
if($record instanceof File) {
foreach(array(
'class' => 'file',
'data-type' => $record->getExtension(),
'data-size' => $record->getSize()
) as $name => $value) {
$attrs .= sprintf('%s="%s" ', $name, $value);
}
}
return sprintf('<a href="%s"%s>%s</a>', $record->Link(), rtrim($attrs), $parser->parse($content));
} else {
return $record->Link();
}
}
/**
* Find a File object by the given filename.
*
@ -167,10 +204,10 @@ class File extends DataObject {
return Director::baseURL() . $this->RelativeLink();
}
function RelativeLink(){
function RelativeLink() {
return $this->Filename;
}
/**
* @deprecated 3.0 Use getTreeTitle()
*/

View File

@ -307,7 +307,7 @@ class HtmlEditorField_Toolbar extends RequestHandler {
$siteTree,
new TextField('external', _t('HtmlEditorField.URL', 'URL'), 'http://'),
new EmailField('email', _t('HtmlEditorField.EMAIL', 'Email address')),
new TreeDropdownField('file', _t('HtmlEditorField.FILE', 'File'), 'File', 'Filename', 'Title', true),
new TreeDropdownField('file', _t('HtmlEditorField.FILE', 'File'), 'File', 'ID', 'Title', true),
new TextField('Anchor', _t('HtmlEditorField.ANCHORVALUE', 'Anchor')),
new TextField('Description', _t('HtmlEditorField.LINKDESCR', 'Link description')),
new CheckboxField('TargetBlank', _t('HtmlEditorField.LINKOPENNEWWIN', 'Open link in a new window?')),
@ -663,4 +663,4 @@ class HtmlEditorField_Image extends HtmlEditorField_File {
return ($this->file) ? $this->file->CMSThumbnail() : sprintf('<img src="%s" />', $this->url);
}
}
}

View File

@ -379,7 +379,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
break;
case 'file':
href = this.find(':input[name=file]').val();
href = '[file_link id=' + this.find(':input[name=file]').val() + ']';
target = '_blank';
break;
@ -532,7 +532,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
email: RegExp.$1,
Description: title
};
} else if(href.match(/^(assets\/.*)$/)) {
} else if(href.match(/^(assets\/.*)$/) || href.match(/^\[file_link\s*(?:%20)?id=([0-9]+)\]?(#.*)?$/)) {
return {
LinkType: 'file',
file: RegExp.$1,
@ -565,7 +565,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
LinkType: 'internal'
};
}
}
}
});
$('form.htmleditorfield-linkform input[name=LinkType]').entwine({
@ -967,4 +967,4 @@ function sapphiremce_cleanup(type, value) {
}
return value;
}
}

View File

@ -8,7 +8,39 @@ class FileTest extends SapphireTest {
static $fixture_file = 'FileTest.yml';
protected $extraDataObjects = array('FileTest_MyCustomFile');
public function testLinkShortcodeHandler() {
$testFile = $this->objFromFixture('File', 'asdf');
$errorPage = $this->objFromFixture('ErrorPage', '404');
$parser = new ShortcodeParser();
$parser->register('file_link', array('File', 'link_shortcode_handler'));
$fileShortcode = sprintf('[file_link id=%d]', $testFile->ID);
$fileEnclosed = sprintf('[file_link id=%d]Example Content[/file_link]', $testFile->ID);
$fileShortcodeExpected = $testFile->Link();
$fileEnclosedExpected = sprintf('<a href="%s" class="file" data-type="txt" data-size="977 KB">Example Content</a>', $testFile->Link());
$this->assertEquals($fileShortcodeExpected, $parser->parse($fileShortcode), 'Test that simple linking works.');
$this->assertEquals($fileEnclosedExpected, $parser->parse($fileEnclosed), 'Test enclosed content is linked.');
$testFile->delete();
$fileShortcode = '[file_link id="-1"]';
$fileEnclosed = '[file_link id="-1"]Example Content[/file_link]';
$fileShortcodeExpected = $errorPage->Link();
$fileEnclosedExpected = sprintf('<a href="%s">Example Content</a>', $errorPage->Link());
$this->assertEquals($fileShortcodeExpected, $parser->parse($fileShortcode), 'Test link to 404 page if no suitable matches.');
$this->assertEquals($fileEnclosedExpected, $parser->parse($fileEnclosed));
$this->assertEquals('', $parser->parse('[file_link]'), 'Test that invalid ID attributes are not parsed.');
$this->assertEquals('', $parser->parse('[file_link id="text"]'));
$this->assertEquals('', $parser->parse('[file_link]Example Content[/file_link]'));
}
function testCreateWithFilenameWithSubfolder() {
// Note: We can't use fixtures/setUp() for this, as we want to create the db record manually.
// Creating the folder is necessary to avoid having "Filename" overwritten by setName()/setRelativePath(),
@ -373,4 +405,4 @@ class FileTest extends SapphireTest {
class FileTest_MyCustomFile extends File implements TestOnly {
}
}

View File

@ -27,4 +27,8 @@ File:
file1-folder1:
Filename: assets/FileTest-folder1/File1.txt
Name: File1.txt
ParentID: =>Folder.folder1
ParentID: =>Folder.folder1
ErrorPage:
404:
Title: Page not Found
ErrorCode: 404