Skip to content
Snippets Groups Projects
Commit 99fda7ce authored by Jared Hancock's avatar Jared Hancock
Browse files

Merge pull request #753 from protich/feature/organization-support-revisited


Organization support revisited

Reviewed-By: default avatarJared Hancock <jared@osticket.com>
parents 5d0da7c8 8742d556
No related branches found
No related tags found
No related merge requests found
...@@ -177,18 +177,22 @@ class UsersAjaxAPI extends AjaxController { ...@@ -177,18 +177,22 @@ class UsersAjaxAPI extends AjaxController {
elseif (!($user = User::lookup($id))) elseif (!($user = User::lookup($id)))
Http::response(404, 'Unknown user'); 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(); $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()) if (!$info['error'] && $user->delete())
$info['error'] = 'You cannot delete a user with tickets!';
elseif ($user->delete())
Http::response(204, 'User deleted successfully'); Http::response(204, 'User deleted successfully');
else elseif (!$info['error'])
$info['error'] = 'Unable to delete user - try again!'; $info['error'] = 'Unable to delete user - try again!';
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
require_once(INCLUDE_DIR . 'class.orm.php'); require_once(INCLUDE_DIR . 'class.orm.php');
require_once(INCLUDE_DIR . 'class.forms.php'); require_once(INCLUDE_DIR . 'class.forms.php');
require_once(INCLUDE_DIR . 'class.dynamic_forms.php'); require_once(INCLUDE_DIR . 'class.dynamic_forms.php');
require_once(INCLUDE_DIR . 'class.user.php');
class OrganizationModel extends VerySimpleModel { class OrganizationModel extends VerySimpleModel {
static $meta = array( static $meta = array(
...@@ -22,33 +23,15 @@ class OrganizationModel extends VerySimpleModel { ...@@ -22,33 +23,15 @@ class OrganizationModel extends VerySimpleModel {
'pk' => array('id'), 'pk' => array('id'),
'joins' => array( 'joins' => array(
'users' => array( 'users' => array(
'reverse' => 'UserAccountModel.org', 'reverse' => 'UserAccount.org',
), ),
) )
); );
var $users;
static function objects() {
$qs = parent::objects();
return $qs;
}
function getId() { function getId() {
return $this->id; 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() { function getName() {
return $this->name; return $this->name;
} }
...@@ -60,6 +43,11 @@ class Organization extends OrganizationModel { ...@@ -60,6 +43,11 @@ class Organization extends OrganizationModel {
function getCreateDate() { function getCreateDate() {
return $this->created; return $this->created;
} }
}
class Organization extends OrganizationModel {
var $_entries;
var $_forms;
function addDynamicData($data) { function addDynamicData($data) {
...@@ -123,11 +111,6 @@ class Organization extends OrganizationModel { ...@@ -123,11 +111,6 @@ class Organization extends OrganizationModel {
return (string) $this->getName(); return (string) $this->getName();
} }
function delete() {
//TODO: delete or reset intrumented list.
return parent::delete();
}
function update($vars, &$errors) { function update($vars, &$errors) {
$valid = true; $valid = true;
...@@ -250,7 +233,5 @@ class OrganizationForm extends DynamicForm { ...@@ -250,7 +233,5 @@ class OrganizationForm extends DynamicForm {
} }
} }
Organization::_inspect();
//Organization::_inspect();
?> ?>
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
vim: expandtab sw=4 ts=4 sts=4: vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/ **********************************************************************/
require_once(INCLUDE_DIR . 'class.orm.php'); require_once(INCLUDE_DIR . 'class.orm.php');
require_once(INCLUDE_DIR . 'class.organization.php');
class UserEmailModel extends VerySimpleModel { class UserEmailModel extends VerySimpleModel {
static $meta = array( static $meta = array(
...@@ -29,6 +28,30 @@ class UserEmailModel extends VerySimpleModel { ...@@ -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 { class UserModel extends VerySimpleModel {
static $meta = array( static $meta = array(
'table' => USER_TABLE, 'table' => USER_TABLE,
...@@ -37,6 +60,9 @@ class UserModel extends VerySimpleModel { ...@@ -37,6 +60,9 @@ class UserModel extends VerySimpleModel {
'emails' => array( 'emails' => array(
'reverse' => 'UserEmailModel.user', 'reverse' => 'UserEmailModel.user',
), ),
'tickets' => array(
'reverse' => 'TicketModel.user',
),
'account' => array( 'account' => array(
'list' => false, 'list' => false,
'reverse' => 'UserAccount.user', 'reverse' => 'UserAccount.user',
...@@ -48,14 +74,6 @@ class UserModel extends VerySimpleModel { ...@@ -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() { function getId() {
return $this->id; return $this->id;
} }
...@@ -74,15 +92,6 @@ class User extends UserModel { ...@@ -74,15 +92,6 @@ class User extends UserModel {
var $_entries; var $_entries;
var $_forms; 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) { static function fromVars($vars) {
// Try and lookup by email address // Try and lookup by email address
$user = User::lookup(array('emails__address'=>$vars['email'])); $user = User::lookup(array('emails__address'=>$vars['email']));
...@@ -226,12 +235,7 @@ class User extends UserModel { ...@@ -226,12 +235,7 @@ class User extends UserModel {
} }
function getAccount() { function getAccount() {
// XXX: return $this->account; return $this->account;
if (!isset($this->_account))
$this->_account = UserAccount::lookup(array('user_id'=>$this->getId()));
return $this->_account;
} }
function getAccountStatus() { function getAccountStatus() {
...@@ -257,12 +261,6 @@ class User extends UserModel { ...@@ -257,12 +261,6 @@ class User extends UserModel {
return UserAccount::register($this, $vars, $errors); return UserAccount::register($this, $vars, $errors);
} }
//TODO: Add organization support
function getOrg() {
return '';
}
function updateInfo($vars, &$errors) { function updateInfo($vars, &$errors) {
$valid = true; $valid = true;
...@@ -333,11 +331,17 @@ class User extends UserModel { ...@@ -333,11 +331,17 @@ class User extends UserModel {
} }
function delete() { function delete() {
//TODO: See about deleting other associated models.
// Delete email // Refuse to delete a user with tickets
if ($this->default_email) if ($this->tickets->count())
$this->default_email->delete(); return false;
// Delete account record (if any)
if ($this->getAccount())
$this->getAccount()->delete();
// Delete emails.
$this->emails->expunge();
// Delete user // Delete user
return parent::delete(); return parent::delete();
...@@ -534,16 +538,13 @@ class UserAccountModel extends VerySimpleModel { ...@@ -534,16 +538,13 @@ class UserAccountModel extends VerySimpleModel {
'joins' => array( 'joins' => array(
'user' => array( 'user' => array(
'null' => false, '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 CONFIRMED = 0x0001;
const LOCKED = 0x0002; const LOCKED = 0x0002;
...@@ -593,10 +594,6 @@ class UserAccount extends UserAccountModel { ...@@ -593,10 +594,6 @@ class UserAccount extends UserAccountModel {
return !$this->hasStatus(self::FORBID_PASSWD_RESET); return !$this->hasStatus(self::FORBID_PASSWD_RESET);
} }
function hasPassword() {
return (bool) $this->get('passwd');
}
function getStatus() { function getStatus() {
return $this->get('status'); return $this->get('status');
} }
...@@ -614,12 +611,8 @@ class UserAccount extends UserAccountModel { ...@@ -614,12 +611,8 @@ class UserAccount extends UserAccountModel {
} }
function getUser() { function getUser() {
$this->user->set('account', $this);
if (!isset($this->_user)) { return $this->user;
if ($this->_user = User::lookup($this->getUserId()))
$this->_user->set('account', $this);
}
return $this->_user;
} }
function getOrgId() { function getOrgId() {
...@@ -627,24 +620,26 @@ class UserAccount extends UserAccountModel { ...@@ -627,24 +620,26 @@ class UserAccount extends UserAccountModel {
} }
function getOrganization() { function getOrganization() {
return $this->org;
if (!isset($this->_org))
$this->_org = Organization::lookup($this->getOrgId());
return $this->_org;
} }
function setOrganization($org) { function setOrganization($org) {
if (!$org instanceof Organization) if (!$org instanceof Organization)
return false; return false;
$this->set('org_id', $org->getId()); $this->set('org', $org);
$this->_org = null;
$this->save(); $this->save();
return true; return true;
} }
}
class UserAccount extends UserAccountModel {
function hasPassword() {
return (bool) $this->get('passwd');
}
function sendResetEmail() { function sendResetEmail() {
return static::sendUnlockEmail('pwreset-client') === true; return static::sendUnlockEmail('pwreset-client') === true;
...@@ -867,6 +862,7 @@ class UserList implements IteratorAggregate, ArrayAccess { ...@@ -867,6 +862,7 @@ class UserList implements IteratorAggregate, ArrayAccess {
return $list ? implode(', ', $list) : ''; return $list ? implode(', ', $list) : '';
} }
} }
require_once(INCLUDE_DIR . 'class.organization.php');
User::_inspect(); User::_inspect();
UserAccount::_inspect();
?> ?>
...@@ -16,10 +16,10 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path') ...@@ -16,10 +16,10 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path')
</table> </table>
<table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0">
<tr> <tr>
<td width="50"> <td width="50%">
<table border="0" cellspacing="" cellpadding="4" width="100%"> <table border="0" cellspacing="" cellpadding="4" width="100%">
<tr> <tr>
<th width="100">Name:</th> <th width="150">Name:</th>
<td><b><a href="#orgs/<?php echo $org->getId(); <td><b><a href="#orgs/<?php echo $org->getId();
?>/edit" class="org-action"><i ?>/edit" class="org-action"><i
class="icon-edit"></i>&nbsp;<?php echo class="icon-edit"></i>&nbsp;<?php echo
...@@ -27,16 +27,15 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path') ...@@ -27,16 +27,15 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($org)) die('Invalid path')
?></a></td> ?></a></td>
</tr> </tr>
<tr> <tr>
<th>Users:</th> <th>Account Manager:</th>
<td> {num-here} <td>&nbsp; </td>
</td>
</tr> </tr>
</table> </table>
</td> </td>
<td width="50%" style="vertical-align:top"> <td width="50%" style="vertical-align:top">
<table border="0" cellspacing="" cellpadding="4" width="100%"> <table border="0" cellspacing="" cellpadding="4" width="100%">
<tr> <tr>
<th>Created:</th> <th width="150">Created:</th>
<td><?php echo Format::db_datetime($org->getCreateDate()); ?></td> <td><?php echo Format::db_datetime($org->getCreateDate()); ?></td>
</tr> </tr>
<tr> <tr>
......
...@@ -121,11 +121,7 @@ else ...@@ -121,11 +121,7 @@ else
<?php <?php
} //end of while. } //end of while.
endif; ?> endif; ?>
<tfoot> </tbody>
<tr>
<td colspan="5"> &nbsp; </td>
</tr>
</tfoot>
</table> </table>
<?php <?php
if($res && $num): //Show options.. if($res && $num): //Show options..
......
...@@ -8,6 +8,7 @@ if (isset($options['entry']) && $options['mode'] == 'edit' ...@@ -8,6 +8,7 @@ if (isset($options['entry']) && $options['mode'] == 'edit'
return; return;
?> ?>
<tbody> <tbody>
<tr><td style="width:<?php echo $options['width'] ?: 150;?>px;"></td><td></td></tr>
<?php <?php
// Keep up with the entry id in a hidden field to decide what to add and // Keep up with the entry id in a hidden field to decide what to add and
// delete when the parent form is submitted // delete when the parent form is submitted
......
...@@ -37,6 +37,13 @@ if ($info['error']) { ...@@ -37,6 +37,13 @@ if ($info['error']) {
?> ?>
</table> </table>
<div class="clear"></div> <div class="clear"></div>
<?php
if (($users=$org->users->count())) { ?>
<hr>
<div>&nbsp;<strong><?php echo sprintf('%d %s', $users, $users>1 ? 'users' : 'user');
?> assigned to this organization will be orphaned.</strong></div>
<?php
} ?>
<hr> <hr>
<form method="delete" class="org" <form method="delete" class="org"
action="#orgs/<?php echo $org->getId(); ?>/delete"> action="#orgs/<?php echo $org->getId(); ?>/delete">
......
...@@ -47,20 +47,21 @@ if ($info['error']) { ...@@ -47,20 +47,21 @@ if ($info['error']) {
</table> </table>
<div class="clear"></div> <div class="clear"></div>
<hr> <hr>
<form method="post" class="user"
action="#users/<?php echo $user->getId(); ?>/delete">
<input type="hidden" name="id" value="<?php echo $user->getId(); ?>" />
<?php <?php
if ($user->getNumTickets()) { if (($num=$user->tickets->count())) {
echo sprintf('<div><input type="checkbox" name="deletetickets" value="1" > echo sprintf('<div><input type="checkbox" name="deletetickets" value="1" >
<strong>Delete <a href="tickets.php?a=search&uid=%d" target="_blank">%d <strong>Delete <a href="tickets.php?a=search&uid=%d" target="_blank">%d
%s</a> and any associated attachments and data.</strong></div><hr>', %s</a> and any associated attachments and data.</strong></div><hr>',
$user->getId(), $user->getId(),
$user->getNumTickets(), $num,
($user->getNumTickets() >1) ? 'tickets' : 'ticket' ($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"> <p class="full-width">
<span class="buttons" style="float:left"> <span class="buttons" style="float:left">
<input type="reset" value="Reset"> <input type="reset" value="Reset">
......
...@@ -103,11 +103,7 @@ else ...@@ -103,11 +103,7 @@ else
<?php <?php
} //end of while. } //end of while.
endif; ?> endif; ?>
<tfoot> </tbody>
<tr>
<td colspan="4"> &nbsp; </td>
</tr>
</tfoot>
</table> </table>
<?php <?php
if($res && $num): //Show options.. if($res && $num): //Show options..
......
...@@ -132,7 +132,7 @@ if($ticket->isOverdue()) ...@@ -132,7 +132,7 @@ if($ticket->isOverdue())
</table> </table>
<table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0">
<tr> <tr>
<td width="50"> <td width="50%">
<table border="0" cellspacing="" cellpadding="4" width="100%"> <table border="0" cellspacing="" cellpadding="4" width="100%">
<tr> <tr>
<th width="100">Status:</th> <th width="100">Status:</th>
......
...@@ -4,7 +4,6 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($user)) die('Invalid path' ...@@ -4,7 +4,6 @@ if(!defined('OSTSCPINC') || !$thisstaff || !is_object($user)) die('Invalid path'
$account = $user->getAccount(); $account = $user->getAccount();
$org = $account ? $account->getOrganization() : null; $org = $account ? $account->getOrganization() : null;
?> ?>
<table width="940" cellpadding="2" cellspacing="0" border="0"> <table width="940" cellpadding="2" cellspacing="0" border="0">
<tr> <tr>
...@@ -60,10 +59,10 @@ $org = $account ? $account->getOrganization() : null; ...@@ -60,10 +59,10 @@ $org = $account ? $account->getOrganization() : null;
</table> </table>
<table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0"> <table class="ticket_info" cellspacing="0" cellpadding="0" width="940" border="0">
<tr> <tr>
<td width="50"> <td width="50%">
<table border="0" cellspacing="" cellpadding="4" width="100%"> <table border="0" cellspacing="" cellpadding="4" width="100%">
<tr> <tr>
<th width="100">Name:</th> <th width="150">Name:</th>
<td><b><a href="#users/<?php echo $user->getId(); <td><b><a href="#users/<?php echo $user->getId();
?>/edit" class="user-action"><i ?>/edit" class="user-action"><i
class="icon-edit"></i>&nbsp;<?php echo class="icon-edit"></i>&nbsp;<?php echo
...@@ -100,7 +99,7 @@ $org = $account ? $account->getOrganization() : null; ...@@ -100,7 +99,7 @@ $org = $account ? $account->getOrganization() : null;
<td width="50%" style="vertical-align:top"> <td width="50%" style="vertical-align:top">
<table border="0" cellspacing="" cellpadding="4" width="100%"> <table border="0" cellspacing="" cellpadding="4" width="100%">
<tr> <tr>
<th>Status:</th> <th width="150">Status:</th>
<td> <span id="user-<?php echo $user->getId(); <td> <span id="user-<?php echo $user->getId();
?>-status"><?php echo $user->getAccountStatus(); ?></span></td> ?>-status"><?php echo $user->getAccountStatus(); ?></span></td>
</tr> </tr>
......
...@@ -137,11 +137,7 @@ else ...@@ -137,11 +137,7 @@ else
<?php <?php
} //end of while. } //end of while.
endif; ?> endif; ?>
<tfoot> </tbody>
<tr>
<td colspan="5"> &nbsp; </td>
</tr>
</tfoot>
</table> </table>
<?php <?php
if($res && $num): //Show options.. if($res && $num): //Show options..
......
...@@ -84,7 +84,7 @@ $dispatcher = patterns('', ...@@ -84,7 +84,7 @@ $dispatcher = patterns('',
url_get('^/(?P<id>\d+)/register$', 'register'), url_get('^/(?P<id>\d+)/register$', 'register'),
url_post('^/(?P<id>\d+)/register$', 'register'), url_post('^/(?P<id>\d+)/register$', 'register'),
url_get('^/(?P<id>\d+)/delete$', 'delete'), 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_get('^/(?P<id>\d+)/manage(?:/(?P<target>\w+))?$', 'manage'),
url_post('^/(?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'), url_get('^/(?P<id>\d+)/org(?:/(?P<orgid>\d+))?$', 'updateOrg'),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment