Enabled Feature: Mass Delete

This commit is contained in:
Deon George 2009-07-06 15:19:42 +10:00
parent 08199e67e0
commit d501393d49
4 changed files with 213 additions and 108 deletions

View File

@ -2,109 +2,142 @@
// $Header$ // $Header$
/** /**
* Enables user to mass delete multiple entries using checkboxes. * Displays a last chance confirmation form to delete a DN.
*
* Variables that come in as GET vars:
* - mass_delete - an array of DNs to delete in this form:
* Array (
* [o=myorg,dc=example,dc=com] => on
* [cn=bob,dc=example,dc=com] => on
* )
* etc.
* *
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Page
*/ */
/** /**
*/ */
require './common.php'; require './common.php';
if ($ldapserver->isReadOnly()) # The DN we are working with
error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); $request = array();
$request['dn'] = get_request('dn','REQUEST');
if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete','mass_delete')) if (! is_array($request['dn']))
error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete mass entries')),'error','index.php'); $request['dn'] = array($request['dn']);
$confirmed = isset($_POST['confirmed']) ? true : false; $request['children'] = array();
isset($_POST['mass_delete']) or $request['parent'] = array();
error(_('Error calling mass_delete.php. Missing mass_delete in POST vars.'),'error','index.php'); foreach ($request['dn'] as $dn) {
# Check if the entry exists.
if (! $dn || ! $app['server']->dnExists($dn))
system_message(array(
'title'=>_('Entry does not exist'),
'body'=>sprintf('%s (%s/%s)',_('The entry does not exist and will be ignored'),$dn),
'type'=>'error'));
$mass_delete = $_POST['mass_delete']; # We search all children, not only the visible children in the tree
if (! in_array_ignore_case($dn,$request['children'])) {
is_array($mass_delete) or $request['children'] = array_merge($request['children'],$app['server']->getContainerContents($dn,null,0,'(objectClass=*)',LDAP_DEREF_NEVER));
error(_('mass_delete POST var is not an array.'),'error','index.php'); array_push($request['parent'],$dn);
$ldapserver->isMassDeleteEnabled() or
error(_('Mass deletion is not enabled. Please enable it in config.php before proceeding.'),'error','index.php');
printf('<h3 class="title">%s</h3>',_('Mass Deleting'));
if ($confirmed == true) {
printf('<h3 class="subtitle">'._('Deletion progress on server "%s"').'</h3>',$ldapserver->name);
echo '<blockquote>';
echo '<small>';
$successfully_delete_dns = array();
$failed_dns = array();
if (! is_array($mass_delete))
error(_('Malformed mass_delete array.'),'error','index.php');
if (count($mass_delete) == 0) {
echo '<br />';
printf('<center>%s</center>',_('You did not select any entries to delete.'));
return;
} }
// @todo: Should sort these entries, so that they are deleted in order, if a user selects children.
foreach ($mass_delete as $dn => $junk) {
printf(_('Deleting %s'),htmlspecialchars($dn));
if(run_hook('pre_entry_delete',array('server_id'=>$ldapserver->server_id,'dn'=>$dn))) {
$success = $ldapserver->delete($dn);
if ($success) {
run_hook('post_entry_delete',array('server_id'=>$ldapserver->server_id,'dn'=>$dn));
printf(' <span style="color:green">%s</span>.<br />',_('Success'));
$successfully_delete_dns[] = $dn;
} else {
printf(' <span style="color:red">%s</span>.<br /> (%s)<br />',_('Failed'),$ldapserver->error());
$failed_dns[] = $dn;
}
}
}
echo '<blockquote>';
echo '</small>';
$failed_count = count($failed_dns);
$total_count = count($mass_delete);
if ($failed_count > 0)
printf('<span style="color: red; font-weight: bold;">'._('%s of %s entries failed to be deleted.').'</span>',$failed_count,$total_count);
else
printf('<span style="color: green; font-weight: bold;">%s</span>',_('All entries deleted successfully.'));
} else {
$n = count($mass_delete);
printf('<h3 class="subtitle">'._('Confirm mass delete of %s entries on server %s').'</h3>',$n,$ldapserver->name);
echo'<center>';
printf(_('Do you really want to delete %s %s %s'),
($n == 1? _('this') : _('these')),$n,($n == 1 ? _('entry') : _('entries')));
echo '<form action="cmd.php?cmd=mass_delete" method="post">';
echo '<input type="hidden" name="confirmed" value="true" />';
printf('<input type="hidden" name="server_id" value="%s" />',$ldapserver->server_id);
echo '<table><tr><td><ol>';
foreach ($mass_delete as $dn => $junk)
printf('<input type="hidden" name="mass_delete[%s]" value="on" /><li>%s</li>',htmlspecialchars($dn),htmlspecialchars($dn));
echo '</ol></td></tr></table>';
printf('<input type="submit" value="%s" /></center>',_('Yes, delete!'));
echo '</form>';
} }
printf('<h3 class="title">%s</h3>',_('Mass Delete'));
printf('<h3 class="subtitle">%s: <b>%s</b></h3>',_('Server'),$app['server']->getName());
echo "\n";
echo '<center>';
echo '<table class="forminput" border=0>';
if (count($request['parent']) == 1)
printf('<tr><td colspan=4><b>%s</b></td></tr>',_('Are you sure you want to permanently delete this object?'));
else
printf('<tr><td colspan=4><b>%s</b></td></tr>',_('Are you sure you want to permanently delete these objects?'));
echo '<tr><td colspan=4>&nbsp;</td></tr>';
printf('<tr><td width=10%%>%s:</td><td colspan=3 width=75%%><b>%s</b></td></tr>',_('Server'),$app['server']->getName());
foreach ($request['parent'] as $dn)
printf('<tr><td width=10%%><acronym title="%s">%s</acronym></td><td colspan=3 width=75%%><b>%s</b></td></tr>',
_('Distinguished Name'),_('DN'),$dn);
echo '<tr><td colspan=4>&nbsp;</td></tr>';
$request['delete'] = $request['parent'];
if (count($request['children'])) {
printf('<tr><td colspan=4><b>%s</b></td></tr>',_('Permanently delete all children also?'));
echo '<tr><td colspan=4>&nbsp;</td></tr>';
# We need to see if the children have children
$query = array();
$query['scope'] = 'sub';
$query['attrs'] = array('dn');
$query['size_limit'] = 0;
$query['deref'] = LDAP_DEREF_NEVER;
$request['search'] = array();
foreach ($request['children'] as $dn) {
$query['base'] = $dn;
$request['search'] = array_merge($request['search'],$app['server']->query($query,null));
}
foreach ($request['search'] as $value)
array_push($request['delete'],$value['dn']);
echo '<tr>';
echo '<td colspan=4>';
printf(_('This request also includes %s children entries.'),count($request['children']));
echo '</td></tr>';
printf('<tr><td colspan=4>%s</td></tr>',
sprintf(_('phpLDAPadmin can also recursively delete all %s of the child entries. See below for a list of all the entries that this action will delete. Do you want to do this?'),count($request['children'])));
echo '<tr><td colspan=4>&nbsp;</td></tr>';
printf('<tr><td colspan=4><small>%s</small></td></tr>',
_('Note: this is potentially very dangerous and you do this at your own risk. This operation cannot be undone. Take into consideration aliases, referrals, and other things that may cause problems.'));
echo "\n";
echo '<tr><td colspan=4>&nbsp;</td></tr>';
echo "\n";
printf('<tr><td colspan=4><center><b>%s</b></center></td></tr>',_('List of entries to be deleted:'));
echo '<tr><td colspan=4>&nbsp;</td></tr>';
$i = 0;
echo '<tr><td colspan=4><center>';
printf('<select size="%s" multiple disabled style="background:white; color:black;width:500px" >',min(10,count($request['delete'])));
foreach ($request['delete'] as $key => $value)
printf('<option>%s. %s</option>',++$i,htmlspecialchars(dn_unescape($value)));
echo '</select>';
echo '</center></td></tr>';
echo "\n";
echo '<tr><td colspan=4>&nbsp;</td></tr>';
}
echo '<tr>';
echo '<td width=50% colspan=2><center>';
echo '<form action="cmd.php" method="post">';
echo '<input type="hidden" name="cmd" value="rdelete" />';
printf('<input type="hidden" name="server_id" value="%s" />',$app['server']->getIndex());
foreach ($request['parent'] as $dn)
printf('<input type="hidden" name="dn[]" value="%s" />',htmlspecialchars($dn));
printf('<input type="submit" value="%s" />',sprintf(_('Delete all %s objects'),count($request['delete'])));
echo '</form>';
echo '</center></td>';
echo '<td colspan=2 width=50%><center>';
echo '<form action="cmd.php" method="get">';
echo '<input type="hidden" name="cmd" value="template_engine" />';
printf('<input type="hidden" name="server_id" value="%s" />',$app['server']->getIndex());
printf('<input type="submit" name="submit" value="%s" />',_('Cancel'));
echo '</form>';
echo '</center></td>';
echo '</tr>';
echo "\n";
echo '</table>';
echo '</center>';
echo '<br />';
?> ?>

