Created
October 3, 2009 02:53
-
-
Save ajshort/200362 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @@ -30,61 +30,80 @@ class HtmlEditorField extends TextareaField { | |
| /** | |
| * @return string | |
| */ | |
| function Field() { | |
| + // mark up broken links | |
| + $value = new SS_HTMLValue($this->value); | |
| + $parser = ShortcodeParser::get_active(); | |
| + | |
| + if($links = $value->getElementsByTagName('a')) foreach($links as $link) { | |
| + $matches = array(); | |
| + | |
| + if(preg_match('/\[sitetree_link id=([0-9]+)\]/i', $link->getAttribute('href'), $matches)) { | |
| + if(!DataObject::get_by_id('SiteTree', $matches[1])) { | |
| + $class = $link->getAttribute('class'); | |
| + $link->setAttribute('class', ($class ? "$class ss-broken" : 'ss-broken')); | |
| + } | |
| + } | |
| + } | |
| + | |
| return $this->createTag ( | |
| 'textarea', | |
| array ( | |
| 'class' => $this->extraClass(), | |
| 'rows' => $this->rows, | |
| 'cols' => $this->cols, | |
| - 'style' => "width: 97%; height: " . ($this->rows * 16) . "px", // Prevents horizontal scrollbars | |
| + 'style' => 'width: 97%; height: ' . ($this->rows * 16) . 'px', // prevents horizontal scrollbars | |
| 'tinymce' => 'true', | |
| 'id' => $this->id(), | |
| 'name' => $this->name | |
| ), | |
| - htmlentities($this->value, ENT_COMPAT, 'UTF-8') | |
| + htmlentities($value->getContent(), ENT_COMPAT, 'UTF-8') | |
| ); | |
| } | |
| public function saveInto($record) { | |
| if($record->escapeTypeForField($this->name) != 'xml') { | |
| throw new Exception ( | |
| 'HtmlEditorField->saveInto(): This field should save into a HTMLText or HTMLVarchar field.' | |
| ); | |
| } | |
| - $value = $this->value ? $this->value : '<p></p>'; | |
| - $value = preg_replace('/src="([^\?]*)\?r=[0-9]+"/i', 'src="$1"', $value); | |
| - | |
| $linkedPages = array(); | |
| $linkedFiles = array(); | |
| - $document = new DOMDocument(null, 'UTF-8'); | |
| - $document->strictErrorChecking = false; | |
| - $document->loadHTML($value); | |
| + $htmlValue = new SS_HTMLValue($this->value); | |
| + $parser = ShortcodeParser::get_active(); | |
| // Populate link tracking for internal links & links to asset files. | |
| - if($links = $document->getElementsByTagName('a')) foreach($links as $link) { | |
| - $link = Director::makeRelative($link->getAttribute('href')); | |
| + if($links = $htmlValue->getElementsByTagName('a')) foreach($links as $link) { | |
| + $href = Director::makeRelative($link->getAttribute('href')); | |
| - if(preg_match('/\[sitetree_link id=([0-9]+)\]/i', $link, $matches)) { | |
| + if(preg_match('/\[sitetree_link id=([0-9]+)\]/i', $href, $matches)) { | |
| $ID = $matches[1]; | |
| + // clear out any broken link classes | |
| + if($class = $link->getAttribute('class')) { | |
| + $link->setAttribute('class', preg_replace('/(^ss-broken|ss-broken$| ss-broken )/', null, $class)); | |
| + } | |
| + | |
| if($page = DataObject::get_by_id('SiteTree', $ID)) { | |
| $linkedPages[] = $page->ID; | |
| } else { | |
| $record->HasBrokenLink = true; | |
| } | |
| - } elseif($link[0] != '/' && $file = File::find($link)) { | |
| + } elseif($href[0] != '/' && $file = File::find($href)) { | |
| $linkedFiles[] = $file->ID; | |
| } | |
| } | |
| // Resample images, add default attributes and add to assets tracking. | |
| - if($images = $document->getElementsByTagName('img')) foreach($images as $img) { | |
| + if($images = $htmlValue->getElementsByTagName('img')) foreach($images as $img) { | |
| + // strip any ?r=n data from the src attribute | |
| + $img->setAttribute('src', preg_replace('/([^\?]*)\?r=[0-9]+$/i', '$1', $img->getAttribute('src'))); | |
| + | |
| if(!$image = File::find($path = Director::makeRelative($img->getAttribute('src')))) { | |
| if(substr($path, 0, strlen(ASSETS_DIR) + 1) == ASSETS_DIR . '/') { | |
| $record->HasBrokenFile = true; | |
| } | |
| @@ -114,11 +133,11 @@ class HtmlEditorField extends TextareaField { | |
| if($record->ID && $record->many_many('ImageTracking') && $tracker = $record->ImageTracking()) { | |
| $tracker->setByIDList($linkedFiles); | |
| } | |
| - $record->{$this->name} = substr(simplexml_import_dom($document)->body->asXML(), 6, -7); | |
| + $record->{$this->name} = $htmlValue->getContent(); | |
| } | |
| /** | |
| * @return HtmlEditorField_Readonly | |
| */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This class acts as a wrapper around the built in DOMDocument class in order to use it to manage a HTML snippet, | |
| * rather than a whole document, while still exposing the DOMDocument API. | |
| * | |
| * @package sapphire | |
| * @subpackage integration | |
| */ | |
| class SS_HTMLValue extends ViewableData { | |
| /** | |
| * @var DOMDocument | |
| */ | |
| protected $document; | |
| /** | |
| * @param string $content | |
| */ | |
| public function __construct($content = null) { | |
| $this->document = new DOMDocument('1.0', 'UTF-8'); | |
| $this->document->scrictErrorChecking = false; | |
| $this->setContent($content); | |
| parent::__construct(); | |
| } | |
| /** | |
| * @return string | |
| */ | |
| public function getContent() { | |
| // saveXML is used to allow for XHTML-compliant output | |
| $xml = $this->getDocument()->saveXML($this->getDocument()->documentElement->lastChild); | |
| if(substr($xml, 0, 6) != '<body>') { | |
| return null; | |
| } else { | |
| // as DOMDocument adds enclosing body tags by default, these need to be stripped | |
| return substr($xml, 6, -7); | |
| } | |
| } | |
| /** | |
| * @param string $content | |
| * @return bool | |
| */ | |
| public function setContent($content) { | |
| return $this->getDocument()->loadHTML(sprintf ( | |
| '<meta http-equiv="content-type" content="text/html; charset=utf-8"><body>%s</body>', $content | |
| )); | |
| } | |
| /** | |
| * @return DOMDocument | |
| */ | |
| public function getDocument() { | |
| return $this->document; | |
| } | |
| /** | |
| * A simple convinience wrapper around DOMDocument::getElementsByTagName(). | |
| * | |
| * @param string $name | |
| * @return DOMNodeList | |
| */ | |
| public function getElementsByTagName($name) { | |
| return $this->getDocument()->getElementsByTagName($name); | |
| } | |
| /** | |
| * @see HTMLValue::getContent() | |
| */ | |
| public function forTemplate() { | |
| return $this->getContent(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment