tags which are then converted with javascript. * The {@link Requirements} system is used to ensure that all necessary javascript is included. */ class HtmlEditorField extends TextareaField { protected $rows; /** * Construct a new HtmlEditor field */ function __construct($name, $title = "", $rows = 15, $cols = 20, $value = "", $form = null) { parent::__construct($name, $title, $rows, $cols, $value, $form); $this->extraClass = 'typography'; } /** * Returns the a "; } /** * This function has been created to explicit the functionnality. */ function setCSSClass($class){ $this->extraClass = $class; } function saveInto($record) { $content = $this->value; $content = preg_replace('/mce_real_src="[^"]+"/i', "", $content); $content = eregi_replace('width=([0-9]+)','width="\\1"',$content); $content = eregi_replace('height=([0-9]+)','height="\\1"',$content); $content = preg_replace_callback('/(]* )(width="|height="|src=")([^"]+)("[^>]* )(width="|height="|src=")([^"]+)("[^>]* )(width="|height="|src=")([^"]+)("[^>]*>)/i', "HtmlEditorField_dataValue_processImage", $content); // If we don't have a containing block element, add a p tag. if(!ereg("^[ \t\r\n]*<", $content)) $content = "

$content

"; $links = HTTP::getLinksIn($content); if($links) foreach($links as $link) { $link = Director::makeRelative($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; // This caused bugs in the publication script // $candidatePage->destroy(); } else { $record->HasBrokenLink = 1; } } else if($link{0} == '/') { $record->HasBrokenLink = 1; } else if($candidateFile = DataObject::get_one("File", "Filename = '" . Convert::raw2sql(urldecode($link)) . "'", false)) { $linkedFiles[] = $candidateFile->ID; // $candidateFile->destroy(); } } $images = HTTP::getImagesIn($content); if($images){ foreach($images as $image) { $image = Director::makeRelative($image); if(substr($image,0,7) == 'assets/') { $candidateImage = DataObject::get_one("File", "Filename = '$image'"); if($candidateImage) $linkedFiles[] = $candidateImage->ID; else $record->HasBrokenFile = 1; } } } $fieldName = $this->name; if($record->ID && $record->hasMethod('LinkTracking') && $linkTracking = $record->LinkTracking()) { $linkTracking->removeByFilter("FieldName = '$fieldName'"); if(isset($linkedPages)) foreach($linkedPages as $item) { $linkTracking->add($item, array("FieldName" => $fieldName)); } // $linkTracking->destroy(); } if($record->ID && $record->hasMethod('ImageTracking') && $imageTracking = $record->ImageTracking()) { $imageTracking->removeByFilter("FieldName = '$fieldName'"); if(isset($linkedFiles)) foreach($linkedFiles as $item) { $imageTracking->add($item, array("FieldName" => $fieldName)); } // $imageTracking->destroy(); } $record->$fieldName = $content; } function rewriteLink($old, $new) { $bases[] = ""; $bases[] = Director::baseURL(); $bases[] = Director::absoluteBaseURL(); foreach($bases as $base) { $this->value = ereg_replace("(href=\"?)$base$old","\\1$new", $this->value); } $this->value = ereg_replace("(href=\"?)$base$old","\\1$new", $this->value); return $this->value; } function performReadonlyTransformation() { $field = new HtmlEditorField_readonly($this->name, $this->title, $this->value); $field->setForm($this->form); $field->dontEscape = true; return $field; } } class HtmlEditorField_readonly extends ReadonlyField { function Field() { $valforInput = $this->value ? Convert::raw2att($this->value) : ""; return "
id() . "\">$this->value

name."\" value=\"".$valforInput."\" />"; } function Type() { return 'readonly'; } } /** * Proccesses HTML images into the correct proportions from * the regular expression evaluated on the save. */ function HtmlEditorField_dataValue_processImage($parts) { // The info could be in any order $info[$parts[2]] = $parts[3]; $partSource[$parts[2]] = 3; $info[$parts[5]] = $parts[6]; $partSource[$parts[5]] = 6; $info[$parts[8]] = $parts[9]; $partSource[$parts[8]] = 9; $src = Director::makeRelative($info['src="']); if(substr($src,0,10) == '../assets/') $src = substr($src,3); $width = $info['width="']; $height = $info['height="']; if(!$width || !$height) { user_error("Can't find width/height in $text", E_USER_ERROR); } // find the image inserted from the HTML editor $image = Image::find($src); if($image) { // If we have an image, generate the resized image. $resizedImage = $image->getFormattedImage("ResizedImage",$width, $height); $parts[$partSource['src="']] = $resizedImage->getRelativePath() ; } else { $parts[$partSource['src="']] = ""; } $parts[0] = ""; $result = implode("", $parts); return $result; } class HtmlEditorField_Toolbar extends ViewableData { protected $controller, $name; function __construct($controller, $name) { $this->controller = $controller; $this->name = $name; } function Buttons() { return new DataObjectSet( new HtmlEditorField_button("Bold","bold","Bold (Ctrl+B)"), new HtmlEditorField_button("Italic","italic","Italic (Ctrl+I)"), new HtmlEditorField_button("Underline","underline", "Underline (Ctrl+U)"), new HtmlEditorField_button("Strikethrough","strikethrough"), new HtmlEditorField_separator(), new HtmlEditorField_button("JustifyLeft","justifyleft","Align left"), new HtmlEditorField_button("JustifyCenter","justifycenter","Align center"), new HtmlEditorField_button("JustifyRight","justifyright","Align right"), new HtmlEditorField_button("JustifyFull","justifyfull","Justify"), /*new HtmlEditorField_dropdown("mceSetCSSClass", "styleSelect", array( "mceContentBody" => "mceContentBody", )),*/ new HtmlEditorField_dropdown("FormatBlock", "formatSelect", array( "

" => "Paragraph", "

" => "Address", "
" => "Preformatted",
				"

" => "Heading 1", "

" => "Heading 2", "

" => "Heading 3", "

" => "Heading 4", "

" => "Heading 5", "
" => "Heading 6", )), new HtmlEditorField_separator(), new HtmlEditorField_button("InsertUnorderedList","bullist","Bullet-point list"), new HtmlEditorField_button("InsertOrderedList","numlist","Numbered list"), new HtmlEditorField_button("Outdent","outdent","Decrease outdent"), new HtmlEditorField_button("Indent","indent","Increase indent"), new HtmlEditorField_button("inserthorizontalrule","hr","Insert horizontal line"), new HtmlEditorField_button("mceCharMap","charmap","Insert symbol"), new HtmlEditorField_break(), new HtmlEditorField_button("Undo","undo","Undo (Ctrl+Z)"), new HtmlEditorField_button("Redo","redo","Redo (Ctrl+Y)"), new HtmlEditorField_separator(), new HtmlEditorField_button("Cut","cut","Cut (Ctrl+X)"), new HtmlEditorField_button("Copy","copy","Copy (Ctrl+C)"), new HtmlEditorField_button("Paste","paste","Paste (Ctrl+V)"), new HtmlEditorField_separator(), new HtmlEditorField_button("ssImage","image","Insert image"), new HtmlEditorField_button("ssFlash","flash:flash","Insert flash"), new HtmlEditorField_button("ssLink","link","Insert/edit link for highlighted text"), new HtmlEditorField_button("unlink","unlink","Remove link"), new HtmlEditorField_button("mceInsertAnchor","anchor","Insert/edit anchor"), new HtmlEditorField_separator(), new HtmlEditorField_button("mceCodeEditor","code","Edit HTML Code"), // We don't need this because tinymce is good at auto-tidying // new HtmlEditorField_button("mceCleanup","cleanup","Clean up code"), new HtmlEditorField_button("mceToggleVisualAid","visualaid","Show/hide guidelines"), new HtmlEditorField_separator(), new HtmlEditorField_button("mceInsertTable","table:table","Insert table"), new HtmlEditorField_button("mceTableInsertRowBefore","table:table_insert_row_before","Insert row before"), new HtmlEditorField_button("mceTableInsertRowAfter","table:table_insert_row_after","Insert row after"), new HtmlEditorField_button("mceTableDeleteRow","table:table_delete_row","Delete row"), new HtmlEditorField_button("mceTableInsertColBefore","table:table_insert_col_before","Insert column before"), new HtmlEditorField_button("mceTableInsertColAfter","table:table_insert_col_after","Insert column after"), new HtmlEditorField_button("mceTableDeleteCol","table:table_delete_col","Delete column") ); } /** * Returns the form which the Link button returns. * The link functions below are shown and hidden via javascript */ function LinkForm() { $form = new Form( $this->controller, "{$this->name}.LinkForm", new FieldSet( new OptionsetField("LinkType", "Link to", array( "internal" => "Page on the site", "external" => "Another website", "email" => "Email address", "file" => "Download a file", ) ), new TreeDropdownField("internal", "Page", "SiteTree", "URLSegment"), new TextField("external", "URL"), new EmailField("email", "Email address"), new TreeDropdownField("file","File","File", "Filename"), new TextField("Description", "Link description"), new CheckboxField("TargetBlank", "Open link in a new window?") ), new FieldSet( new FormAction("insert", "Insert link"), new FormAction("remove", "Remove link"), new FormAction("cancel", "Cancel") ) ); $form->loadDataFrom($this); return $form; } function ImageForm() { $form = new Form($this->controller, "{$this->name}.ImageForm", new FieldSet( new TreeDropdownField("FolderID", "Folder", "Folder"), new ThumbnailStripField("Image", "FolderID", "getimages"), new TextField("AltText", "Description", "", 80), new DropdownField("CSSClass", "Alignment / style", array( "left" => "On the left, with text wrapping around.", "right" => "On the right, with text wrapping around.", "center" => "Centred, on its own.", )), new FieldGroup("Dimensions", new TextField("Width", "", "", 5), new TextField("Height", "x", "", 5) ) ), new FieldSet( /* new FormAction("insertimage", "Insert image"), new FormAction("cancel", "Cancel") */ ) ); $form->loadDataFrom($this); return $form; } function FlashForm() { $form = new Form($this->controller, "{$this->name}.FlashForm", new FieldSet( new TreeDropdownField("FolderID", "Folder", "Folder"), new ThumbnailStripField("Flash", "FolderID", "getflash"), new TextField("Width", "Width (px)"), new TextField("Height", "Height (px)") ), new FieldSet() ); $form->loadDataFrom($this); return $form; } } /** * These controls are used when manually constructing a toolbar, as we do in the CMS */ class HtmlEditorField_control extends ViewableData { protected $command; function Type() { return substr($this->class,strrpos($this->class,'_')+1); } function Command() { return $this->command; } } class HtmlEditorField_button extends HtmlEditorField_control { function __construct($command, $icon, $title = null) { $this->title = $title ? $title : $command; $this->command = $command; $this->icon = $icon; parent::__construct(); } function Command() { return $this->command; } function Icon() { if(strpos($this->icon,'/') !== false) { return $this->icon; } else if(strpos($this->icon,':') !== false) { list($plugin,$icon) = explode(':', $this->icon, 2); return MCE_ROOT . 'plugins/' . $plugin . '/images/' . $icon . '.gif'; } else { return MCE_ROOT . 'themes/advanced/images/' . $this->icon . '.gif'; } } function Title() { return $this->title; } function IDSegment() { return $this->icon; } } class HtmlEditorField_separator extends HtmlEditorField_control { } class HtmlEditorField_dropdown extends HtmlEditorField_control { protected $options, $idSegment; function __construct($command, $idSegment, $options) { $this->command = $command; $this->options = $options; $this->idSegment = $idSegment; parent::__construct(); } function Options() { $options = ''; foreach($this->options as $k => $v) { $k = Convert::raw2att($k); $v = Convert::raw2xml($v); $options .= "\n"; } return $options; } function IDSegment() { return $this->idSegment; } } class HtmlEditorField_break extends HtmlEditorField_control { } ?>