View File

@ -19,28 +19,40 @@ if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete','simple_delete'))
$request = array(); $request = array();
$request['dn'] = get_request('dn','REQUEST',true); $request['dn'] = get_request('dn','REQUEST',true);
if (! $app['server']->dnExists($request['dn'])) if (! is_array($request['dn']))
error(sprintf('%s (%s)',_('No such entry.'),$request['dn']),'error','index.php'); $request['dn'] = array($request['dn']);
printf('<h3 class="title">%s %s</h3>',_('Deleting'),get_rdn($request['dn'])); $request['parent'] = array();
foreach ($request['dn'] as $dn)
if (! $app['server']->dnExists($dn))
system_message(array(
'title'=>_('Entry does not exist'),
'body'=>sprintf('%s (%s)',_('Unable to delete entry, it does not exist'),$dn),
'type'=>'error'));
else
array_push($request['parent'],$dn);
printf('<h3 class="title">%s</h3>',_('Delete LDAP entries'));
printf('<h3 class="subtitle">%s</h3>',_('Recursive delete progress')); printf('<h3 class="subtitle">%s</h3>',_('Recursive delete progress'));
# Prevent script from bailing early on a long delete # Prevent script from bailing early on a long delete
@set_time_limit(0); @set_time_limit(0);
echo '<br /><br />'; foreach ($request['parent'] as $dn) {
echo '<small>'; echo '<br /><br />';
$result = pla_rdelete($app['server'],$request['dn']); echo '<small>';
echo '</small><br />'; $result = pla_rdelete($app['server'],$dn);
echo '</small><br />';
if ($result) { if ($result) {
printf(_('Entry %s and sub-tree deleted successfully.'),'<b>'.$request['dn'].'</b>'); printf(_('Entry %s and sub-tree deleted successfully.'),'<b>'.$dn.'</b>');
} else { } else {
system_message(array( system_message(array(
'title'=>_('Could not delete the entry.').sprintf(' (%s)',pretty_print_dn($request['dn'])), 'title'=>_('Could not delete the entry.').sprintf(' (%s)',pretty_print_dn($request['dn'])),
'body'=>ldap_error_msg($app['server']->getErrorMessage(null),$app['server']->getErrorNum(null)), 'body'=>ldap_error_msg($app['server']->getErrorMessage(null),$app['server']->getErrorNum(null)),
'type'=>'error')); 'type'=>'error'));
}
} }
function pla_rdelete($server,$dn) { function pla_rdelete($server,$dn) {

View File

@ -99,7 +99,6 @@ class QueryRender extends PageRender {
echo '</tr>'; echo '</tr>';
} }
echo '<tr>';
printf('<td><acronym title="%s">%s</acronym></td>',_('The format to show the query results'),_('Display Format')); printf('<td><acronym title="%s">%s</acronym></td>',_('The format to show the query results'),_('Display Format'));
echo '<td>'; echo '<td>';
echo '<select name="format" style="width: 200px">'; echo '<select name="format" style="width: 200px">';
@ -205,6 +204,14 @@ class QueryRender extends PageRender {
$server = $this->getServer(); $server = $this->getServer();
$afattrs = $this->getAFAttrs(); $afattrs = $this->getAFAttrs();
# If Mass Actions Enabled
if ($_SESSION[APPCONFIG]->getValue('mass','enabled')) {
$mass_actions = array(
'&nbsp;' => '',
_('delete') => 'mass_delete'
);
}
# Display the Javascript that enables us to show/hide DV entries # Display the Javascript that enables us to show/hide DV entries
echo '<script type="text/javascript" language="javascript">'; echo '<script type="text/javascript" language="javascript">';
echo " echo "
@ -354,11 +361,15 @@ function hideall(key,except) {
continue; continue;
} }
echo '<form action="cmd.php" method="post" name="massform">';
printf('<input type="hidden" name="server_id" value="%s" />',$server->getIndex());
echo '<table class="result_table" border=0>'; echo '<table class="result_table" border=0>';
echo '<thead class="fixheader">'; echo '<thead class="fixheader">';
echo '<tr class="heading">'; echo '<tr class="heading">';
echo '<td>&nbsp;</td>'; echo '<td>&nbsp;</td>';
echo '<td>&nbsp;</td>';
foreach (explode(',',$this->template->getAttrDisplayOrder()) as $attr) { foreach (explode(',',$this->template->getAttrDisplayOrder()) as $attr) {
echo '<td>'; echo '<td>';
@ -372,12 +383,18 @@ function hideall(key,except) {
echo '<tbody class="scroll">'; echo '<tbody class="scroll">';
$counter = 0; $counter = 0;
foreach ($results as $dn => $dndetails) { foreach ($results as $dn => $dndetails) {
$counter++;
$dndetails = array_change_key_case($dndetails); $dndetails = array_change_key_case($dndetails);
# Temporarily set our DN, for rendering that leverages our DN (eg: JpegPhoto) # Temporarily set our DN, for rendering that leverages our DN (eg: JpegPhoto)
$this->template->setDN($dn); $this->template->setDN($dn);
printf('<tr class="%s">',++$counter%2 ? 'odd' : 'even'); printf('<tr class="%s" id="tr_ma%s" onClick="var cb=document.getElementById(\'ma%s\'); cb.checked=!cb.checked;">',
$counter%2 ? 'odd' : 'even',$counter,$counter);
# Is mass action enabled.
if ($_SESSION[APPCONFIG]->getValue('mass','enabled'))
printf('<td><input type="checkbox" id="ma%s" name="dn[]" value="%s"/ onclick="this.checked=!this.checked;"></td>',$counter,$dn);
$href = sprintf('cmd=template_engine&server_id=%s&dn=%s',$server->getIndex(),rawurlencode($dn)); $href = sprintf('cmd=template_engine&server_id=%s&dn=%s',$server->getIndex(),rawurlencode($dn));
printf('<td class="icon"><a href="cmd.php?%s"><img src="%s/%s" alt="icon" /></a></td>', printf('<td class="icon"><a href="cmd.php?%s"><img src="%s/%s" alt="icon" /></a></td>',
@ -417,12 +434,49 @@ function hideall(key,except) {
echo '</tr>'; echo '</tr>';
} }
# Is mass action enabled.
if ($_SESSION[APPCONFIG]->getValue('mass','enabled')) {
printf('<tr class="%s">',++$counter%2 ? 'odd' : 'even',$counter);
echo '<td><input type="checkbox" name="allbox" value="1" onclick="CheckAll(1);" /></td>';
printf('<td colspan=%s>',2+count(explode(',',$this->template->getAttrDisplayOrder())));
echo '<select name="cmd" onChange="if (this.value) submit();" style="font-size: 12px">';
foreach ($mass_actions as $action => $display)
printf('<option value="%s">%s</option>',$display,$action);
echo '</select>';
echo '</td>';
echo '</tr>';
}
echo '</tbody>'; echo '</tbody>';
echo '</table>'; echo '</table>';
echo '</form>';
echo '</td></tr>'; echo '</td></tr>';
echo '</table>'; echo '</table>';
echo '</div>'; echo '</div>';
echo "\n\n"; echo "\n\n";
echo '<script type="text/javascript" language="javascript">'."\n";
echo "
function CheckAll(setbgcolor) {
var deon=0;
for (var i=0;i<document.massform.elements.length;i++) {
var e = document.massform.elements[i];
if (e.type == 'checkbox' && e.name != 'allbox') {
e.checked = document.massform.allbox.checked;
if (!document.layers && setbgcolor) {
var tr = document.getElementById('tr_'+e.id);
if (e.checked) {
tr.style.backgroundColor='#DDDDFF';
} else {
var id = e.id.substr(2);
tr.style.backgroundColor= id%2 ? '#F0F0F0' : '#E0E0E0';
}
}
}
}
}
";
echo '</script>';
} }
break; break;

View File

@ -307,6 +307,7 @@ class Config {
'login' => true, 'login' => true,
'logout' => true, 'logout' => true,
'login_form' => true, 'login_form' => true,
'mass_delete' => true,
'modify_member_form' => true, 'modify_member_form' => true,
'monitor' => true, 'monitor' => true,
'purge_cache' => true, 'purge_cache' => true,
@ -419,6 +420,11 @@ class Config {
'desc'=>'Temporary directory for jpegPhoto data', 'desc'=>'Temporary directory for jpegPhoto data',
'default'=>'/tmp'); 'default'=>'/tmp');
## Mass update commands
$this->default->mass['enabled'] = array(
'desc'=>'Are mass update commands enabled',
'default'=>true);
## Modify members feature ## Modify members feature
/** /**
* Search filter setting for new members. This is used to search possible members that can be added * Search filter setting for new members. This is used to search possible members that can be added