Skip to content

Commit

Permalink
fix(FileLinkReplaceExtension) Re-wrote file link logic (#3)
Browse files Browse the repository at this point in the history
* fix(FileLinkReplaceExtension) Re-wrote file link logic

Previous implementation wouldn't handle having non-file links as the first
ones appearing on the page. Instead, the files are looked up by the links
present in content to ensure a like-for-like match

* fix(FileLinkReplaceExtensionTest) Fixed missing method reference
  • Loading branch information
nyeholt authored and jason-symbiote committed Oct 1, 2018
1 parent 829c4f3 commit 8a35aad
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 34 deletions.
39 changes: 18 additions & 21 deletions src/Exension/FileLinkReplaceExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Symbiote\ContentReplace\Model\WYSIWYGElement;
use SilverStripe\Control\Controller;
use SilverStripe\Admin\LeftAndMain;
use SilverStripe\Assets\File;

class FileLinkReplaceExtension extends Extension
{
Expand Down Expand Up @@ -61,35 +62,29 @@ private function replaceFileLinkWithTemplate($value)
return $value;
}

// Match the index of $fileIds
$index = 0;
return preg_replace_callback(
$files = File::get()->filter('ID', $fileIds);

$fileMap = [];
// create a map of URL to file object for later use
foreach ($files as $file) {
$fileMap[$file->getURL()] = $file;
}

$res = preg_replace_callback(
// Match all a tags, even with nested child html tags
'#<a[\s]+[^>]+>(?:.(?!\<\/a\>))*.<\/a>#i',
function ($val) use ($fileIds, &$index) {
'#<a.*?href=\"(.*?)\".*?>(?:.(?!\<\/a\>))*.<\/a>#i',
function ($val) use ($fileMap) {
// $val[0] - the link HTML tag, eg: <a href="link">text</a>
$linkHtml = $val[0];
$element = WYSIWYGElement::create();
$href = $val[1];

if ($index >= sizeof($fileIds)) {
return $linkHtml;
}

$id = $fileIds[$index];
if (!$id) {
return $linkHtml;
}
$element = WYSIWYGElement::create();

$element->setFileId((int)$id);
// check if the element has href attribute and
// it's linking to a File rather than an external url
$file = $element->getFile();
if (!$file) {
if (!isset($fileMap[$href])) {
return $linkHtml;
}

// Don't increment index unless it's a file link
$index += 1;
$element->setFile($fileMap[$href]);

// set default link HTML
$element->setLinkHTML($linkHtml);
Expand All @@ -104,5 +99,7 @@ function ($val) use ($fileIds, &$index) {
},
$value
);

return $res;
}
}
15 changes: 6 additions & 9 deletions src/Model/WYSIWYGElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@ class WYSIWYGElement extends ViewableData
protected $linkHTML = "";

/**
* @var int|null
* @var File|null
*/
protected $fileId = null;
protected $file = null;

/**
* @return File|null
*/
public function getFile()
{
$id = $this->getFileId();
return $id ?
File::get()->filter('ID', $id)->first() :
null;
return $this->file;
}

/**
Expand All @@ -47,14 +44,14 @@ public function getLinkHTML()
return $this->linkHTML;
}

public function setFileId(int $id)
public function setFile(File $file)
{
$this->fileId = $id;
$this->file = $file;
return $this;
}

public function getFileId()
{
return $this->fileId;
return $this->file->ID;
}
}
8 changes: 4 additions & 4 deletions tests/FileLinkReplaceExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function testFileLinkReplace()
{

$testFile = $this->objFromFixture(File::class, 'example_file');

$parser = new ShortcodeParser();
$parser->register('file_link', [FileShortcodeProvider::class, 'handle_shortcode']);

Expand All @@ -60,8 +60,8 @@ public function testFileLinkReplace()

$element = WYSIWYGElement::create();
$linkHtml = '<a href="/assets/FileLinkReplaceExtensionTest/55b443b601/example.pdf" class="file" data-type="pdf" data-size="977 KB">Example Content</a>';
$element->setFileId($testFile->ID);

$element->setFile($testFile);
$element->setLinkHTML($linkHtml);
$htmlExpected = $element
->renderWith(
Expand All @@ -84,7 +84,7 @@ public function testFileLinkReplace()
);

$testFile->delete();

$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,id="-1"]'), 'Short code is removed if file record is not present.');
Expand Down

0 comments on commit 8a35aad

Please sign in to comment.