diff --git a/include/ajax.users.php b/include/ajax.users.php index 05b4094e4fd0449bb2c144e686ffa9276799d425..5529cf6c623e6f0c460af48f2a20d079b3bc963e 100644 --- a/include/ajax.users.php +++ b/include/ajax.users.php @@ -177,18 +177,22 @@ class UsersAjaxAPI extends AjaxController { elseif (!($user = User::lookup($id))) Http::response(404, 'Unknown user'); - //Switch to end user so we can get ticket stats - // fixme: use orm to get ticket count at the user model level. - $user = new EndUser($user); - $info = array(); - if ($_SERVER['REQUEST_METHOD'] == 'DELETE') { + if ($_POST) { + if ($user->tickets->count()) { + if (!$thisstaff->canDeleteTickets()) { + $info['error'] = 'You do not have permission to delete a user with tickets!'; + } elseif ($_POST['deletetickets']) { + foreach($user->tickets as $ticket) + $ticket->delete(); + } else { + $info['error'] = 'You cannot delete a user with tickets!'; + } + } - if ($user->getNumTickets()) - $info['error'] = 'You cannot delete a user with tickets!'; - elseif ($user->delete()) + if (!$info['error'] && $user->delete()) Http::response(204, 'User deleted successfully'); - else + elseif (!$info['error']) $info['error'] = 'Unable to delete user - try again!'; } diff --git a/include/class.organization.php b/include/class.organization.php index 18b9f537d92735ad613b1fbc57af0f0e73f38284..c12ae9a047e467a0ba916622c46fbc8c25c70312 100644 --- a/include/class.organization.php +++ b/include/class.organization.php @@ -15,6 +15,7 @@ require_once(INCLUDE_DIR . 'class.orm.php'); require_once(INCLUDE_DIR . 'class.forms.php'); require_once(INCLUDE_DIR . 'class.dynamic_forms.php'); +require_once(INCLUDE_DIR . 'class.user.php'); class OrganizationModel extends VerySimpleModel { static $meta = array( @@ -22,33 +23,15 @@ class OrganizationModel extends VerySimpleModel { 'pk' => array('id'), 'joins' => array( 'users' => array( - 'reverse' => 'UserAccountModel.org', + 'reverse' => 'UserAccount.org', ), ) ); - var $users; - - static function objects() { - $qs = parent::objects(); - - return $qs; - } - function getId() { return $this->id; } -} -class Organization extends OrganizationModel { - var $_entries; - var $_forms; - - function __construct($ht) { - parent::__construct($ht); - } - - //XXX: Shouldn't getName use magic get method to figure this out? function getName() { return $this->name; } @@ -60,6 +43,11 @@ class Organization extends OrganizationModel { function getCreateDate() { return $this->created; } +} + +class Organization extends OrganizationModel { + var $_entries; + var $_forms; function addDynamicData($data) { @@ -123,11 +111,6 @@ class Organization extends OrganizationModel { return (string) $this->getName(); } - function delete() { - //TODO: delete or reset intrumented list. - return parent::delete(); - } - function update($vars, &$errors) { $valid = true; @@ -250,7 +233,5 @@ class OrganizationForm extends DynamicForm { } } - -//Organization::_inspect(); - +Organization::_inspect(); ?> diff --git a/include/class.user.php b/include/class.user.php index d51c61639fb8a5509c7f0fefdd049664f8ec0653..a845455e6b9df52da4bb44b5bfcd9ed42b7ebf32 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -15,7 +15,6 @@ vim: expandtab sw=4 ts=4 sts=4: **********************************************************************/ require_once(INCLUDE_DIR . 'class.orm.php'); -require_once(INCLUDE_DIR . 'class.organization.php'); class UserEmailModel extends VerySimpleModel { static $meta = array( @@ -29,6 +28,30 @@ class UserEmailModel extends VerySimpleModel { ); } +class TicketModel extends VerySimpleModel { + static $meta = array( + 'table' => TICKET_TABLE, + 'pk' => array('ticket_id'), + 'joins' => array( + 'user' => array( + 'constraint' => array('user_id' => 'UserModel.id') + ) + ) + ); + + function getId() { + return $this->ticket_id; + } + + function delete() { + + if (($ticket=Ticket::lookup($this->getId())) && @$ticket->delete()) + return true; + + return false; + } +} + class UserModel extends VerySimpleModel { static $meta = array( 'table' => USER_TABLE, @@ -37,6 +60,9 @@ class UserModel extends VerySimpleModel { 'emails' => array( 'reverse' => 'UserEmailModel.user', ), + 'tickets' => array( + 'reverse' => 'TicketModel.user', + ), 'account' => array( 'list' => false, 'reverse' => 'UserAccount.user', @@ -48,14 +74,6 @@ class UserModel extends VerySimpleModel { ) ); - var $emails; - - static function objects() { - $qs = parent::objects(); - #$qs->select_related('default_email'); - return $qs; - } - function getId() { return $this->id; } @@ -74,15 +92,6 @@ class User extends UserModel { var $_entries; var $_forms; - var $_account; - - function __construct($ht) { - parent::__construct($ht); - // TODO: Make this automatic with select_related() - if (isset($ht['default_email_id'])) - $this->default_email = UserEmail::lookup($ht['default_email_id']); - } - static function fromVars($vars) { // Try and lookup by email address $user = User::lookup(array('emails__address'=>$vars['email'])); @@ -226,12 +235,7 @@ class User extends UserModel { } function getAccount() { - // XXX: return $this->account; - - if (!isset($this->_account)) - $this->_account = UserAccount::lookup(array('user_id'=>$this->getId())); - - return $this->_account; + return $this->account; } function getAccountStatus() { @@ -257,12 +261,6 @@ class User extends UserModel { return UserAccount::register($this, $vars, $errors); } - //TODO: Add organization support - function getOrg() { - return ''; - } - - function updateInfo($vars, &$errors) { $valid = true; @@ -333,11 +331,17 @@ class User extends UserModel { } function delete() { - //TODO: See about deleting other associated models. - // Delete email - if ($this->default_email) - $this->default_email->delete(); + // Refuse to delete a user with tickets + if ($this->tickets->count()) + return false; + + // Delete account record (if any) + if ($this->getAccount()) + $this->getAccount()->delete(); + + // Delete emails. + $this->emails->expunge(); // Delete user return parent::delete(); @@ -534,16 +538,13 @@ class UserAccountModel extends VerySimpleModel { 'joins' => array( 'user' => array( 'null' => false, - 'constraint' => array('user_id' => 'UserModel.id') + 'constraint' => array('user_id' => 'User.id') + ), + 'org' => array( + 'constraint' => array('org_id' => 'Organization.id') ), ), ); -} - -class UserAccount extends UserAccountModel { - var $_options = null; - var $_user; - var $_org; const CONFIRMED = 0x0001; const LOCKED = 0x0002; @@ -593,10 +594,6 @@ class UserAccount extends UserAccountModel { return !$this->hasStatus(self::FORBID_PASSWD_RESET); } - function hasPassword() { - return (bool) $this->get('passwd'); - } - function getStatus() { return $this->get('status'); } @@ -614,12 +611,8 @@ class UserAccount extends UserAccountModel { } function getUser() { - - if (!isset($this->_user)) { - if ($this->_user = User::lookup($this->getUserId())) - $this->_user->set('account', $this); - } - return $this->_user; + $this->user->set('account', $this); + return $this->user; } function getOrgId() { @@ -627,24 +620,26 @@ class UserAccount extends UserAccountModel { } function getOrganization() { - - if (!isset($this->_org)) - $this->_org = Organization::lookup($this->getOrgId()); - - return $this->_org; + return $this->org; } function setOrganization($org) { if (!$org instanceof Organization) return false; - $this->set('org_id', $org->getId()); - $this->_org = null; + $this->set('org', $org); $this->save(); return true; - } + } + +} +class UserAccount extends UserAccountModel { + + function hasPassword() { + return (bool) $this->get('passwd'); + } function sendResetEmail() { return static::sendUnlockEmail('pwreset-client') === true; @@ -867,6 +862,7 @@ class UserList implements IteratorAggregate, ArrayAccess { return $list ? implode(', ', $list) : ''; } } +require_once(INCLUDE_DIR . 'class.organization.php'); User::_inspect(); - +UserAccount::_inspect(); ?> diff --git a/include/staff/org-view.inc.php b/include/staff/org-view.inc.php index 89a8ee39df6d587cc7db14297e25c49ff9d18581..7951460c2cfbefdd309e09563bd9009a86c94aac 100644 --- a/include/staff/org-view.inc.php +++ b/include/staff/org-view.inc.php @@ -16,10 +16,10 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path') </table> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <tr> - <td width="50"> + <td width="50%"> <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> - <th width="100">Name:</th> + <th width="150">Name:</th> <td><b><a href="#orgs/<?php echo $org->getId(); ?>/edit" class="org-action"><i class="icon-edit"></i> <?php echo @@ -27,16 +27,15 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path') ?></a></td> </tr> <tr> - <th>Users:</th> - <td> {num-here} - </td> + <th>Account Manager:</th> + <td> </td> </tr> </table> </td> <td width="50%" style="vertical-align:top"> <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> - <th>Created:</th> + <th width="150">Created:</th> <td><?php echo Format::db_datetime($org->getCreateDate()); ?></td> </tr> <tr> diff --git a/include/staff/orgs.inc.php b/include/staff/orgs.inc.php index 0df382c6d9aa02f431f2bb952ca7683cb03c56e0..ded6efeb259f66a21580d9e7d8a7454c37b20f7c 100644 --- a/include/staff/orgs.inc.php +++ b/include/staff/orgs.inc.php @@ -121,11 +121,7 @@ else <?php } //end of while. endif; ?> - <tfoot> - <tr> - <td colspan="5"> </td> - </tr> - </tfoot> + </tbody> </table> <?php if($res && $num): //Show options.. diff --git a/include/staff/templates/dynamic-form.tmpl.php b/include/staff/templates/dynamic-form.tmpl.php index e6afae15a37d7b1ebb80eafa8fb1e341e6c98672..aaaf1bf696bd2481f2280ce707064ec5da621ea2 100644 --- a/include/staff/templates/dynamic-form.tmpl.php +++ b/include/staff/templates/dynamic-form.tmpl.php @@ -8,6 +8,7 @@ if (isset($options['entry']) && $options['mode'] == 'edit' return; ?> <tbody> + <tr><td style="width:<?php echo $options['width'] ?: 150;?>px;"></td><td></td></tr> <?php // Keep up with the entry id in a hidden field to decide what to add and // delete when the parent form is submitted diff --git a/include/staff/templates/org-delete.tmpl.php b/include/staff/templates/org-delete.tmpl.php index 17ab2bc6a94577e0967059c64050124ff2d910fa..5b00aee559e84c5189e5c9317e0fa2b3a0c0eee7 100644 --- a/include/staff/templates/org-delete.tmpl.php +++ b/include/staff/templates/org-delete.tmpl.php @@ -37,6 +37,13 @@ if ($info['error']) { ?> </table> <div class="clear"></div> + <?php + if (($users=$org->users->count())) { ?> + <hr> + <div> <strong><?php echo sprintf('%d %s', $users, $users>1 ? 'users' : 'user'); + ?> assigned to this organization will be orphaned.</strong></div> + <?php + } ?> <hr> <form method="delete" class="org" action="#orgs/<?php echo $org->getId(); ?>/delete"> diff --git a/include/staff/templates/user-delete.tmpl.php b/include/staff/templates/user-delete.tmpl.php index 661bfa70ee08148f1291238337edbf686ccdd77c..ae9b5ca1ceab456598eb8d4dfe3f47ef763751b3 100644 --- a/include/staff/templates/user-delete.tmpl.php +++ b/include/staff/templates/user-delete.tmpl.php @@ -47,20 +47,21 @@ if ($info['error']) { </table> <div class="clear"></div> <hr> + <form method="post" class="user" + action="#users/<?php echo $user->getId(); ?>/delete"> + <input type="hidden" name="id" value="<?php echo $user->getId(); ?>" /> + <?php - if ($user->getNumTickets()) { + if (($num=$user->tickets->count())) { echo sprintf('<div><input type="checkbox" name="deletetickets" value="1" > <strong>Delete <a href="tickets.php?a=search&uid=%d" target="_blank">%d %s</a> and any associated attachments and data.</strong></div><hr>', $user->getId(), - $user->getNumTickets(), - ($user->getNumTickets() >1) ? 'tickets' : 'ticket' + $num, + ($num >1) ? 'tickets' : 'ticket' ); } ?> - <form method="delete" class="user" - action="#users/<?php echo $user->getId(); ?>/delete"> - <input type="hidden" name="id" value="<?php echo $user->getId(); ?>" /> <p class="full-width"> <span class="buttons" style="float:left"> <input type="reset" value="Reset"> diff --git a/include/staff/templates/users.tmpl.php b/include/staff/templates/users.tmpl.php index 6b22d3db9ed111fb2a9ba72b86e3f4558e8e57f1..1b7ab4e1e5d25cf4e69fcf38ff9b76134d682a42 100644 --- a/include/staff/templates/users.tmpl.php +++ b/include/staff/templates/users.tmpl.php @@ -103,11 +103,7 @@ else <?php } //end of while. endif; ?> - <tfoot> - <tr> - <td colspan="4"> </td> - </tr> - </tfoot> + </tbody> </table> <?php if($res && $num): //Show options.. diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index d2c8ebe9a72cc4c88c2ef56ab230bf9236b0814b..c76bf30affd6655e6e46ecda139c4d09003dd7c6 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -132,7 +132,7 @@ if($ticket->isOverdue()) </table> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <tr> - <td width="50"> + <td width="50%"> <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> <th width="100">Status:</th> diff --git a/include/staff/user-view.inc.php b/include/staff/user-view.inc.php index 5ad4478c7fea8e9954a304eef9fffc4a1bd130a6..de27ddc2fc5f2bf1bfdc11cfe6e2114d946d9e9a 100644 --- a/include/staff/user-view.inc.php +++ b/include/staff/user-view.inc.php @@ -4,7 +4,6 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($user)) die('Invalid path' $account = $user->getAccount(); $org = $account ? $account->getOrganization() : null; - ?> <table width="940" cellpadding="2" cellspacing="0" border="0"> <tr> @@ -60,10 +59,10 @@ $org = $account ? $account->getOrganization() : null; </table> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <tr> - <td width="50"> + <td width="50%"> <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> - <th width="100">Name:</th> + <th width="150">Name:</th> <td><b><a href="#users/<?php echo $user->getId(); ?>/edit" class="user-action"><i class="icon-edit"></i> <?php echo @@ -100,7 +99,7 @@ $org = $account ? $account->getOrganization() : null; <td width="50%" style="vertical-align:top"> <table border="0" cellspacing="" cellpadding="4" width="100%"> <tr> - <th>Status:</th> + <th width="150">Status:</th> <td> <span id="user-<?php echo $user->getId(); ?>-status"><?php echo $user->getAccountStatus(); ?></span></td> </tr> diff --git a/include/staff/users.inc.php b/include/staff/users.inc.php index dab7d730527eddcc74afb20865285af5d154a3a9..62361f198e57510487e798d47bde5cb077a9b85d 100644 --- a/include/staff/users.inc.php +++ b/include/staff/users.inc.php @@ -137,11 +137,7 @@ else <?php } //end of while. endif; ?> - <tfoot> - <tr> - <td colspan="5"> </td> - </tr> - </tfoot> + </tbody> </table> <?php if($res && $num): //Show options.. diff --git a/scp/ajax.php b/scp/ajax.php index 65ce1c01143df2976f82c3ad2b21f97285af15f4..5a340bbce92122a5eb79af30a2269e43ac857989 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -84,7 +84,7 @@ $dispatcher = patterns('', url_get('^/(?P<id>\d+)/register$', 'register'), url_post('^/(?P<id>\d+)/register$', 'register'), url_get('^/(?P<id>\d+)/delete$', 'delete'), - url_delete('^/(?P<id>\d+)/delete$', 'delete'), + url_post('^/(?P<id>\d+)/delete$', 'delete'), url_get('^/(?P<id>\d+)/manage(?:/(?P<target>\w+))?$', 'manage'), url_post('^/(?P<id>\d+)/manage(?:/(?P<target>\w+))?$', 'manage'), url_get('^/(?P<id>\d+)/org(?:/(?P<orgid>\d+))?$', 'updateOrg'),