2007-07-19 12:40:05 +02:00
|
|
|
<?php
|
|
|
|
|
2008-01-08 07:41:55 +01:00
|
|
|
/**
|
|
|
|
* @package cms
|
2008-01-10 01:33:49 +01:00
|
|
|
* @subpackage security
|
2008-01-08 07:41:55 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Security section of the CMS
|
2008-01-10 01:33:49 +01:00
|
|
|
* @package cms
|
|
|
|
* @subpackage security
|
2008-01-08 07:41:55 +01:00
|
|
|
*/
|
2007-08-31 02:31:49 +02:00
|
|
|
class SecurityAdmin extends LeftAndMain implements PermissionProvider {
|
2007-07-19 12:40:05 +02:00
|
|
|
static $tree_class = "Group";
|
|
|
|
static $subitem_class = "Member";
|
|
|
|
|
|
|
|
public function init() {
|
|
|
|
// Check permissions
|
|
|
|
// if(!Member::currentUser() || !Member::currentUser()->isAdmin()) Security::permissionFailure($this);
|
|
|
|
|
|
|
|
parent::init();
|
|
|
|
|
|
|
|
Requirements::javascript("jsparty/hover.js");
|
|
|
|
Requirements::javascript("jsparty/scriptaculous/controls.js");
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// needed for MemberTableField (Requirements not determined before Ajax-Call)
|
|
|
|
Requirements::javascript("sapphire/javascript/TableListField.js");
|
|
|
|
Requirements::javascript("sapphire/javascript/TableField.js");
|
|
|
|
Requirements::javascript("sapphire/javascript/ComplexTableField.js");
|
|
|
|
Requirements::javascript("cms/javascript/MemberTableField.js");
|
|
|
|
Requirements::css("jsparty/greybox/greybox.css");
|
|
|
|
Requirements::css("sapphire/css/ComplexTableField.css");
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
Requirements::javascript("cms/javascript/SecurityAdmin.js");
|
|
|
|
Requirements::javascript("cms/javascript/SecurityAdmin_left.js");
|
|
|
|
Requirements::javascript("cms/javascript/SecurityAdmin_right.js");
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
Requirements::javascript("jsparty/greybox/AmiJS.js");
|
|
|
|
Requirements::javascript("jsparty/greybox/greybox.js");
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getEditForm($id) {
|
|
|
|
$record = DataObject::get_by_id("Group", $id);
|
|
|
|
if($record) {
|
|
|
|
$fields = new FieldSet(
|
|
|
|
new TabSet("Root",
|
2008-01-10 04:28:13 +01:00
|
|
|
new Tab(_t('SecurityAdmin.MEMBERS', 'Members'),
|
|
|
|
new TextField("Title", _t('SecurityAdmin.GROUPNAME', 'Group name')),
|
2007-07-19 12:40:05 +02:00
|
|
|
$memberList = new MemberTableField(
|
|
|
|
$this,
|
2007-09-14 21:40:56 +02:00
|
|
|
"Members",
|
2008-02-19 01:17:48 +01:00
|
|
|
$record,
|
|
|
|
null,
|
|
|
|
false
|
2007-07-19 12:40:05 +02:00
|
|
|
)
|
|
|
|
),
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2008-01-10 04:28:13 +01:00
|
|
|
new Tab(_t('SecurityAdmin.PERMISSIONS', 'Permissions'),
|
2007-09-16 18:33:05 +02:00
|
|
|
new LiteralField("", "<p>"._t('SecurityAdmin.ADVANCEDONLY',"This section is for advanced users only.
|
2007-09-14 21:40:56 +02:00
|
|
|
See <a href=\"http://doc.silverstripe.com/doku.php?id=permissions:codes\" target=\"_blank\">this page</a>
|
2007-09-16 18:33:05 +02:00
|
|
|
for more information.")."</p>"),
|
2007-07-19 12:40:05 +02:00
|
|
|
new TableField(
|
|
|
|
"Permissions",
|
|
|
|
"Permission",
|
2007-11-23 02:10:19 +01:00
|
|
|
array(
|
2008-01-10 04:28:13 +01:00
|
|
|
"Code" => _t('SecurityAdmin.CODE', 'Code'),
|
|
|
|
"Arg" => _t('SecurityAdmin.OPTIONALID', 'Optional ID'),
|
2007-11-23 02:10:19 +01:00
|
|
|
),
|
|
|
|
array(
|
|
|
|
"Code" => "PermissionDropdownField",
|
|
|
|
"Arg" => "TextField",
|
|
|
|
),
|
2007-07-19 12:40:05 +02:00
|
|
|
"GroupID", $id
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-08-31 02:31:49 +02:00
|
|
|
if(!Permission::check('EDIT_PERMISSIONS')) $fields->removeFieldFromTab('Root', 'Permissions');
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$memberList->setController($this);
|
2007-11-15 23:43:09 +01:00
|
|
|
$memberList->setPermissions(array('show', 'edit', 'delete', 'export', 'add'));
|
2008-01-03 09:44:29 +01:00
|
|
|
$memberList->setParentClass('Group');
|
2008-01-10 23:27:38 +01:00
|
|
|
$memberList->setPopupCaption(_t('SecurityAdmin.VIEWUSER', 'View User'));
|
2008-01-03 09:44:29 +01:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$fields->push($idField = new HiddenField("ID"));
|
|
|
|
$idField->setValue($id);
|
|
|
|
$actions = new FieldSet(
|
2007-09-16 18:33:05 +02:00
|
|
|
new FormAction('addmember',_t('SecurityAdmin.ADDMEMBER','Add Member'))
|
2007-07-19 12:40:05 +02:00
|
|
|
);
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-09-16 18:33:05 +02:00
|
|
|
$actions->push(new FormAction('save',_t('SecurityAdmin.SAVE','Save')));
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$form = new Form($this, "EditForm", $fields, $actions);
|
|
|
|
$form->loadDataFrom($record);
|
|
|
|
return $form;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function AddRecordForm() {
|
|
|
|
$m = new MemberTableField(
|
|
|
|
$this,
|
2007-09-14 21:40:56 +02:00
|
|
|
"Members",
|
2007-07-19 12:40:05 +02:00
|
|
|
$this->currentPageID()
|
|
|
|
);
|
|
|
|
return $m->AddRecordForm();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Ajax autocompletion
|
|
|
|
*/
|
|
|
|
public function autocomplete() {
|
|
|
|
$fieldName = $this->urlParams['ID'];
|
|
|
|
$fieldVal = $_REQUEST[$fieldName];
|
2008-01-14 01:51:35 +01:00
|
|
|
$result = '';
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$matches = DataObject::get("Member","$fieldName LIKE '" . addslashes($fieldVal) . "%'");
|
|
|
|
if($matches) {
|
|
|
|
$result .= "<ul>";
|
|
|
|
foreach($matches as $match) {
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$data = $match->FirstName;
|
|
|
|
$data .= ",$match->Surname";
|
|
|
|
$data .= ",$match->Email";
|
|
|
|
$data .= ",$match->Password";
|
|
|
|
$result .= "<li>" . $match->$fieldName . "<span class=\"informal\">($match->FirstName $match->Surname, $match->Email)</span><span class=\"informal data\">$data</span></li>";
|
|
|
|
}
|
|
|
|
$result .= "</ul>";
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getmember() {
|
|
|
|
Session::set('currentMember', $_REQUEST['ID']);
|
|
|
|
SSViewer::setOption('rewriteHashlinks', false);
|
2007-12-18 22:38:01 +01:00
|
|
|
$result = $this->renderWith("LeftAndMain_rightbottom");
|
2007-07-19 12:40:05 +02:00
|
|
|
$parts = split('</?form[^>]*>', $result);
|
|
|
|
echo $parts[1];
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function MemberForm() {
|
|
|
|
$id = $_REQUEST['ID'] ? $_REQUEST['ID'] : Session::get('currentMember');
|
|
|
|
if($id)
|
|
|
|
return $this->getMemberForm($id);
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function getMemberForm($id) {
|
|
|
|
if($id && $id != 'new') $record = DataObject::get_one("Member", "`Member`.ID = $id");
|
|
|
|
if($record || $id == 'new') {
|
|
|
|
$fields = new FieldSet(
|
|
|
|
new HiddenField('MemberListBaseGroup', '', $this->currentPageID() )
|
|
|
|
);
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( $extraFields = $record->getCMSFields() )
|
|
|
|
foreach( $extraFields as $extra )
|
|
|
|
$fields->push( $extra );
|
|
|
|
|
|
|
|
$fields->push($idField = new HiddenField("ID"));
|
|
|
|
$fields->push($groupIDField = new HiddenField("GroupID"));
|
|
|
|
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$actions = new FieldSet();
|
2007-09-16 18:33:05 +02:00
|
|
|
$actions->push(new FormAction('savemember',_t('SecurityAdmin.SAVE')));
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$form = new Form($this, "MemberForm", $fields, $actions);
|
|
|
|
if($record) $form->loadDataFrom($record);
|
|
|
|
|
|
|
|
$idField->setValue($id);
|
|
|
|
$groupIDField->setValue($this->currentPageID());
|
|
|
|
|
|
|
|
return $form;
|
|
|
|
}
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
function savemember() {
|
|
|
|
$data = $_REQUEST;
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$className = $this->stat('subitem_class');
|
|
|
|
|
|
|
|
$id = $_REQUEST['ID'];
|
|
|
|
if($id == 'new') $id = null;
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if($id) {
|
|
|
|
$record = DataObject::get_one($className, "`$className`.ID = $id");
|
|
|
|
} else {
|
|
|
|
$record = new $className();
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$record->update($data);
|
|
|
|
$record->ID = $id;
|
|
|
|
$record->write();
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$record->Groups()->add($data['GroupID']);
|
|
|
|
|
|
|
|
|
|
|
|
FormResponse::add("reloadMemberTableField();");
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
return FormResponse::respond();
|
|
|
|
}
|
|
|
|
|
|
|
|
function addmember($className=null) {
|
|
|
|
$data = $_REQUEST;
|
|
|
|
unset($data['ID']);
|
2007-09-14 21:40:56 +02:00
|
|
|
if($className == null)
|
2007-07-19 12:40:05 +02:00
|
|
|
$className = $this->stat('subitem_class');
|
|
|
|
$record = new $className();
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$record->update($data);
|
|
|
|
$record->write();
|
|
|
|
if($data['GroupID'])
|
2007-09-14 21:40:56 +02:00
|
|
|
$record->Groups()->add($data['GroupID']);
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
FormResponse::add("reloadMemberTableField();");
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
return FormResponse::respond();
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function removememberfromgroup() {
|
|
|
|
$groupID = $this->urlParams['ID'];
|
|
|
|
$memberID = $this->urlParams['OtherID'];
|
|
|
|
if(is_numeric($groupID) && is_numeric($memberID)) {
|
|
|
|
$member = DataObject::get_by_id('Member', $memberID);
|
|
|
|
$member->Groups()->remove($groupID);
|
|
|
|
FormResponse::add("reloadMemberTableField();");
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
} else {
|
|
|
|
user_error("SecurityAdmin::removememberfromgroup: Bad parameters: Group=$groupID, Member=$memberID", E_USER_ERROR);
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
return FormResponse::respond();
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
/**
|
|
|
|
* Return the entire site tree as a nested set of ULs
|
|
|
|
*/
|
|
|
|
public function SiteTreeAsUL() {
|
|
|
|
$className = "Group";
|
|
|
|
|
|
|
|
$obj = singleton($className);
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// getChildrenAsUL is a flexible and complex way of traversing the tree
|
2007-09-14 21:40:56 +02:00
|
|
|
$siteTree = $obj->getChildrenAsUL("",
|
2007-07-19 12:40:05 +02:00
|
|
|
' "<li id=\"record-$child->ID\" class=\"$child->class " . ($child->Locked ? " nodelete" : "") . ' .
|
2007-09-14 21:40:56 +02:00
|
|
|
' ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' .
|
2007-08-31 02:31:49 +02:00
|
|
|
' "<a href=\"" . Director::link("admin", "show", $child->ID) . "\" >" . $child->TreeTitle() . "</a>" ',$this);
|
2007-07-19 12:40:05 +02:00
|
|
|
|
|
|
|
$siteTree = "<ul id=\"sitetree\" class=\"tree unformatted\">" .
|
|
|
|
"<li id=\"record-0\" class=\"Root\">" .
|
2007-11-02 02:12:31 +01:00
|
|
|
"<a href=\"admin/security/show/0\" ><strong>"._t('SecurityAdmin.SGROUPS',"Security groups")."</strong></a>"
|
2007-09-14 21:40:56 +02:00
|
|
|
. $siteTree .
|
2007-07-19 12:40:05 +02:00
|
|
|
"</li>" .
|
|
|
|
"</ul>";
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
return $siteTree;
|
|
|
|
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function addgroup() {
|
|
|
|
$parent = $_REQUEST['ParentID'] ? $_REQUEST['ParentID'] : 0;
|
|
|
|
$p = new Group();
|
2007-09-16 18:33:05 +02:00
|
|
|
$p->Title = _t('SecurityAdmin.NEWGROUP',"New Group");
|
2007-07-19 12:40:05 +02:00
|
|
|
$p->Code = "new-group";
|
|
|
|
$p->ParentID = $parent;
|
|
|
|
$p->write();
|
|
|
|
return $this->returnItemToUser($p);
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function newmember() {
|
|
|
|
Session::clear('currentMember');
|
|
|
|
$newMemberForm = array(
|
|
|
|
"MemberForm" => $this->getMemberForm('new'),
|
|
|
|
);
|
|
|
|
// This should be using FormResponse ;-)
|
|
|
|
if(Director::is_ajax()) {
|
|
|
|
SSViewer::setOption('rewriteHashlinks', false);
|
2007-09-14 21:40:56 +02:00
|
|
|
$customised = $this->customise($newMemberForm);
|
2007-07-19 12:40:05 +02:00
|
|
|
$result = $customised->renderWith($this->class . "_rightbottom");
|
|
|
|
$parts = split('</?form[^>]*>', $result);
|
|
|
|
return $parts[1];
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
} else {
|
|
|
|
return $newMemberForm;
|
|
|
|
}
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function EditedMember() {
|
|
|
|
if(Session::get('currentMember'))
|
|
|
|
return DataObject::get_by_id("Member", Session::get('currentMember'));
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function Link($action = null) {
|
|
|
|
if(!$action) $action = "index";
|
|
|
|
return "admin/security/$action/" . $this->currentPageID();
|
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
public function listmembers( $baseGroup = null ) {
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( !$baseGroup )
|
|
|
|
$baseGroup = $this->urlParams['ID'];
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// Debug::message( $_REQUEST['MemberListOrderByField'] );
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// construct the filter and sort
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( $_REQUEST['MemberListOrderByField'] )
|
|
|
|
$sort = "`" . $_REQUEST['MemberListOrderByField'] . "`" . addslashes( $_REQUEST['MemberListOrderByOrder'] );
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$whereClauses = array();
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$search = addslashes( $_REQUEST['MemberListSearch'] );
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( $_REQUEST['MemberListPage'] ) {
|
|
|
|
$pageSize = 10;
|
2007-09-14 21:40:56 +02:00
|
|
|
|
|
|
|
$limitClause = ( $_REQUEST['MemberListPage'] ) . ", $pageSize";
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( !empty($_REQUEST['MemberListSearch']) )
|
|
|
|
$whereClauses[] = "( `Email`='$search' OR `FirstName`='$search' OR `Surname`='$search' )";
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( is_numeric( $_REQUEST['MemberListBaseGroup'] ) ) {
|
|
|
|
$whereClauses[] = "`GroupID`='".$_REQUEST['MemberListBaseGroup']."'";
|
|
|
|
$join = "INNER JOIN `Group_Members` ON `MemberID`=`Member`.`ID`";
|
2007-09-14 21:40:56 +02:00
|
|
|
}
|
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// $_REQUEST['showqueries'] = 1;
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$members = DataObject::get('Member', implode( ' AND ', $whereClauses ), $sort, $join, $limitClause );
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( is_numeric( $_REQUEST['MemberListGroup'] ) ) {
|
|
|
|
$baseMembers = new DataObjectSet();
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
if( $members )
|
|
|
|
foreach( $members as $member )
|
|
|
|
if( $member->inGroup( $_REQUEST['MemberListGroup'] ) )
|
|
|
|
$baseMembers->push( $member );
|
2007-09-14 21:40:56 +02:00
|
|
|
} else
|
2007-07-19 12:40:05 +02:00
|
|
|
$baseMembers = $members;
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$baseMembers = null;
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
// user_error( $_REQUEST['MemberListBaseGroup'], E_USER_ERROR );
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
$memberListField = new MemberTableField(
|
|
|
|
$this,
|
2007-09-14 21:40:56 +02:00
|
|
|
'MemberList',
|
|
|
|
$_REQUEST['MemberListBaseGroup'],
|
|
|
|
$baseMembers,
|
2007-07-19 12:40:05 +02:00
|
|
|
$_REQUEST['MemberListDontShowPassword']
|
|
|
|
);
|
2007-09-14 21:40:56 +02:00
|
|
|
|
2007-07-19 12:40:05 +02:00
|
|
|
return $memberListField->renderWith('MemberList_Table');
|
|
|
|
}
|
2007-08-31 02:31:49 +02:00
|
|
|
|
|
|
|
function providePermissions() {
|
|
|
|
return array(
|
2008-01-10 04:28:13 +01:00
|
|
|
'EDIT_PERMISSIONS' => _t('SecurityAdmin.EDITPERMISSIONS', 'Edit Permissions on each Group'),
|
2007-08-31 02:31:49 +02:00
|
|
|
);
|
|
|
|
}
|
2007-07-19 12:40:05 +02:00
|
|
|
}
|
|
|
|
|
2007-11-15 23:42:22 +01:00
|
|
|
?>
|