Merged from branches/2.3

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@75592 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sean Harvey 2009-04-29 01:44:28 +00:00
parent 8d61656c2e
commit 42a6692d79
23 changed files with 295 additions and 187 deletions

View File

@ -76,8 +76,6 @@ class AssetAdmin extends LeftAndMain {
Requirements::css(SAPPHIRE_DIR . "/css/ComplexTableField.css");
Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin.js");
Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin_left.js");
Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin_right.js");
Requirements::javascript(CMS_DIR . "/javascript/CMSMain_upload.js");
Requirements::javascript(CMS_DIR . "/javascript/Upload.js");
@ -235,6 +233,8 @@ JS
foreach($newFiles as $newFile) {
$fileIDs[] = $newFile;
$fileObj = DataObject::get_one('File', "\"File\".\"ID\"=$newFile");
// notify file object after uploading
if (method_exists($fileObj, 'onAfterUpload')) $fileObj->onAfterUpload();
$fileNames[] = $fileObj->Name;
}
@ -254,6 +254,18 @@ JS
</script>
HTML;
}
/**
* Custom currentPage() method to handle opening the 'root' folder
*/
public function currentPage() {
$id = $this->currentPageID();
if($id && is_numeric($id)) {
return DataObject::get_by_id($this->stat('tree_class'), $id);
} else if($id == 'root') {
return singleton($this->stat('tree_class'));
}
}
/**
* Return the form that displays the details of a folder, including a file list and fields for editing the folder name.
@ -485,24 +497,18 @@ JS;
if(!$parentObj || !$parentObj->ID) $parent = 0;
}
$p = new Folder();
$p->ParentID = $parent;
$p->Title = $name;
$p->Name = $name;
// Get the folder to be created
if(isset($parentObj->ID)) $filename = $parentObj->FullPath . $p->Name;
else $filename = ASSETS_PATH . '/' . $p->Name;
if(isset($parentObj->ID)) $filename = $parentObj->FullPath . $name;
else $filename = ASSETS_PATH . '/' . $name;
// Ensure uniqueness
$i = 2;
$baseFilename = $filename . '-';
while(file_exists($filename)) {
$filename = $baseFilename . $i;
$p->Name = $p->Title = basename($filename);
$i++;
}
// Actually create
if(!file_exists(ASSETS_PATH)) {
mkdir(ASSETS_PATH);
@ -510,8 +516,12 @@ JS;
mkdir($filename);
chmod($filename, Filesystem::$file_create_mask);
// Create object
$p = new Folder();
$p->ParentID = $parent;
$p->Name = $p->Title = basename($filename);
$p->write();
if(isset($_REQUEST['returnID'])) {
return $p->ID;
} else {
@ -519,25 +529,6 @@ JS;
}
}
/**
* Return the given tree item to the client.
* If called by ajax, this will be some javascript commands.
* Otherwise, it will redirect back.
*/
public function returnItemToUser($p) {
if(!empty($_REQUEST['ajax'])) {
$parentID = (int) $p->ParentID;
return <<<JS
tree = $('sitetree');
var newNode = tree.createTreeNode($p->ID, "$p->Title", "$p->class");
tree.getTreeNodeByIdx($parentID).appendTreeNode(newNode);
newNode.selectTreeNode();
JS;
} else {
Director::redirectBack();
}
}
/**
* @return Form
*/
@ -573,13 +564,11 @@ JS;
foreach($ids as $id) {
if(is_numeric($id)) {
$record = DataObject::get_by_id($this->stat('tree_class'), $id);
if(!$record) {
Debug::message( "Record appears to be null" );
if($record) {
$script .= $this->deleteTreeNodeJS($record);
$record->delete();
$record->destroy();
}
$record->delete();
$record->destroy();
$script .= $this->deleteTreeNodeJS($record);
}
}
@ -724,4 +713,4 @@ JS;
}
}
?>
?>

View File

