BUGFIX: Fixed link rewriting to work on other HTMLText fields (from r99517) (from r101110)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@111590 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2010-10-04 04:48:47 +00:00
parent ca0550bb3a
commit e2b6291a30
2 changed files with 232 additions and 28 deletions

View File

@ -1375,41 +1375,54 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
function syncLinkTracking() {
// Set LinkTracking appropriately
$links = HTTP::getLinksIn($this->Content);
// Build a list of HTMLText fields
$allFields = $this->db();
$htmlFields = array();
foreach($allFields as $field => $fieldSpec) {
if(preg_match('/([^(]+)/', $fieldSpec, $matches)) {
$class = $matches[0];
if($class == 'HTMLText' || is_subclass_of($class, 'HTMLText')) $htmlFields[] = $field;
}
}
$linkedPages = array();
$linkedFiles = array();
$this->HasBrokenLink = false;
$this->HasBrokenFile = false;
if($links) foreach($links as $link) {
if(preg_match('/^([A-Za-z0-9_-]+)\/?(#.*)?$/', $link, $parts)) {
$candidatePage = DataObject::get_one("SiteTree", "\"URLSegment\" = '" . urldecode( $parts[1] ). "'", false);
if($candidatePage) {
$linkedPages[] = $candidatePage->ID;
} else {
foreach($htmlFields as $field) {
// Set LinkTracking appropriately
$links = HTTP::getLinksIn($this->$field);
if($links) foreach($links as $link) {
if(preg_match('/^([A-Za-z0-9_-]+)\/?(#.*)?$/', $link, $parts)) {
$candidatePage = DataObject::get_one("SiteTree", "\"URLSegment\" = '" . urldecode( $parts[1] ). "'", false);
if($candidatePage) {
$linkedPages[] = $candidatePage->ID;
} else {
$this->HasBrokenLink = true;
}
} else if(substr($link,0,7) == 'assets/') {
$candidateFile = File::find(Convert::raw2sql(urldecode($link)));
if($candidateFile) {
$linkedFiles[] = $candidateFile->ID;
} else {
$this->HasBrokenFile = true;
}
} else if($link == '' || $link[0] == '/') {
$this->HasBrokenLink = true;
}
} else if(substr($link,0,7) == 'assets/') {
$candidateFile = File::find(Convert::raw2sql(urldecode($link)));
if($candidateFile) {
$linkedFiles[] = $candidateFile->ID;
} else {
$this->HasBrokenFile = true;
}
} else if($link == '' || $link[0] == '/') {
$this->HasBrokenLink = true;
}
}
$images = HTTP::getImagesIn($this->Content);
if($images) {
foreach($images as $image) {
$image = Director::makeRelative($image);
if(substr($image,0,7) == 'assets/') {
$candidateImage = File::find($image);
if($candidateImage) $linkedFiles[] = $candidateImage->ID;
else $this->HasBrokenFile = true;
$images = HTTP::getImagesIn($this->$field);
if($images) {
foreach($images as $image) {
$image = Director::makeRelative($image);
if(substr($image,0,7) == 'assets/') {
$candidateImage = File::find($image);
if($candidateImage) $linkedFiles[] = $candidateImage->ID;
else $this->HasBrokenFile = true;
}
}
}
}
@ -2019,8 +2032,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($original->URLSegment && $original->URLSegment != $this->URLSegment) {
foreach($this->BackLinkTracking() as $linkedPage) {
$linkedPageLive = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $linkedPage->ID);
$linkedPageLive->rewriteLink($original->URLSegment . '/', $this->URLSegment . '/');
$linkedPageLive->writeToStage('Live');
if($linkedPageLive) {
$linkedPageLive->rewriteLink($original->URLSegment . '/', $this->URLSegment . '/');
$linkedPageLive->writeToStage('Live');
}
}
}

View File

@ -2,6 +2,10 @@
class SiteTreeBacklinksTest extends SapphireTest {
static $fixture_file = "sapphire/tests/SiteTreeBacklinksTest.yml";
protected $requiredExtensions = array(
'SiteTree' => array('SiteTreeBacklinksTest_DOD'),
);
static function set_up_once() {
SiteTreeTest::set_up_once();
@ -60,6 +64,191 @@ class SiteTreeBacklinksTest extends SapphireTest {
// assert backlink to page 3 exists
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page3->ID)), 'Assert backlink to page 3 doesn\'t exist');
}
function testChangingUrlOnDraftSiteRewritesLink() {
// load page 1
$page1 = $this->objFromFixture('Page', 'page1');
// assert backlink to page 3 exists
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->BackLinkTracking()->containsIDs(array($page3->ID)), 'Assert backlink to page 3 exists');
// assert hyperlink to page 1's current url exists on page 3
$links = HTTP::getLinksIn($page3->Content);
$this->assertContains('page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
// change url of page 1
$page1->URLSegment = 'new-url-segment';
$page1->write();
// load page 3
$page3 = $this->objFromFixture('Page', 'page3');
// assert hyperlink to page 1's new url exists
$links = HTTP::getLinksIn($page3->Content);
$this->assertContains('new-url-segment/', $links, 'Assert hyperlink to page 1\'s new url exists on page 3');
}
function testChangingUrlOnLiveSiteRewritesLink() {
// publish page 1 & 3
$page1 = $this->objFromFixture('Page', 'page1');
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->doPublish());
$this->assertTrue($page3->doPublish());
// load pages from live
$page1live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page1->ID);
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
// assert backlink to page 3 exists
$this->assertTrue($page1live->BackLinkTracking()->containsIDs(array($page3live->ID)), 'Assert backlink to page 3 exists');
// assert hyperlink to page 1's current url exists on page 3
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
// change url of page 1
$page1live->URLSegment = 'new-url-segment';
$page1live->writeToStage('Live');
// load page 3 from live
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
// assert hyperlink to page 1's new url exists
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('new-url-segment/', $links, 'Assert hyperlink to page 1\'s new url exists on page 3');
}
function testPublishingPageWithModifiedUrlRewritesLink() {
// publish page 1 & 3
$page1 = $this->objFromFixture('Page', 'page1');
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->doPublish());
$this->assertTrue($page3->doPublish());
// load page 3 from live
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
// assert hyperlink to page 1's current url exists
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
// rename url of page 1 on stage
$page1->URLSegment = 'new-url-segment';
$page1->write();
// assert hyperlink to page 1's current publish url exists
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
// publish page 1
$this->assertTrue($page1->doPublish());
// assert hyperlink to page 1's new published url exists
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('new-url-segment/', $links, 'Assert hyperlink to page 1\'s new published url exists on page 3');
}
function testPublishingPageWithModifiedLinksRewritesLinks() {
// publish page 1 & 3
$page1 = $this->objFromFixture('Page', 'page1');
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->doPublish());
$this->assertTrue($page3->doPublish());
// assert hyperlink to page 1's current url exists
$links = HTTP::getLinksIn($page3->Content);
$this->assertContains('page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
// change page 1 url on draft
$page1->URLSegment = 'new-url-segment';
// save page 1
$page1->write();
// assert page 3 on draft contains new page 1 url
$page3 = $this->objFromFixture('Page', 'page3');
$links = HTTP::getLinksIn($page3->Content);
$this->assertContains('new-url-segment/', $links, 'Assert hyperlink to page 1\'s current draft url exists on page 3');
// publish page 3
$this->assertTrue($page3->doPublish());
// assert page 3 on published site contains old page 1 url
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
// publish page 1
$this->assertTrue($page1->doPublish());
// assert page 3 on published site contains new page 1 url
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->Content);
$this->assertContains('new-url-segment/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
}
function testLinkTrackingOnExtraContentFields() {
$page1 = $this->objFromFixture('Page', 'page1');
$page2 = $this->objFromFixture('Page', 'page2');
$page1->doPublish();
$page2->doPublish();
// assert backlink to page 2 doesn't exist
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 doesn\'t exist');
// add hyperlink to page 1 on page 2
$page2->ExtraContent .= '<p><a href="page1/">Testing page 1 link</a></p>';
$page2->write();
$page2->doPublish();
// assert backlink to page 2 exists
$this->assertTrue($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 exists');
// update page1 url
$page1 = $this->objFromFixture('Page', 'page1');
$page1->URLSegment = "page1-new-url";
$page1->write();
// confirm that draft link on page2 has been rewritten
$page2 = $this->objFromFixture('Page', 'page2');
$this->assertEquals('<p><a href="page1-new-url/">Testing page 1 link</a></p>', $page2->ExtraContent);
// confirm that published link hasn't
$page2Live = Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = $page2->ID");
$this->assertEquals('<p><a href="page1/">Testing page 1 link</a></p>', $page2Live->ExtraContent);
// publish page1 and confirm that the link on the published page2 has now been updated
$page1->doPublish();
$page2Live = Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = $page2->ID");
$this->assertEquals('<p><a href="page1-new-url/">Testing page 1 link</a></p>', $page2Live->ExtraContent);
// remove hyperlink to page 1
$page2->ExtraContent = '<p>No links anymore!</p>';
$page2->write();
// assert backlink to page 2 no longer exists
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 has been removed');
}
}
class SiteTreeBacklinksTest_DOD extends DataObjectDecorator implements TestOnly {
function extraStatics() {
return array(
'db' => array(
'ExtraContent' => 'HTMLText',
),
);
}
function updateCMSFields(&$fields) {
$fields->addFieldToTab("Root.Content.Main", new HTMLEditorField("ExtraContent"));
}
}
?>