2007-07-19 12:40:05 +02:00
< ? php
/**
* Enhances { ComplexTableField } with the ability to list groups and given members .
* It is based around groups , so it deletes Members from a Group rather than from the entire system .
2007-09-14 21:39:59 +02:00
*
2007-07-19 12:40:05 +02:00
* In contrast to the original implementation , the URL - parameters " ParentClass " and " ParentID " are used
* to specify " Group " ( hardcoded ) and the GroupID - relation .
*
* Returns either :
* - provided members
* - members of a provided group
* - all members
* - members based on a search - query
2008-02-25 03:10:37 +01:00
* @ package cms
* @ subpackage security
2007-07-19 12:40:05 +02:00
*/
class MemberTableField extends ComplexTableField {
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
protected $members ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
protected $hidePassword ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
protected $pageSize ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
protected $detailFormValidator ;
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
protected $group ;
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
protected $template = " MemberTableField " ;
2007-09-14 21:39:59 +02:00
2008-02-25 03:10:37 +01:00
public $popupClass = 'MemberTableField_Popup' ;
2007-07-19 12:40:05 +02:00
static $data_class = " Member " ;
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
protected $permissions = array (
" add " ,
" edit " ,
" delete "
);
private static $addedPermissions = array ();
private static $addedFields = array ();
private static $addedCsvFields = array ();
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
public static function addPermissions ( $addingPermissionList ) {
self :: $addedPermissions = $addingPermissionList ;
}
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
public static function addMembershipFields ( $addingFieldList , $addingCsvFieldList = null ) {
self :: $addedFields = $addingFieldList ;
$addingCsvFieldList == null ? self :: $addedCsvFields = $addingFieldList : self :: $addedCsvFields = $addingCsvFieldList ;
}
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
function __construct ( $controller , $name , $group , $members = null , $hidePassword = true , $pageLimit = 10 ) {
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
if ( $group ) {
if ( is_object ( $group )) {
$this -> group = $group ;
} else if ( is_numeric ( $group )){
$this -> group = DataObject :: get_by_id ( 'Group' , $group );
2007-09-14 21:39:59 +02:00
}
2007-07-19 12:40:05 +02:00
} else if ( is_numeric ( $_REQUEST [ 'ctf' ][ $this -> Name ()][ " ID " ])) {
$this -> group = DataObject :: get_by_id ( 'Group' , $_REQUEST [ 'ctf' ][ $this -> Name ()][ " ID " ]);
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$sourceClass = $this -> stat ( " data_class " );
foreach ( self :: $addedPermissions as $permission )
array_push ( $this -> permissions , $permission );
$fieldList = array (
2008-02-25 03:10:37 +01:00
" FirstName " => _t ( 'MemberTableField.FIRSTNAME' , 'Firstname' ),
" Surname " => _t ( 'MemberTableField.SURNAME' , 'Surname' ),
" Email " => _t ( 'MemberTableField.EMAIL' , 'Email' )
2007-07-19 12:40:05 +02:00
);
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
$csvFieldList = $fieldList ;
foreach ( self :: $addedCsvFields as $key => $value ) {
$csvFieldList [ $key ] = $value ;
}
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
foreach ( self :: $addedFields as $key => $value ) {
$fieldList [ $key ] = $value ;
}
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
if ( ! $hidePassword ) {
2008-02-25 03:10:37 +01:00
$fieldList [ " SetPassword " ] = " Password " ;
2007-07-19 12:40:05 +02:00
}
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 ();
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
$this -> pageSize = $pageLimit ;
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
// Legacy: Use setCustomSourceItems() instead.
if ( $members ) {
$this -> customSourceItems = $this -> memberListWithGroupID ( $members , $group );
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$this -> hidePassword = $hidePassword ;
2008-02-25 03:10:37 +01:00
parent :: __construct ( $controller , $name , $sourceClass , $fieldList );
2007-09-14 21:39:59 +02:00
2008-02-25 03:10:37 +01:00
Requirements :: javascript ( 'cms/javascript/MemberTableField.js' );
2008-04-26 08:28:20 +02:00
Requirements :: javascript ( " cms/javascript/MemberTableField_popup.js " );
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
// construct the filter and sort
if ( isset ( $_REQUEST [ 'MemberOrderByField' ])) {
2008-02-25 03:10:37 +01:00
$this -> sourceSort = '`' . Convert :: raw2sql ( $_REQUEST [ 'MemberOrderByField' ]) . '`' . Convert :: raw2sql ( $_REQUEST [ 'MemberOrderByOrder' ] );
2007-07-19 12:40:05 +02:00
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
// search
2008-03-10 22:28:15 +01:00
$SQL_search = isset ( $_REQUEST [ 'MemberSearch' ]) ? Convert :: raw2sql ( $_REQUEST [ 'MemberSearch' ]) : null ;
2007-07-19 12:40:05 +02:00
if ( ! empty ( $_REQUEST [ 'MemberSearch' ])) {
2008-03-10 22:28:15 +01:00
$searchFilters = array ();
foreach ( $SNG_member -> stat ( 'searchable_fields' ) as $fieldName => $fieldSpec ) {
$searchFilters [] = " ` $fieldName ` LIKE '% { $SQL_search } %' " ;
}
$this -> sourceFilter [] = '(' . implode ( ' OR ' , $searchFilters ) . ')' ;
2007-07-19 12:40:05 +02:00
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
// 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`)) " ;
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$this -> sourceJoin = " INNER JOIN `Group_Members` ON `MemberID`=`Member`.`ID` " ;
$this -> setFieldListCsv ( $csvFieldList );
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
/**
* Overridden functions
*/
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
function sourceID () {
return $this -> group -> ID ;
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
function AddLink () {
return " { $this -> PopupBaseLink () } &methodName=add " ;
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
function SearchForm () {
$searchFields = new FieldGroup (
2008-02-25 03:10:37 +01:00
new TextField ( 'MemberSearch' , _t ( 'MemberTableField.SEARCH' , 'Search' )),
2007-07-19 12:40:05 +02:00
new HiddenField ( " ctf[ID] " , '' , $this -> group -> ID ),
new HiddenField ( 'MemberFieldName' , '' , $this -> name ),
new HiddenField ( 'MemberDontShowPassword' , '' , $this -> hidePassword )
);
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$orderByFields = new FieldGroup (
2008-02-25 03:10:37 +01:00
new LabelField ( _t ( 'MemberTableField.ORDERBY' , 'Order by' )),
2007-09-14 21:39:59 +02:00
new FieldSet (
2007-07-19 12:40:05 +02:00
new DropdownField ( 'MemberOrderByField' , '' , array (
2008-02-25 03:10:37 +01:00
'FirstName' => _t ( 'MemberTableField.FIRSTNAME' , 'FirstName' ),
'Surname' => _t ( 'MemberTableField.SURNAME' , 'Surname' ),
'Email' => _t ( 'MemberTableField.EMAIL' , 'Email' )
2007-07-19 12:40:05 +02:00
)),
new DropdownField ( 'MemberOrderByOrder' , '' , array (
2008-02-25 03:10:37 +01:00
'ASC' => _t ( 'MemberTableField.ASC' , 'Ascending' ),
'DESC' => _t ( 'MemberTableField.DESC' , 'Descending' )
2007-07-19 12:40:05 +02:00
))
)
);
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$groups = DataObject :: get ( 'Group' );
2008-02-25 03:10:37 +01:00
$groupArray = array ( '' => _t ( 'MemberTableField.ANYGROUP' , 'Any group' ));
2007-07-19 12:40:05 +02:00
foreach ( $groups as $group ) {
$groupArray [ $group -> ID ] = $group -> Title ;
}
2008-02-25 03:10:37 +01:00
$groupFields = new DropdownField ( 'MemberGroup' , _t ( 'MemberTableField.FILTERBYGROUP' , 'Filter by group' ), $groupArray );
2007-09-14 21:39:59 +02:00
2008-02-25 03:10:37 +01:00
$actionFields = new LiteralField ( 'MemberFilterButton' , '<input type="submit" class="action" name="MemberFilterButton" value="' . _t ( 'MemberTableField.FILTER' , 'Filter' ) . '" id="MemberFilterButton"/>' );
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$fieldContainer = new FieldGroup (
$searchFields ,
// $orderByFields,
// $groupFields,
$actionFields
);
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
return $fieldContainer -> FieldHolder ();
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
/**
* Add existing member to group rather than creating a new member
*/
function addtogroup () {
$data = $_REQUEST ;
unset ( $data [ 'ID' ]);
if ( ! is_numeric ( $data [ 'ctf' ][ 'ID' ])) {
2008-02-25 03:10:37 +01:00
FormResponse :: status_messsage ( _t ( 'MemberTableField.ADDINGFIELD' , 'Adding failed' ), 'bad' );
2007-07-19 12:40:05 +02:00
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$className = $this -> stat ( 'data_class' );
$record = new $className ();
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
$record -> update ( $data );
2008-04-26 08:28:33 +02:00
$valid = $record -> validate ();
if ( $valid -> valid ()) {
$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' ] );
2007-09-15 22:10:43 +02:00
2008-04-26 08:28:33 +02:00
$this -> sourceItems ();
2007-07-19 12:40:05 +02:00
2008-04-26 08:28:33 +02:00
// 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 ( _t ( 'MemberTableField.ADDEDTOGROUP' , 'Added member to group' ), 'good' );
} else {
FormResponse :: status_message ( Convert :: raw2xml ( " I couldn't add that user to this group: \n \n " . $valid -> starredlist ()), 'bad' );
}
2007-07-19 12:40:05 +02:00
return FormResponse :: respond ();
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
/**
* Custom delete implementation :
* Remove member from group rather than from the database
*/
function delete () {
2008-02-25 03:10:37 +01:00
$groupID = Convert :: raw2sql ( $_REQUEST [ 'ctf' ][ 'ID' ]);
$memberID = Convert :: raw2sql ( $_REQUEST [ 'ctf' ][ 'childID' ]);
2007-07-19 12:40:05 +02:00
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 );
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
return FormResponse :: respond ();
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
/**
* #################################
* Utility Functions
* #################################
*/
function getParentClass () {
2008-02-25 03:10:37 +01:00
return 'Group' ;
2007-07-19 12:40:05 +02:00
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
function getParentIdName ( $childClass , $parentClass ){
2008-02-25 03:10:37 +01:00
return 'GroupID' ;
2007-07-19 12:40:05 +02:00
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
/**
* #################################
* Custom Functions
* #################################
*/
function memberListWithGroupID ( $members , $group ) {
$newMembers = new DataObjectSet ();
foreach ( $members as $member ) {
2008-02-25 03:10:37 +01:00
$newMembers -> push ( $member -> customise ( array ( 'GroupID' => $group -> ID )));
2007-07-19 12:40:05 +02:00
}
return $newMembers ;
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
function setGroup ( $group ) {
$this -> group = $group ;
}
function setController ( $controller ) {
$this -> controller = $controller ;
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
function GetControllerName () {
return $this -> controller -> class ;
}
2007-09-14 21:39:59 +02:00
2007-07-19 12:40:05 +02:00
/**
* 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 ));
}
2008-02-25 03:10:37 +01:00
$fields -> push ( new HiddenField ( 'ctf[ID]' , null , $this -> group -> ID ));
2007-09-14 21:39:59 +02:00
2008-08-06 08:54:59 +02:00
return new TabularStyle ( new NestedForm ( new Form ( $this , 'AddRecordForm' ,
2007-07-19 12:40:05 +02:00
$fields ,
new FieldSet (
2008-02-25 03:10:37 +01:00
new FormAction ( 'addtogroup' , _t ( 'MemberTableField.ADD' , 'Add' ))
2007-07-19 12:40:05 +02:00
)
2008-08-06 08:54:59 +02:00
)));
2007-07-19 12:40:05 +02:00
}
/**
* Cached version for getting the appropraite members for this particular group .
2007-09-14 21:39:59 +02:00
*
2007-07-19 12:40:05 +02:00
* This includes getting inherited groups , such as groups under groups .
*/
function sourceItems (){
// Caching.
if ( $this -> sourceItems ) {
return $this -> sourceItems ;
}
2007-09-14 21:39:59 +02:00
// Setup limits
2008-02-25 03:10:37 +01:00
$limitClause = '' ;
2007-07-19 12:40:05 +02:00
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
);
2008-02-25 03:10:37 +01:00
$this -> unpagedSourceItems = $this -> group -> Members ( '' , '' , $this -> sourceFilter , $this -> sourceSort );
2007-07-19 12:40:05 +02:00
$this -> totalCount = ( $this -> sourceItems ) ? $this -> sourceItems -> TotalItems () : 0 ;
return $this -> sourceItems ;
}
2007-09-15 22:10:43 +02:00
2007-07-19 12:40:05 +02:00
function TotalCount () {
$this -> sourceItems (); // Called for its side-effect of setting total count
return $this -> totalCount ;
}
}
2008-02-25 03:10:37 +01:00
/**
* Popup window for { @ link MemberTableField } .
* @ package cms
* @ subpackage security
*/
2007-07-19 12:40:05 +02:00
class MemberTableField_Popup extends ComplexTableField_Popup {
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
function __construct ( $controller , $name , $fields , $sourceClass , $readonly = false , $validator = null ) {
parent :: __construct ( $controller , $name , $fields , $sourceClass , $readonly , $validator );
2008-02-25 03:10:37 +01:00
Requirements :: javascript ( 'cms/javascript/MemberTableField.js' );
Requirements :: javascript ( 'cms/javascript/MemberTableField_popup.js' );
2007-07-19 12:40:05 +02:00
}
2008-03-12 10:24:59 +01:00
/**
* Same behaviour as parent class , but adds the member to the passed GroupID .
*
* @ return string
*/
2007-07-19 12:40:05 +02:00
function saveComplexTableField () {
2008-03-12 10:24:59 +01:00
if ( isset ( $_REQUEST [ 'ctf' ][ 'childID' ]) && is_numeric ( $_REQUEST [ 'ctf' ][ 'childID' ])) {
$childObject = DataObject :: get_by_id ( $this -> sourceClass , $_REQUEST [ 'ctf' ][ 'childID' ]);
2007-07-19 12:40:05 +02:00
} else {
$childObject = new $this -> sourceClass ();
2008-02-25 03:10:37 +01:00
$this -> fields -> removeByName ( 'ID' );
2007-07-19 12:40:05 +02:00
}
2008-02-25 03:10:37 +01:00
2007-07-19 12:40:05 +02:00
$this -> saveInto ( $childObject );
2007-09-14 21:39:59 +02:00
2008-04-26 08:28:20 +02:00
$form = $this -> controller -> DetailForm ( $childObject -> ID );
$valid = $childObject -> validate ();
if ( $valid -> valid ()) {
$childObject -> write ();
// custom behaviour for MemberTableField: add member to current group
$childObject -> Groups () -> add ( $_REQUEST [ 'GroupID' ]);
2008-04-26 08:28:33 +02:00
$form -> sessionMessage ( " Changes saved. " , 'good' );
2008-04-26 08:28:20 +02:00
} else {
2008-04-26 08:28:33 +02:00
$form -> sessionMessage ( Convert :: raw2xml ( " I couldn't save your changes: \n \n " . $valid -> starredList ()), 'bad' );
2008-04-26 08:28:20 +02:00
}
2008-03-12 10:24:59 +01:00
// if ajax-call in an iframe, update window
if ( Director :: is_ajax ()) {
// Newly saved objects need their ID reflected in the reloaded form to avoid double saving
$form -> loadDataFrom ( $childObject );
2008-04-26 08:28:20 +02:00
if ( $valid -> valid ()) {
FormResponse :: update_dom_id ( $form -> FormName (), $form -> formHtmlContent (), true , 'update' );
} else {
FormResponse :: load_form ( $form -> forTemplate (), $form -> FormName ());
}
2008-03-12 10:24:59 +01:00
return FormResponse :: respond ();
} else {
Director :: redirectBack ();
2007-07-19 12:40:05 +02:00
}
}
}
2008-02-25 03:10:37 +01:00
?>