@ -16,10 +16,14 @@ class AssetTableField extends ComplexTableField {
"delete",
//"export",
);
/**
* Indicates whether a search is being executed on this object
*/
protected $searchingFor = null;
function __construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") {
parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin);
Requirements::javascript(CMS_DIR . '/javascript/AssetTableField.js');
$SNG_file = singleton('File');
@ -31,6 +35,7 @@ class AssetTableField extends ComplexTableField {
if(strpos($fieldName, '.') === false) $searchFilters[] = "\"$fieldName\" LIKE '%{$SQL_search}%'";
}
$this->sourceFilter = '(' . implode(' OR ', $searchFilters) . ')';
$this->searchingFor = $_REQUEST['FileSearch'];
}
$this->sourceSort = 'Title';
@ -38,15 +43,36 @@ class AssetTableField extends ComplexTableField {
}
function FieldHolder() {
$ret = parent::FieldHolder();
Requirements::javascript(CMS_DIR . '/javascript/AssetTableField.js');
Requirements::javascript('cms/javascript/ImageEditor/Activator.js');
return parent::FieldHolder();
return $ret;
}
function setFolder($folder) {
$this->folder = $folder;
$this->sourceFilter .= ($this->sourceFilter) ? " AND " : "";
$this->sourceFilter .= " \"ParentID\" = '" . $folder->ID . "' AND \"ClassName\" <> 'Folder'";
// If you are searching for files then show all those from subfolders
if($this->searchingFor) {
$folderIDs = $nextIDSet = array($folder->ID);
$folderClasses = "'" . implode("','", ClassInfo::subclassesFor("Folder")) . "'";
while($nextIDSet) {
// TO DO: In 2.4 this should be refactored to use the new data mapper.
$nextIDSet = DB::query("SELECT ID FROM `File` WHERE ParentID IN ("
. implode(", " , $nextIDSet) . ") AND ClassName IN ($folderClasses)")->column();
if($nextIDSet) $folderIDs = array_merge($folderIDs, $nextIDSet);
}
$this->sourceFilter .= " ParentID IN (" . implode(", ", $folderIDs) . ") AND ClassName <> 'Folder'";
// Otherwise just show the direct contents
} else {
$this->sourceFilter .= " ParentID = '" . $folder->ID . "' AND ClassName <> 'Folder'";
}
}
function Folder() {
@ -140,7 +166,7 @@ class AssetTableField extends ComplexTableField {
*/
function SearchForm() {
$searchFields = new FieldGroup(
new TextField('FileSearch', _t('MemberTableField.SEARCH', 'Search')),
new TextField('FileSearch', _t('MemberTableField.SEARCH', 'Search'), $this->searchingFor),
new HiddenField("ctf[ID]", '', $this->ID),
new HiddenField('FileFieldName', '', $this->name)
);
@ -160,4 +186,4 @@ class AssetTableField extends ComplexTableField {
}
?>
?>

View File

@ -62,6 +62,8 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
* SiteTree Columns that can be filtered using the the Site Tree Search button
*/
static $site_tree_filter_options = array(
'Title' => array('CMSMain.TITLE', 'Title'),
'MenuTitle' => array('CMSMain.MENUTITLE', 'Navigation Label'),
'ClassName' => array('CMSMain.PAGETYPE', 'Page Type'),
'Status' => array('CMSMain.STATUS', 'Status'),
'MetaDescription' => array('CMSMain.METADESC', 'Description'),
@ -70,10 +72,12 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
static function T_SiteTreeFilterOptions(){
return array(
'Title' => _t('CMSMain.TITLEOPT', 'Title', 0, 'The dropdown title in CMSMain left SiteTreeFilterOptions'),
'MenuTitle' => _t('CMSMain.MENUTITLEOPT', 'Navigation Label', 0, 'The dropdown title in CMSMain left SiteTreeFilterOptions'),
'ClassName' => _t('CMSMain.PAGETYPEOPT', 'Page Type', 0, "The dropdown title in CMSMain left SiteTreeFilterOptions"),
'Status' => _t('CMSMain.STATUSOPT', 'Status', 0, "The dropdown title in CMSMain left SiteTreeFilterOptions"),
'MetaDescription' => _t('CMSMain.METADESCOPT', 'Description', 0, "The dropdown title in CMSMain left SiteTreeFilterOptions"),
'MetaKeywords' => _t('CMSMain.METAKEYWORDSOPT', 'Keywords', 0, "The dropdown title in CMSMain left SiteTreeFilterOptions"),
'MetaKeywords' => _t('CMSMain.METAKEYWORDSOPT', 'Keywords', 0, "The dropdown title in CMSMain left SiteTreeFilterOptions")
);
}
@ -1057,6 +1061,7 @@ JS;
}
}
$oldID = $record->ID;
$record->delete();
$record->destroy();
@ -1066,13 +1071,14 @@ JS;
$liveRecord = Versioned::get_one_by_stage( $this->stat('tree_class'), 'Live', "\"{$this->stat('tree_class')}\".\"ID\"={$id}");
if($liveRecord) {
$title = Convert::raw2js($record->TreeTitle());
FormResponse::add("$('sitetree').setNodeTitle($record->OldID, '$title');");
FormResponse::add("$('Form_EditForm').reloadIfSetTo($record->OldID);");
$liveRecord->IsDeletedFromStage = true;
$title = Convert::raw2js($liveRecord->TreeTitle());
FormResponse::add("$('sitetree').setNodeTitle($oldID, '$title');");
FormResponse::add("$('Form_EditForm').reloadIfSetTo($oldID);");
} else {
FormResponse::add("var node = $('sitetree').getTreeNodeByIdx('$id');");
FormResponse::add("if(node && node.parentTreeNode) node.parentTreeNode.removeTreeNode(node);");
FormResponse::add("$('Form_EditForm').reloadIfSetTo($record->OldID);");
FormResponse::add("$('Form_EditForm').reloadIfSetTo($oldID);");
}
}
}
@ -1483,4 +1489,4 @@ function cmsMainMarkingFilterFunction($node) {
}
}
?>
?>

View File

