getElementsByTagName('a'); if (!$links) { return $results; } /** @var DOMElement $link */ foreach ($links as $link) { if (!$link->hasAttribute('href')) { continue; } $href = $link->getAttribute('href'); if (Director::is_site_url($href)) { $href = Director::makeRelative($href); } // Definitely broken links. if ($href == '' || $href[0] == '/') { $results[] = array( 'Type' => 'broken', 'Target' => null, 'Anchor' => null, 'DOMReference' => $link, 'Broken' => true ); continue; } // Link to a page on this site. $matches = array(); if (preg_match('/\[sitetree_link(?:\s*|%20|,)?id=(?[0-9]+)\](#(?.*))?/i', $href, $matches)) { // Check if page link is broken /** @var SiteTree $page */ $page = DataObject::get_by_id(SiteTree::class, $matches['id']); if (!$page) { // Page doesn't exist. $broken = true; } elseif (!empty($matches['anchor'])) { // Ensure anchor isn't broken on target page $anchor = preg_quote($matches['anchor'], '/'); $broken = !preg_match("/(name|id)=\"{$anchor}\"/", $page->Content); } else { $broken = false; } $results[] = array( 'Type' => 'sitetree', 'Target' => $matches['id'], 'Anchor' => empty($matches['anchor']) ? null : $matches['anchor'], 'DOMReference' => $link, 'Broken' => $broken ); continue; } // Local anchor. if (preg_match('/^#(.*)/i', $href, $matches)) { $anchor = preg_quote($matches[1], '#'); $results[] = array( 'Type' => 'localanchor', 'Target' => null, 'Anchor' => $matches[1], 'DOMReference' => $link, 'Broken' => !preg_match("#(name|id)=\"{$anchor}\"#", $htmlValue->getContent()) ); continue; } } return $results; } }