group = $group; } else if(is_numeric($group)){ $this->group = DataObject::get_by_id('Group',$group); } } else if(is_numeric($_REQUEST['ctf'][$this->Name()]["ID"])) { $this->group = DataObject::get_by_id('Group',$_REQUEST['ctf'][$this->Name()]["ID"]); } $sourceClass = $this->stat("data_class"); foreach( self::$addedPermissions as $permission ) array_push( $this->permissions, $permission ); $fieldList = array( "FirstName" => "Firstname", "Surname" => "Surname", "Email" => "Email" ); $csvFieldList = $fieldList; foreach( self::$addedCsvFields as $key => $value ) { $csvFieldList[$key] = $value; } foreach( self::$addedFields as $key => $value ) { $fieldList[$key] = $value; } if(!$hidePassword) { $fieldList["Password"] = "Password"; } if(isset($_REQUEST['ctf']['childID']) && $memberID = $_REQUEST['ctf']['childID']) { $SNG_member = DataObject::get_by_id($this->stat("data_class"),$_REQUEST['ctf']['childID']); } else { $SNG_member = singleton(Object::getCustomClass($this->stat("data_class"))); } $detailFormFields = $SNG_member->getCMSFields(); $this->detailFormValidator = $SNG_member->getValidator(); $this->pageSize = $pageLimit; // Legacy: Use setCustomSourceItems() instead. if($members) { $this->customSourceItems = $this->memberListWithGroupID($members, $group); } $this->hidePassword = $hidePassword; parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields); Requirements::javascript("cms/javascript/MemberTableField.js"); // construct the filter and sort if(isset($_REQUEST['MemberOrderByField'])) { $this->sourceSort = "`" . Convert::raw2sql($_REQUEST['MemberOrderByField']) . "`" . Convert::raw2sql( $_REQUEST['MemberOrderByOrder'] ); } // search $search = isset($_REQUEST['MemberSearch']) ? Convert::raw2sql($_REQUEST['MemberSearch']) : null; if(!empty($_REQUEST['MemberSearch'])) { //$this->sourceFilter[] = "( `Email` LIKE '%$search%' OR `FirstName` LIKE '%$search%' OR `Surname` LIKE '%$search%' )"; $sourceF = "( "; foreach( $fieldList as $k => $v ) $sourceF .= "`$k` LIKE '%$search%' OR "; $this->sourceFilter[] = substr( $sourceF, 0, -3 ) . ")"; } // filter by groups // TODO Not implemented yet if(isset($_REQUEST['ctf'][$this->Name()]['GroupID']) && is_numeric($_REQUEST['ctf'][$this->Name()]['GroupID'])) { $this->sourceFilter[] = "`GroupID`='{$_REQUEST['ctf'][$this->Name()]['GroupID']}'"; } elseif($this->group) { //$this->sourceFilter[] = "`GroupID`='{$this->group->ID}'"; // If the table is not clean (without duplication), the total and navigation wil not work well, so uncheck the big line below $this->sourceFilter[] = "`Group_Members`.`ID` IN (SELECT `ID` FROM `Group_Members` WHERE `GroupID`='{$this->group->ID}' GROUP BY `MemberID` HAVING MIN(`ID`))"; } $this->sourceJoin = " INNER JOIN `Group_Members` ON `MemberID`=`Member`.`ID`"; $this->setFieldListCsv( $csvFieldList ); } /** * Overridden functions */ function sourceID() { return $this->group->ID; } function AddLink() { return "{$this->PopupBaseLink()}&methodName=add"; } function DetailForm() { $ID = Convert::raw2xml($_REQUEST['ctf']['ID']); $childID = isset($_REQUEST['ctf']['childID']) ? Convert::raw2xml($_REQUEST['ctf']['childID']) : 0; $childClass = Convert::raw2xml($_REQUEST['fieldName']); $methodName = isset($_REQUEST['methodName']) ? $_REQUEST['methodName'] : ''; if($methodName == "add") { $parentIdName = $this->getParentIdName($childClass,$this->getParentClass()); if(!$parentIdName) { user_error("ComplexTableField::DetailForm() Dataobject does not seem to have an 'has-one'-relationship", E_USER_WARNING); return; } $this->detailFormFields->push(new HiddenField('parentClass'," ",$this->getParentClass())); } // the ID field confuses the Controller-logic in finding the right view for ReferencedField $this->detailFormFields->removeByName('ID'); $this->detailFormFields->push(new HiddenField("ctf[ID]"," ",$ID)); // add a namespaced ID instead thats "converted" by saveComplexTableField() $this->detailFormFields->push(new HiddenField("ctf[childID]","",$childID)); $this->detailFormFields->push(new HiddenField("ClassName","",$this->sourceClass)); $form = new MemberTableField_Popup($this, "DetailForm", $this->detailFormFields, $this->sourceClass, $methodName == "show", $this->detailFormValidator); if (is_numeric($childID)) { if ($methodName == "show" || $methodName == "edit") { $childData = DataObject::get_by_id($this->sourceClass, $childID); $form->loadDataFrom($childData); } } if ($methodName == "show") { $form->makeReadonly(); } return $form; } function SearchForm() { $searchFields = new FieldGroup( new TextField('MemberSearch', 'Search'), new HiddenField("ctf[ID]",'',$this->group->ID), new HiddenField('MemberFieldName','',$this->name), new HiddenField('MemberDontShowPassword','',$this->hidePassword) ); $orderByFields = new FieldGroup( new LabelField('Order by'), new FieldSet( new DropdownField('MemberOrderByField','', array( 'FirstName' => 'FirstName', 'Surname' => 'Surname', 'Email' => 'Email' )), new DropdownField('MemberOrderByOrder','',array( 'ASC' => 'Ascending', 'DESC' => 'Descending' )) ) ); $groups = DataObject::get('Group'); $groupArray = array('' => 'Any group'); foreach( $groups as $group ) { $groupArray[$group->ID] = $group->Title; } $groupFields = new DropdownField('MemberGroup','Filter by group',$groupArray ); $actionFields = new LiteralField('MemberFilterButton',''); $fieldContainer = new FieldGroup( $searchFields, // $orderByFields, // $groupFields, $actionFields ); return $fieldContainer->FieldHolder(); } /** * Add existing member to group rather than creating a new member */ function addtogroup() { $data = $_REQUEST; unset($data['ID']); if(!is_numeric($data['ctf']['ID'])) { FormResponse::status_messsage('Adding failed', 'bad'); } $className = $this->stat('data_class'); $record = new $className(); $record->update($data); $record->write(); // To Avoid duplication in the Group_Members table if the ComponentSet.php is not modified just uncomment le line below //if( ! $record->isInGroup( $data['ctf']['ID'] ) ) $record->Groups()->add( $data['ctf']['ID'] ); $this->sourceItems(); // TODO add javascript to highlight added row (problem: might not show up due to sorting/filtering) FormResponse::update_dom_id($this->id(), $this->renderWith($this->template), true); FormResponse::status_message('Added member to group', 'good'); return FormResponse::respond(); } /** * Custom delete implementation: * Remove member from group rather than from the database */ function delete() { $groupID = Convert::raw2sql($_REQUEST["ctf"]["ID"]); $memberID = Convert::raw2sql($_REQUEST["ctf"]["childID"]); if(is_numeric($groupID) && is_numeric($memberID)) { $member = DataObject::get_by_id('Member', $memberID); $member->Groups()->remove($groupID); } else { user_error("MemberTableField::delete: Bad parameters: Group=$groupID, Member=$memberID", E_USER_ERROR); } return FormResponse::respond(); } /** * ################################# * Utility Functions * ################################# */ function getParentClass() { return "Group"; } function getParentIdName($childClass,$parentClass){ return "GroupID"; } /** * ################################# * Custom Functions * ################################# */ function memberListWithGroupID($members, $group) { $newMembers = new DataObjectSet(); foreach($members as $member) { $newMembers->push($member->customise(array("GroupID" => $group->ID))); } return $newMembers; } function setGroup($group) { $this->group = $group; } function setController($controller) { $this->controller = $controller; } function GetControllerName() { return $this->controller->class; } /** * Add existing member to group by name (with JS-autocompletion) */ function AddRecordForm() { $fields = new FieldSet(); foreach($this->FieldList() as $fieldName=>$fieldTitle) { $fields->push(new TextField($fieldName)); } $fields->push(new HiddenField("ctf[ID]", null, $this->group->ID)); return new TabularStyle(new Form($this->controller,'AddRecordForm', $fields, new FieldSet( new FormAction("addtogroup", "Add") ) )); } /** * Cached version for getting the appropraite members for this particular group. * * This includes getting inherited groups, such as groups under groups. */ function sourceItems(){ // Caching. if($this->sourceItems) { return $this->sourceItems; } // Setup limits $limitClause = ""; if(isset($_REQUEST['ctf'][$this->Name()]['start']) && is_numeric($_REQUEST['ctf'][$this->Name()]['start'])) { $limitClause = ($_REQUEST['ctf'][$this->Name()]['start']) . ", {$this->pageSize}"; } else { $limitClause = "0, {$this->pageSize}"; } // 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->unpagedSourceItems = $this->group->Members( "", "", $this->sourceFilter, $this->sourceSort ); $this->totalCount = ($this->sourceItems) ? $this->sourceItems->TotalItems() : 0; return $this->sourceItems; } function TotalCount() { $this->sourceItems(); // Called for its side-effect of setting total count return $this->totalCount; } } class MemberTableField_Popup extends ComplexTableField_Popup { function __construct($controller, $name, $fields, $sourceClass, $readonly=false, $validator = null) { // DO NOT CHANGE THE ORDER OF THESE JS FILES. THESE ARE ONLY REQUIRED FOR THIS INSTANCE !!!11onetwo parent::__construct($controller, $name, $fields, $sourceClass, $readonly, $validator); Requirements::javascript("cms/javascript/MemberTableField.js"); Requirements::javascript("cms/javascript/MemberTableField_popup.js"); } function saveComplexTableField() { $id = Convert::raw2sql($_REQUEST['ctf']['childID']); if (is_numeric($id)) { $childObject = DataObject::get_by_id($this->sourceClass, $id); } else { $childObject = new $this->sourceClass(); } $this->saveInto($childObject); $childObject->write(); $childObject->Groups()->add($_REQUEST['ctf']['ID']); // if ajax-call in an iframe, close window by javascript, else redirect to referrer if(!Director::is_ajax()) { Director::redirect(substr($_SERVER['REQUEST_URI'],0,strpos($_SERVER['REQUEST_URI'],"?"))); } } } ?>