@ -71,11 +71,13 @@ class CommentAdmin extends LeftAndMain {
"Name" => _t('CommentAdmin.AUTHOR', 'Author'),
"Comment" => _t('CommentAdmin.COMMENT', 'Comment'),
"Parent.Title" => _t('CommentAdmin.PAGE', 'Page'),
"CommenterURL" => _t('CommentAdmin.COMMENTERURL', 'URL'),
"Created" => _t('CommentAdmin.DATEPOSTED', 'Date Posted')
);
$popupFields = new FieldSet(
new TextField('Name', _t('CommentAdmin.NAME', 'Name')),
new TextField('CommenterURL', _t('CommentAdmin.COMMENTERURL', 'URL')),
new TextareaField('Comment', _t('CommentAdmin.COMMENT', 'Comment'))
);
@ -290,4 +292,4 @@ JS;
}
}
?>
?>

View File

@ -23,8 +23,14 @@ class CommentTableField extends ComplexTableField {
if(!empty($_REQUEST['CommentSearch'])) {
$this->sourceFilter[] = "( \"Name\" LIKE '%$search%' OR \"Comment\" LIKE '%$search%')";
}
}
function FieldHolder() {
$ret = parent::FieldHolder();
Requirements::javascript(CMS_DIR . '/javascript/CommentTableField.js');
return $ret;
}
function Items() {
@ -138,8 +144,10 @@ class CommentTableField extends ComplexTableField {
}
function SearchForm() {
$query = isset($_GET['CommentSearch']) ? $_GET['CommentSearch'] : null;
$searchFields = new FieldGroup(
new TextField('CommentSearch', _t('CommentTableField.SEARCH', 'Search')),
new TextField('CommentSearch', _t('CommentTableField.SEARCH', 'Search'), $query),
new HiddenField("ctf[ID]",'',$this->mode),
new HiddenField('CommentFieldName','',$this->name)
);

View File

@ -182,6 +182,7 @@ class LeftAndMain extends Controller {
Requirements::javascript(THIRDPARTY_DIR . '/hover.js');
Requirements::javascript(THIRDPARTY_DIR . '/layout_helpers.js');
Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang');
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang');
Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/effects.js');
Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/dragdrop.js');
@ -496,7 +497,7 @@ class LeftAndMain extends Controller {
public function returnItemToUser($p) {
if(Director::is_ajax()) {
// Prepare the object for insertion.
$parentID = (int)$p->ParentID;
$parentID = (int) $p->ParentID;
$id = $p->ID ? $p->ID : "new-$p->class-$p->ParentID";
$treeTitle = Convert::raw2js($p->TreeTitle());
$hasChildren = (is_numeric($id) && $p->AllChildren() && $p->AllChildren()->Count()) ? ' unexpanded' : '';
@ -506,7 +507,9 @@ class LeftAndMain extends Controller {
var tree = $('sitetree');
var newNode = tree.createTreeNode("$id", "$treeTitle", "{$p->class}{$hasChildren}");
node = tree.getTreeNodeByIdx($parentID);
if(!node){ node = tree.getTreeNodeByIdx(0); }
if(!node) {
node = tree.getTreeNodeByIdx(0);
}
node.open();
node.appendTreeNode(newNode);
newNode.selectTreeNode();
@ -515,12 +518,10 @@ JS;
return FormResponse::respond();
} else {
Director::redirect("admin/show/" . $p->ID);
Director::redirect('admin/' . self::$url_segment . '/show/' . $p->ID);
}
}
/**
* Save and Publish page handler
*/
@ -844,7 +845,7 @@ JS;
}
public function EditForm() {
if(isset($_REQUEST['ID'])) {
if(isset($_REQUEST['ID']) && is_numeric($_REQUEST['ID'])) {
$record = DataObject::get_by_id($this->stat('tree_class'), $_REQUEST['ID']);
} else {
$record = $this->CurrentPage();

View File

@ -98,8 +98,8 @@ class MemberTableField extends ComplexTableField {
} elseif(is_numeric($group)) {
$this->group = DataObject::get_by_id('Group', $group);
}
} elseif(is_numeric($_REQUEST['ctf'][$this->Name()]['ID'])) {
$this->group = DataObject::get_by_id('Group', $_REQUEST['ctf'][$this->Name()]['ID']);
} else if(isset($_REQUEST['ctf']) && is_numeric($_REQUEST['ctf'][$this->Name()]["ID"])) {
$this->group = DataObject::get_by_id('Group', $_REQUEST['ctf'][$this->Name()]["ID"]);
}
foreach(self::$addedFields as $key => $value) {
@ -119,9 +119,6 @@ class MemberTableField extends ComplexTableField {
}
parent::__construct($controller, $name, $sourceClass, $fieldList);
Requirements::javascript(CMS_DIR . '/javascript/MemberTableField.js');
Requirements::javascript(CMS_DIR . '/javascript/MemberTableField_popup.js');
$SQL_search = isset($_REQUEST['MemberSearch']) ? Convert::raw2sql($_REQUEST['MemberSearch']) : null;
if(!empty($_REQUEST['MemberSearch'])) {
@ -136,9 +133,18 @@ class MemberTableField extends ComplexTableField {
$this->setFieldListCsv($csvFieldList);
$this->setPageSize($this->stat('page_size'));
}
function FieldHolder() {
$ret = parent::FieldHolder();
Requirements::javascript(CMS_DIR . '/javascript/MemberTableField.js');
Requirements::javascript(CMS_DIR . "/javascript/MemberTableField_popup.js");
return $ret;
}
function sourceID() {
return $this->group->ID;
return ($this->group) ? $this->group->ID : 0;
}
function AddLink() {
@ -146,9 +152,12 @@ class MemberTableField extends ComplexTableField {
}
function SearchForm() {
$groupID = (isset($this->group)) ? $this->group->ID : 0;
$query = isset($_GET['MemberSearch']) ? $_GET['MemberSearch'] : null;
$searchFields = new FieldGroup(
new TextField('MemberSearch', _t('MemberTableField.SEARCH', 'Search')),
new HiddenField('ctf[ID]', '', $this->group->ID),
new TextField('MemberSearch', _t('MemberTableField.SEARCH', 'Search'), $query),
new HiddenField("ctf[ID]", '', $groupID),
new HiddenField('MemberFieldName', '', $this->name),
new HiddenField('MemberDontShowPassword', '', $this->hidePassword)
);
@ -290,8 +299,9 @@ class MemberTableField extends ComplexTableField {
$fields->push(new TextField($fieldName));
}
}
$fields->push(new HiddenField('ctf[ID]', null, $this->group->ID));
if($this->group) {
$fields->push(new HiddenField('ctf[ID]', null, $this->group->ID));
}
$actions = new FieldSet(
new FormAction('addtogroup', _t('MemberTableField.ADD','Add'))
);
@ -358,14 +368,16 @@ class MemberTableField extends ComplexTableField {
// We use the group to get the members, as they already have the bulk of the look up functions
$start = isset($_REQUEST['ctf'][$this->Name()]['start']) ? $_REQUEST['ctf'][$this->Name()]['start'] : 0;
$this->sourceItems = $this->group->Members(
$this->pageSize, // limit
$start, // offset
$this->sourceFilter,
$this->sourceSort
);
$this->sourceItems = false;
if($this->group) {
$this->sourceItems = $this->group->Members(
$this->pageSize, // limit
$start, // offset
$this->sourceFilter,
$this->sourceSort
);
}
// Because we are not used $this->upagedSourceItems any more, and the DataObjectSet is usually the source
// that a large member set runs out of memory. we disable it here.
//$this->unpagedSourceItems = $this->group->Members('', '', $this->sourceFilter, $this->sourceSort);
@ -395,11 +407,13 @@ class MemberTableField extends ComplexTableField {
*/
class MemberTableField_Popup extends ComplexTableField_Popup {
function __construct($controller, $name, $fields, $sourceClass, $readonly=false, $validator = null) {
parent::__construct($controller, $name, $fields, $sourceClass, $readonly, $validator);
function forTemplate() {
$ret = parent::forTemplate();
Requirements::javascript(CMS_DIR . '/javascript/MemberTableField.js');
Requirements::javascript(CMS_DIR . '/javascript/MemberTableField_popup.js');
return $ret;
}
}

View File

@ -128,8 +128,8 @@ abstract class ModelAdmin extends LeftAndMain {
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/livequery/jquery.livequery.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/ui/ui.core.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/ui/ui.tabs.js');
//Requirements::javascript(THIRDPARTY_DIR . '/jquery/ui/ui.core.js');
//Requirements::javascript(THIRDPARTY_DIR . '/jquery/ui/ui.tabs.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/form/jquery.form.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/effen/jquery.fn.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery_improvements.js');
@ -332,7 +332,7 @@ class ModelAdmin_CollectionController extends Controller {
$form = new Form($this, "SearchForm",
$fields,
new FieldSet(
new FormAction('search', _t('MemberTableField.SEARCH')),
new FormAction('search', _t('MemberTableField.SEARCH', 'Search')),
$clearAction = new ResetFormAction('clearsearch', _t('ModelAdmin.CLEAR_SEARCH','Clear Search'))
),
$validator

View File

@ -42,16 +42,20 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
Requirements::css(THIRDPARTY_DIR . "/greybox/greybox.css");
Requirements::css(SAPPHIRE_DIR . "/css/ComplexTableField.css");
Requirements::javascript(CMS_DIR . "/javascript/SecurityAdmin.js");
Requirements::javascript(CMS_DIR . "/javascript/SecurityAdmin_left.js");
Requirements::javascript(CMS_DIR . "/javascript/SecurityAdmin_right.js");
Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin_left.js');
Requirements::javascript(CMS_DIR . '/javascript/SecurityAdmin_right.js');
Requirements::javascript(THIRDPARTY_DIR . "/greybox/AmiJS.js");
Requirements::javascript(THIRDPARTY_DIR . "/greybox/greybox.js");
}
public function getEditForm($id) {
$record = DataObject::get_by_id($this->stat('tree_class'), $id);
$record = null;
if($id && $id != 'root') {
$record = DataObject::get_by_id($this->stat('tree_class'), $id);
}
if(!$record) return false;
$fields = $record->getCMSFields();
@ -197,9 +201,11 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
$memberID = $this->urlParams['OtherID'];
if(is_numeric($groupID) && is_numeric($memberID)) {
$member = DataObject::get_by_id('Member', (int) $memberID);
if(!$member->canDelete()) return Security::permissionFailure($this);
$member->Groups()->remove((int)$groupID);
FormResponse::add("reloadMemberTableField();");
} else {
user_error("SecurityAdmin::removememberfromgroup: Bad parameters: Group=$groupID, Member=$memberID", E_USER_ERROR);
@ -209,24 +215,32 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider {
}
/**
* Return the entire site tree as a nested set of ULs
* Return the entire site tree as a nested set of ULs.
* @return string Unordered list <UL> HTML
*/
public function SiteTreeAsUL() {
$obj = singleton($this->stat('tree_class'));
$obj->markPartialTree();
if($p = $this->currentPage()) $obj->markToExpose($p);
// getChildrenAsUL is a flexible and complex way of traversing the tree
$siteTreeItem = $obj->getChildrenAsUL("",
' "<li id=\"record-$child->ID\" class=\"$child->class " . ($child->Locked ? " nodelete" : "") . ' .
' ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
' "<a href=\"admin/security/show/$child->ID\" >" . $child->TreeTitle() . "</a>" ',$this);
$siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\">" .
"<li id=\"record-0\" class=\"Root\">" .
"<a href=\"admin/security/show/0\" ><strong>"._t('SecurityAdmin.SGROUPS',"Security groups")."</strong></a>"
. $siteTreeItem .
"</li>" .
"</ul>";
$siteTreeList = $obj->getChildrenAsUL(
'',
'"<li id=\"record-$child->ID\" class=\"$child->class " . ($child->Locked ? " nodelete" : "") . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
'"<a href=\"" . Director::link(substr($extraArg->Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "</a>" ',
$this,
true
);
// Wrap the root if needs be
$rootLink = $this->Link() . 'show/root';
$rootTitle = _t('SecurityAdmin.SGROUPS', 'Security Groups');
if(!isset($rootID)) {
$siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\"><li id=\"record-root\" class=\"Root\"><a href=\"$rootLink\"><strong>{$rootTitle}</strong></a>"
. $siteTreeList . "</li></ul>";
}
return $siteTree;
}

View File

@ -11,7 +11,8 @@ class PageComment extends DataObject {
"Comment" => "Text",
"IsSpam" => "Boolean",
"NeedsModeration" => "Boolean",
"CommenterURL" => "Varchar(255)"
"CommenterURL" => "Varchar(255)",
"SessionID" => "Varchar(255)"
);
static $has_one = array(
@ -116,8 +117,13 @@ class PageComment extends DataObject {
return self::$bbcode;
}
function fieldLabels() {
$labels = parent::fieldLabels();
/**
*
* @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields
*
*/
function fieldLabels($includerelations = true) {
$labels = parent::fieldLabels($includerelations);
$labels['Name'] = _t('PageComment.Name', 'Author Name');
$labels['Comment'] = _t('PageComment.Comment', 'Comment');
$labels['IsSpam'] = _t('PageComment.IsSpam', 'Spam?');
@ -185,6 +191,8 @@ class PageComment_Controller extends Controller {
$comment->NeedsModeration = false;
$comment->write();
// @todo Report to spamprotecter this is true
if(Director::is_ajax()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
@ -194,68 +202,80 @@ class PageComment_Controller extends Controller {
}
function reportspam() {
if(SSAkismet::isEnabled()) {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment) {
// check they have access
if(Permission::check('CMS_ACCESS_CMSMain')) {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment) {
// if spam protection module exists
if(class_exists('SpamProtecterManager')) {
SpamProtecterManager::send_feedback($comment, 'spam');
$comment->setField('IsSpam', true);
$comment->write();
}
// If Akismet is enabled
else if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
$akismet->setCommentAuthor($comment->getField('Name'));
$akismet->setCommentContent($comment->getField('Comment'));
$akismet->submitSpam();
} catch (Exception $e) {
// Akismet didn't work, most likely the service is down.
}
if(SSAkismet::getSaveSpam()) {
$comment->setField('IsSpam', true);
$comment->write();
} else {
$comment->delete();
}
}
}
if(Director::is_ajax()) {
if(SSAkismet::getSaveSpam()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
echo '';
}
} else {
Director::redirectBack();
}
}
if(Director::is_ajax()) {
if(SSAkismet::getSaveSpam()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
echo '';
}
} else {
Director::redirectBack();
}
}
/**
* Report a Spam Comment as valid comment (not spam)
*/
function reportham() {
if(SSAkismet::isEnabled()) {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
if($comment) {
if(Permission::check('CMS_ACCESS_CMSMain')) {
$comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']);
// if spam protection module exists
if(class_exists('SpamProtecterManager')) {
SpamProtecterManager::send_feedback($comment, 'ham');
$comment->setField('IsSpam', false);
$comment->write();
}
if($comment) {
if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
$akismet->setCommentAuthor($comment->getField('Name'));
$akismet->setCommentContent($comment->getField('Comment'));
$akismet->submitHam();
} catch (Exception $e) {
// Akismet didn't work, most likely the service is down.
}
$comment->setField('IsSpam', false);
$comment->write();
}
}
if(Director::is_ajax()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
Director::redirectBack();
}
}
if(Director::is_ajax()) {
echo $comment->renderWith('PageCommentInterface_singlecomment');
} else {
Director::redirectBack();
}
}

View File

@ -219,7 +219,7 @@ class PageCommentInterface_Form extends Form {
Cookie::set("PageCommentInterface_Name", $data['Name']);
Cookie::set("PageCommentInterface_CommenterURL", $data['CommenterURL']);
Cookie::set("PageCommentInterface_Comment", $data['Comment']);
if(SSAkismet::isEnabled()) {
try {
$akismet = new SSAkismet();
@ -249,10 +249,10 @@ class PageCommentInterface_Form extends Form {
//check if spam question was right.
if(MathSpamProtection::isEnabled()){
if(!MathSpamProtection::correctAnswer($data['Math'])){
if(!Director::is_ajax()) {
Director::redirectBack();
}
return "spamprotectionfailed"; //used by javascript for checking if the spam question was wrong
if(!Director::is_ajax()) {
Director::redirectBack();
}
return "spamprotectionfailed"; //used by javascript for checking if the spam question was wrong
}
}
@ -267,9 +267,16 @@ class PageCommentInterface_Form extends Form {
$comment = Object::create('PageComment');
$this->saveInto($comment);
// Store the Session ID if needed for Spamprotection
if($session = Session::get('mollom_user_session_id')) {
$comment->SessionID = $session;
Session::clear('mollom_user_session_id');
}
$comment->IsSpam = false;
$comment->NeedsModeration = PageComment::moderationEnabled();
$comment->write();
Cookie::set("PageCommentInterface_Comment", '');
if(Director::is_ajax()) {
if($comment->NeedsModeration){
@ -278,7 +285,16 @@ class PageCommentInterface_Form extends Form {
echo $comment->renderWith('PageCommentInterface_singlecomment');
}
} else {
Director::redirectBack();
// since it is not ajax redirect user down to their comment since it has been posted
// get the pages url off the comments parent ID.
if($comment->ParentID) {
$page = DataObject::get_by_id("Page", $comment->ParentID);
if($page) {
// Redirect to the actual post on the page.
return Director::redirect(Director::baseURL(). $page->URLSegment.'#PageComment_'.$comment->ID);
}
}
return Director::redirectBack(); // worst case, just go back to the page
}
}
}

View File

@ -132,7 +132,8 @@ ul.tree.multiselect li.selected span.a.unexpanded span.b {
}
ul.tree span.a a.notinmenu, ul.tree span.a a.notinmenu * {
ul.tree span.a a.notinmenu, ul.tree span.a a.notinmenu *,
#publication_key span.notinmenu {
color: #77A;
}

View File

@ -160,7 +160,7 @@
background: #fff;
}
.right form .mceEditor .mceFirst {
background:url(../images/textures/mce_editor.gif) repeat-x bottom;
background: #fbfbfb url(../images/textures/mce_editor.gif) repeat-x bottom;
}
.right form .mceEditor .mceToolbar table {
background: transparent;

View File

@ -81,10 +81,15 @@ li.action button {
background: #fff;
}
.ajaxActions input.disabled {
.ajaxActions input.disabled,
input.disabled {
color: #666;
}
input.disabled:hover {
background-image: url(../images/textures/ToolBar.png);
}
input.action.loading, input.action.loading:hover {
padding-left: 22px;
background: url(../images/network-save.gif) 3px 2px no-repeat;

View File

@ -475,7 +475,7 @@ appendLoader(function () {
});
Behaviour.register({
'#UnusedThumbnails button': {
'#Form_EditForm_delete_unused_thumbnails': {
onclick : function(event) {
Event.stop(event);
var options = {

View File

@ -78,7 +78,7 @@ CommentFilterButton.prototype = {
initialize: function() {
this.inputFields = new Array();
var childNodes = this.parentNode.getElementsByTagName('input');
var childNodes = this.parentNode.parentNode.getElementsByTagName('input');
for( var index = 0; index < childNodes.length; index++ ) {
if( childNodes[index].tagName ) {
@ -108,7 +108,7 @@ CommentFilterButton.prototype = {
var form = Event.findElement(e,"form");
var fieldName = $('CommentFieldName').value;
var fieldID = form.id + '_' + fieldName;
var updateURL = form.action + '/field/' + fieldName + '?ajax=1';
for( var index = 0; index < this.inputFields.length; index++ ) {
if( this.inputFields[index].tagName ) {
@ -118,8 +118,8 @@ CommentFilterButton.prototype = {
updateURL += ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '');
new Ajax.Updater( fieldID, updateURL, {
onSuccess: function() {
Behaviour.apply(fieldID, true);
onComplete: function() {
Behaviour.apply($(fieldID), true);
},
onFailure: function( response ) {
errorMessage('Could not filter results: ' + response.responseText );

View File

@ -175,14 +175,14 @@ window.onresize = function(init) {
}
if(typeof fitToParent == 'function') {
fitToParent('Form_EditForm', -20);
fitToParent('Form_EditForm', 4);
if($('Form_EditorToolbarImageForm') && $('Form_EditorToolbarImageForm').style.display == "block") {
fitToParent('Form_EditorToolbarImageForm', 5);
fitToParent($('Form_EditorToolbarImageForm').getElementsByTagName('fieldset')[0]);
if(navigator.appName == "Microsoft Internet Explorer") {
fitToParent('Image');
} else {
fitToParent('Image', 190);
fitToParent('Image', 210);
}
}
if($('Form_EditorToolbarFlashForm') && $('Form_EditorToolbarFlashForm').style.display == "block") {
@ -587,7 +587,9 @@ ChangeTracker.prototype = {
},
field_changed: function() {
return this.originalSerialized != Form.Element.serialize(this);
// Something a value will go from 'undefined' to ''. Ignore such changes
if((this.originalSerialized+'') == 'undefined') return Form.Element.serialize(this) ? true : false;
else return this.originalSerialized != Form.Element.serialize(this);
},
/**
@ -603,8 +605,8 @@ ChangeTracker.prototype = {
if(!element.isChanged) element.isChanged = this.field_changed;
if(!this.changeDetection_fieldsToIgnore[element.name] && element.isChanged()) {
//if( window.location.href.match( /^https?:\/\/dev/ ) )
// Debug.log('Changed:'+ element.id + '(' + this.originalSerialized +')->('+Form.Element.serialize(element)+')' );
//console.log('Changed:'+ element.id + '(' + this.originalSerialized +')->('+Form.Element.serialize(element)+')' );
//console.log(element)
return true;
}

View File

@ -39,11 +39,9 @@ CMSForm.prototype = {
*/
closeIfSetTo: function(id) {
if(this.elements.ID && this.elements.ID.value == id) {
this.innerHTML = "<p>" + ss.i18n._t('LeftAndMain.PAGEWASDELETED') + "</p>";
// Note: TinyMCE coupling
if((typeof tinymce != 'undefined') && tinymce.EditorManager) {
tinymce.EditorManager.editors = {};
}
tinymce_removeAll();
this.innerHTML = "<p>" + ss.i18n._t('LeftAndMain.PAGEWASDELETED') + "</p>";
}
},
@ -87,6 +85,9 @@ CMSForm.prototype = {
// Rewrite iframe links (for IE)
rightHTML = rightHTML.replace(/(<iframe[^>]*src=")([^"]+)("[^>]*>)/g, '$1' + baseHref() + '$2$3');
// Note: TinyMCE coupling
tinymce_removeAll();
// Prepare iframes for removal, otherwise we get loading bugs
var i, allIframes = this.getElementsByTagName('iframe');
if(allIframes) for(i=0;i<allIframes.length;i++) {
@ -119,18 +120,9 @@ CMSForm.prototype = {
_TAB_DIVS_ON_PAGE = [];
try {
var tabs = document.getElementsBySelector('#' + this.id + ' ul.tabstrip');
} catch(er) { /*alert('a: '+ er.message + '\n' + er.line);*/ }
try {
for(var i=0;i<tabs.length;i++) if(tabs[i].tagName) initTabstrip(tabs[i]);
} catch(er) { /*alert('b: '+ er.message + '\n' + er.line);*/ }
// Note: TinyMCE coupling
if((typeof tinymce != 'undefined') && tinymce.EditorManager) {
tinymce.EditorManager.editors = {};
}
//initTabstripe() become livequery in tabstrip.js, so we don't need to call it for each tab strip here.
// We assume that an evaluated response is generated by FormResponse
// which takes care of calling these method it
if (!evalResponse) {
@ -454,4 +446,21 @@ window.name = windowName('cms');
function windowName(suffix) {
var base = document.getElementsByTagName('base')[0].href.replace('~','').replace('http://','').replace(/\//g,'_').replace(/\./g,'_');
return base + suffix;
}
/**
* Remove all the currently active TinyMCE editors.
* Note: everything that calls this has an inappropriate coupling to TinyMCE.
* Perhaps an observer pattern could be used, where TinyMCE listens to a onBeforeCMSPageLoad
* event?
*/
function tinymce_removeAll() {
if((typeof tinymce != 'undefined') && tinymce.EditorManager) {
var id;
for(id in tinymce.EditorManager.editors) {
tinymce.EditorManager.editors[id].remove();
}
tinymce.EditorManager.editors = {};
}
}

View File

@ -26,19 +26,6 @@ $(document).ready(function() {
$(this).parent().addClass('ajaxActions');
});
/**
* Attach tabs plugin to the set of search filter and edit forms
*/
$('ul.tabstrip').livequery(function() {
$(this).tabs({
// This show handler is necessary to get tabs working properly with the crappy old layout_helpers.js layout
// manager
show : function() {
if(window.onresize) window.onresize();
}
});
});
/*
* Highlight buttons on click
*/
@ -303,6 +290,7 @@ $(document).ready(function() {
}
Behaviour.apply(); // refreshes ComplexTableField
if(window.onresize) window.onresize();
}));
},

View File

@ -71,6 +71,9 @@ Behaviour.register({
rightHTML = formContent;
rightHTML = rightHTML.replace(/href *= *"#/g, 'href="' + window.location.href.replace(/#.*$/,'') + '#');
// Note: TinyMCE coupling
tinymce_removeAll();
// Prepare iframes for removal, otherwise we get loading bugs
var i, allIframes = this.getElementsByTagName('iframe');
if(allIframes) for(i=0;i<allIframes.length;i++) {
@ -96,11 +99,6 @@ Behaviour.register({
for(var i=0;i<tabs.length;i++) if(tabs[i].tagName) initTabstrip(tabs[i]);
} catch(er) { /*alert('b: '+ er.message + '\n' + er.line); */}
// Note: TinyMCE coupling
if((typeof tinymce != 'undefined') && tinymce.EditorManager) {
tinymce.EditorManager.editors = {};
}
// if(this.prepareForm) this.prepareForm();
Behaviour.apply($('Form_EditForm'));
if(this.prepareForm)

View File

@ -1,6 +1,12 @@
/**
* Configuration for the left hand tree
*/
if(typeof SiteTreeHandlers == 'undefined') SiteTreeHandlers = {};
SiteTreeHandlers.parentChanged_url = 'admin/security/ajaxupdateparent';
SiteTreeHandlers.orderChanged_url = 'admin/security/ajaxupdatesort';
SiteTreeHandlers.loadPage_url = 'admin/security/getitem';
SiteTreeHandlers.loadTree_url = 'admin/security/getsubtree';
SiteTreeHandlers.showRecord_url = 'admin/security/show/';
SiteTreeHandlers.controller_url = 'admin/security';
_HANDLER_FORMS['deletegroup'] = 'deletegroup_options';

View File

@ -26,12 +26,12 @@ if((typeof tinyMCE != 'undefined')) {
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_toolbar_parent : "right",
plugins : "media,contextmenu,table,emotions,paste,../../tinymce_ssbuttons,../../tinymce_advcode,spellchecker",
plugins : "media,contextmenu,table,emotions,paste,../../tinymce_ssbuttons,../../tinymce_advcode,spellchecker,fullscreen",
blockquote_clear_tag : "p",
table_inline_editing : true,
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,separator,bullist,numlist,outdent,indent,blockquote,hr,charmap",
theme_advanced_buttons2 : "undo,redo,separator,cut,copy,paste,pastetext,pasteword,spellchecker,separator,ssimage,ssflash,sslink,unlink,anchor,separator,advcode,search,replace,selectall,visualaid,separator,tablecontrols",
theme_advanced_buttons3 : "",
theme_advanced_buttons2 : "undo,redo,separator,cut,copy,paste,pastetext,pasteword,spellchecker,separator,ssimage,ssflash,sslink,unlink,anchor,separator,advcode,fullscreen,separator,search,replace,selectall,visualaid",
theme_advanced_buttons3 : "tablecontrols",
spellchecker_languages : "$SpellcheckLangs",
template_templates : [
@ -42,6 +42,7 @@ if((typeof tinyMCE != 'undefined')) {
relative_urls : true,
verify_html : true,
use_native_selects : true, // fancy selects are bug as of SS 2.3.0
valid_elements : "+a[id|rel|rev|dir|tabindex|accesskey|type|name|href|target|title|class],-strong/-b[class],-em/-i[class],-strike[class],-u[class],#p[id|dir|class|align],-ol[class],-ul[class],-li[class],br,img[id|dir|longdesc|usemap|class|src|border|alt=|title|width|height|align],-sub[class],-sup[class],-blockquote[dir|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|dir|id|style],-tr[id|dir|class|rowspan|width|height|align|valign|bgcolor|background|bordercolor|style],tbody[id|class|style],thead[id|class|style],tfoot[id|class|style],-td[id|dir|class|colspan|rowspan|width|height|align|valign|scope|style],-th[id|dir|class|colspan|rowspan|width|height|align|valign|scope|style],caption[id|dir|class],-div[id|dir|class|align|style],-span[class|align],-pre[class|align],address[class|align],-h1[id|dir|class|align],-h2[id|dir|class|align],-h3[id|dir|class|align],-h4[id|dir|class|align],-h5[id|dir|class|align],-h6[id|dir|class|align],hr[class],dd[id|class|title|dir],dl[id|class|title|dir],dt[id|class|title|dir]",
extended_valid_elements : "img[class|src|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],iframe[src|name|width|height|align|frameborder|marginwidth|marginheight|scrolling]"
});
}

View File

@ -80,6 +80,8 @@
<ins style="cursor: help" title="<% _t('ADDEDNOTPUB','Added to the draft site and not published yet') %>"><% _t('NEW','new') %></ins>
<del style="cursor: help" title="<% _t('DELETEDSTILLLIVE','Deleted from the draft site but still on the live site') %>"><% _t('DEL','deleted') %></del>
<span style="cursor: help" title="<% _t('EDITEDNOTPUB','Edited on the draft site and not published yet') %>" class="modified"><% _t('CHANGED','changed') %></span>
<span style="cursor: help" title="<% _t('NOTINMENU','Excluded from navigation menus') %>" class="notinmenu"><% _t('HIDDEN','hidden') %></span>
</div>
<!--