Skip to Content.
Sympa Menu

comanage-dev - [comanage-dev] r314 - in registry/trunk/app: Config/Schema Controller Lib Model View View/CoIdentifierAssignments View/CoPeople View/Elements View/Identifiers View/Identifiers/json View/Identifiers/xml View/Layouts View/Standard

Subject: COmanage Developers List

List archive

[comanage-dev] r314 - in registry/trunk/app: Config/Schema Controller Lib Model View View/CoIdentifierAssignments View/CoPeople View/Elements View/Identifiers View/Identifiers/json View/Identifiers/xml View/Layouts View/Standard


Chronological Thread 
  • From:
  • To:
  • Subject: [comanage-dev] r314 - in registry/trunk/app: Config/Schema Controller Lib Model View View/CoIdentifierAssignments View/CoPeople View/Elements View/Identifiers View/Identifiers/json View/Identifiers/xml View/Layouts View/Standard
  • Date: Sat, 14 Jul 2012 23:18:45 -0400

Author: benno
Date: 2012-07-14 23:18:44 -0400 (Sat, 14 Jul 2012)
New Revision: 314

Added:
registry/trunk/app/Controller/CoIdentifierAssignmentsController.php
registry/trunk/app/Model/CoIdentifierAssignment.php
registry/trunk/app/Model/CoSequentialIdentifierAssignment.php
registry/trunk/app/View/CoIdentifierAssignments/
registry/trunk/app/View/CoIdentifierAssignments/add.ctp
registry/trunk/app/View/CoIdentifierAssignments/edit.ctp
registry/trunk/app/View/CoIdentifierAssignments/fields.inc
registry/trunk/app/View/CoIdentifierAssignments/index.ctp
registry/trunk/app/View/CoIdentifierAssignments/view.ctp
registry/trunk/app/View/Identifiers/json/assign.ctp
registry/trunk/app/View/Identifiers/xml/assign.ctp
Modified:
registry/trunk/app/Config/Schema/schema.xml
registry/trunk/app/Controller/AppController.php
registry/trunk/app/Controller/IdentifiersController.php
registry/trunk/app/Controller/PagesController.php
registry/trunk/app/Controller/UsersController.php
registry/trunk/app/Lib/enum.php
registry/trunk/app/Lib/lang.php
registry/trunk/app/Model/AppModel.php
registry/trunk/app/Model/Co.php
registry/trunk/app/Model/CoPetition.php
registry/trunk/app/Model/Identifier.php
registry/trunk/app/View/CoPeople/fields.inc
registry/trunk/app/View/Elements/dropMenu.ctp
registry/trunk/app/View/Identifiers/fields.inc
registry/trunk/app/View/Identifiers/index.ctp
registry/trunk/app/View/Layouts/default.ctp
registry/trunk/app/View/Standard/edit.ctp
registry/trunk/app/View/Standard/view.ctp
Log:
Identifier Assignment (CO-344, CO-345, CO-346, CO-55)

Modified: registry/trunk/app/Config/Schema/schema.xml
===================================================================
--- registry/trunk/app/Config/Schema/schema.xml 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/Config/Schema/schema.xml 2012-07-15 03:18:44 UTC (rev
314)
@@ -265,6 +265,7 @@
<field name="identifier" type="C" size="256" />
<field name="type" type="C" size="32" />
<field name="login" type="L" />
+ <field name="status" type="C" size="2" />
<field name="co_person_id" type="I">
<constraint>REFERENCES cm_co_people(id)</constraint>
</field>
@@ -672,8 +673,53 @@
<field name="race" type="C" size="5" />
<field name="disability" type="C" size="4" />

- <index name="demographics_i1">
+ <index name="co_nsf_demographics_i1">
<col>co_person_id</col>
</index>
</table>
+
+ <table name="co_identifier_assignments">
+ <field name="id" type="I">
+ <key />
+ <autoincrement />
+ </field>
+ <field name="co_id" type="I">
+ <notnull />
+ <constraint>REFERENCES cm_cos(id)</constraint>
+ </field>
+ <field name="identifier_type" type="C" size="32">
+ <notnull />
+ </field>
+ <field name="description" type="C" size="256" />
+ <field name="login" type="L" />
+ <field name="algorithm" type="C" size="2" />
+ <field name="format" type="C" size="256" />
+ <field name="minimum" type="I" />
+ <field name="maximum" type="I" />
+ <field name="collision_resolution" type="C" size="64" />
+ <field name="exclusions" type="C" size="8" />
+
+ <index name="co_identifier_assignments_i1">
+ <col>co_id</col>
+ </index>
+ </table>
+
+ <table name="co_sequential_identifier_assignments">
+ <field name="id" type="I">
+ <key />
+ <autoincrement />
+ </field>
+ <field name="co_identifier_assignment_id" type="I">
+ <notnull />
+ <constraint>REFERENCES cm_co_identifier_assignments(id)</constraint>
+ </field>
+ <field name="affix" type="C" size="256" />
+ <field name="last" type="I" />
+
+ <index name="co_sequential_identifier_assignments_i1">
+ <col>co_identifier_assignment_id</col>
+ <col>affix</col>
+ <unique />
+ </index>
+ </table>
</schema>

Modified: registry/trunk/app/Controller/AppController.php
===================================================================
--- registry/trunk/app/Controller/AppController.php 2012-07-15 03:16:19
UTC (rev 313)
+++ registry/trunk/app/Controller/AppController.php 2012-07-15 03:18:44
UTC (rev 314)
@@ -116,10 +116,16 @@
if(!empty($this->cur_co)) {
$this->set("cur_co", $this->cur_co);

+ // XXX This is a hack for CO-368 and should not be relied upon.
if(isset($this->Identifier)) {
- // XXX This is a hack for CO-368 and should not be relied upon.
$this->Identifier->coId = $coid;
}
+ if(isset($this->CoIdentifierAssignment)) {
+ $this->CoIdentifierAssignment->coId = $coid;
+ }
+ if(isset($this->CoPetition->EnrolleeCoPerson->Identifier)) {
+ $this->CoPetition->EnrolleeCoPerson->Identifier->coId = $coid;
+ }
} else {
$this->Session->setFlash(_txt('er.co.unk-a', array($coid)), '',
array(), 'error');
$this->redirect(array('controller' => 'cos', 'action' =>
'select'));
@@ -1128,6 +1134,9 @@
// Manage any CO (or COU) population?
$p['menu']['petitions'] = $cmr['admin'] || $cmr['subadmin'];

+ // Manage CO ID Assignment?
+ $p['menu']['idassign'] = $cmr['admin'];
+
// Manage COU definitions?
$p['menu']['cous'] = $cmr['admin'];


Modified: registry/trunk/app/Controller/IdentifiersController.php
===================================================================
--- registry/trunk/app/Controller/IdentifiersController.php 2012-07-15
03:16:19 UTC (rev 313)
+++ registry/trunk/app/Controller/IdentifiersController.php 2012-07-15
03:18:44 UTC (rev 314)
@@ -37,6 +37,108 @@
);

/**
+ * Autoassign identifiers for a CO Person.
+ * - precondition: $this->request->params holds CO ID and CO Person ID
+ * - postcondition: Session flash message updated (HTML) or HTTP status
returned (REST)
+ * - postcondition: Redirect issued (HTML)
+ *
+ * @since COmanage Registry v0.6
+ */
+
+ function assign() {
+ if($this->restful) {
+ // We manually run a few of the steps in StandardController
+
+ if(!$this->checkRestPost($this->request->data)) {
+ return;
+ }
+
+ $coid = $this->cur_co['Co']['id'];
+
+ $personData = $this->parsePersonID($this->request->data);
+
+ if(isset($personData['copersonid'])) {
+ $copersonid = $personData['copersonid'];
+ } else {
+ $this->restResultHeader(403, "No Person Specified");
+ return;
+ }
+ } else {
+ // While the controller doesn't require_co, this method does.
+
+ $coid = $this->parseCOID($this->request->data);
+ $copersonid =
Sanitize::html($this->request->params['named']['copersonid']);
+ }
+
+ if($coid != -1) {
+ // Assign the identifiers, then walk through the result array and
generate a flash message
+ $res = $this->Identifier->assign($coid, $copersonid);
+
+ if(!empty($res)) {
+ // Loop through the results and build result messages
+
+ $errs = ""; // Unexpected errors
+ $assigned = array(); // Identifiers that were assigned
+ $existed = array(); // Identifiers that already existed
+
+ foreach(array_keys($res) as $type) {
+ if($res[$type] == 2) {
+ $existed[] = $type;
+ } elseif($res[$type] == 1) {
+ $assigned[] = $type;
+ } else {
+ $errs .= $type . ": " . $res[$type] . "<br />\n";
+ }
+ }
+
+ if($this->restful) {
+ if($errs != "") {
+ $this->restResultHeader(500, "Other Error");
+ } else {
+ $this->restResultHeader(200, "OK");
+ }
+ } else {
+ if($errs != "") {
+ $this->Session->setFlash($errs, '', array(), 'error');
+ }
+
+ if(!empty($assigned)) {
+ $this->Session->setFlash(_txt('rs.ia.ok') . " (" . implode(',',
$assigned) . ")",
+ '', array(), 'success');
+ }
+
+ if(!empty($existed)) {
+ $this->Session->setFlash(_txt('er.ia.already') . " (" .
implode(',', $existed) . ")",
+ '', array(), 'info');
+ }
+ }
+ } else {
+ if($this->restful) {
+ $this->restResultHeader(200, "OK");
+ } else {
+ $this->Session->setFlash(_txt('er.ia.none'), '', array(), 'info');
+ }
+ }
+ } else {
+ if($this->restful) {
+ $this->restResultHeader(403, "CO Does Not Exist");
+ } else {
+ $this->Session->setFlash(_txt('er.co.unk'), '', array(), 'error');
+ }
+ }
+
+ if(!$this->restful) {
+ // Redirect to CO Person view
+ $rargs['controller'] = 'co_people';
+ $rargs['action'] = 'edit';
+ $rargs[] = $copersonid;
+ $rargs['co'] = $this->cur_co['Co']['id'];
+
+ $this->redirect($rargs);
+ }
+ }
+
+ /**
* Callback before other controller methods are invoked or views are
rendered.
* - postcondition: Redirect may be issued
*
@@ -57,24 +159,67 @@
* This method is intended to be overridden by model-specific controllers.
* - postcondition: Session flash message updated (HTML) or HTTP status
returned (REST)
*
- * @since COmanage Registry v0.3
+ * @since COmanage Registry v0.6
* @param Array Request data
* @param Array Current data
* @return boolean true if dependency checks succeed, false otherwise.
+ */

function checkWriteDependencies($reqdata, $curdata = null) {
- // We currently don't perform any sanity checks (ie: dupe checks) on
identifiers
- // since it's not clear when we should reject an identifier for already
existing.
- // For example, if

is a uid for an org identity, why can't it be a
- // uid for that person's CO identity as well?
+ // Check to make sure that a given identifier of a given type is not
already
+ // in use within a CO. In order to prevent potential conflicts with
Identifier
+ // Assignment (eg: an admin manually changes an identifier to one that
would
+ // be next assigned sequentially) this method creates a transaction that
+ // checkWriteFollowups commits.

- // The minimal case that could be checked is the same identifier for the
same
- // org identity or co person.
+ if(isset($this->cur_co)) {
+ $dbc = $this->Identifier->getDataSource();
+
+ if(isset($this->cur_co)) {
+ $dbc->begin();
+ }
+
+
if(!$this->Identifier->checkAvailability($reqdata['Identifier']['identifier'],
+
$reqdata['Identifier']['type'],
+ $this->cur_co['Co']['id'])) {
+ if($this->restful)
+ $this->restResultHeader(403, "Identifier In Use");
+ else
+ $this->Session->setFlash(_txt('er.ia.exists',
array(Sanitize::html($reqdata['Identifier']['identifier']))), '', array(),
'error');
+
+ $dbc->rollback();
+ return false;
+ }
+ }
+ // else don't do this check for org identities

return true;
}
+
+ /**
+ * Perform any followups following a write operation. Note that if this
+ * method fails, it must return a warning or REST response, but that the
+ * overall transaction is still considered a success (add/edit is not
+ * rolled back).
+ * This method is intended to be overridden by model-specific controllers.
+ *
+ * @since COmanage Registry v0.6
+ * @param Array Request data
+ * @param Array Current data
+ * @return boolean true if dependency checks succeed, false otherwise.
*/
-
+
+ function checkWriteFollowups($reqdata) {
+ $dbc = $this->Identifier->getDataSource();
+
+ if(isset($this->cur_co)) {
+ // Commit under all circumstances
+ $dbc->commit();
+ }
+
+ return true;
+ }
+
/**
* Authorization for this Controller, called by Auth component
* - precondition: Session.Auth holds data used for authz decisions
@@ -106,6 +251,9 @@
// Add a new Identifier?
$p['add'] = ($cmr['cmadmin'] || $admin);

+ // Assign (autogenerate) Identifiers?
+ $p['assign'] = ($cmr['cmadmin'] || $admin);
+
// Delete an existing Identifier?
$p['delete'] = ($cmr['cmadmin'] || $admin);


Modified: registry/trunk/app/Controller/PagesController.php
===================================================================
--- registry/trunk/app/Controller/PagesController.php 2012-07-15 03:16:19
UTC (rev 313)
+++ registry/trunk/app/Controller/PagesController.php 2012-07-15 03:18:44
UTC (rev 314)
@@ -128,7 +128,10 @@
// Manage CO enrollment flow definitions?
$p['menu']['coef'] = $cmr['admin'];

- // Admin COmanage?
+ // Manage CO identifier assignment definitions?
+ $p['menu']['idassign'] = $cmr['admin'];
+
+ // Admin COmanage?
$p['menu']['admin'] = $cmr['cmadmin'];

// Manage NSF Demographics?

Modified: registry/trunk/app/Controller/UsersController.php
===================================================================
--- registry/trunk/app/Controller/UsersController.php 2012-07-15 03:16:19
UTC (rev 313)
+++ registry/trunk/app/Controller/UsersController.php 2012-07-15 03:18:44
UTC (rev 314)
@@ -93,6 +93,9 @@
$args['joins'][0]['conditions'][0] =
'OrgIdentity.id=Identifier.org_identity_id';
$args['conditions']['Identifier.identifier'] = $u;
$args['conditions']['Identifier.login'] = true;
+ // Join on identifiers that aren't deleted (including if they have
no status)
+ $args['conditions']['OR'][] = 'Identifier.status IS NULL';
+ $args['conditions']['OR'][]['Identifier.status <>'] =
StatusEnum::Deleted;
// Through the magic of containable behaviors, we can get all the
associated
// data we need in one clever find
$args['contain'][] = 'Name';

Modified: registry/trunk/app/Lib/enum.php
===================================================================
--- registry/trunk/app/Lib/enum.php 2012-07-15 03:16:19 UTC (rev 313)
+++ registry/trunk/app/Lib/enum.php 2012-07-15 03:18:44 UTC (rev 314)
@@ -115,6 +115,19 @@
const Female = 'F';
}

+class IdentifierAssignmentEnum
+{
+ const Random = 'R';
+ const Sequential = 'S';
+}
+
+class IdentifierAssignmentExclusionEnum
+{
+ const Confusing = 'C';
+ const Offensive = 'O';
+ const Superstitious = 'S';
+}
+
class IdentifierEnum
{
const ePPN = 'eppn';
@@ -157,11 +170,12 @@

class PetitionActionEnum
{
- const Approved = 'PY';
- const Created = 'PC';
- const Declined = 'PX';
- const Denied = 'PN';
- const Finalized = 'PF';
+ const Approved = 'PY';
+ const Created = 'PC';
+ const Declined = 'PX';
+ const Denied = 'PN';
+ const Finalized = 'PF';
+ const IdentifiersAssigned = 'IA';
}

class RequiredEnum

Modified: registry/trunk/app/Lib/lang.php
===================================================================
--- registry/trunk/app/Lib/lang.php 2012-07-15 03:16:19 UTC (rev 313)
+++ registry/trunk/app/Lib/lang.php 2012-07-15 03:18:44 UTC (rev 314)
@@ -65,6 +65,8 @@
'ct.co_extended_attributes.pl' => 'Extended Attributes',
'ct.co_extended_types.1' => 'Extended Type',
'ct.co_extended_types.pl' => 'Extended Types',
+ 'ct.co_identifier_assignments.1' => 'Identifier Assignment',
+ 'ct.co_identifier_assignments.pl' => 'Identifier Assignments',
'ct.co_group_members.1' => 'Group Member',
'ct.co_group_members.pl' => 'Group Members',
'ct.co_groups.1' => 'Group',
@@ -140,6 +142,9 @@
ExtendedAttributeEnum::Timestamp => 'Timestamp',
ExtendedAttributeEnum::Varchar32 => 'String
(32)'),

+ 'en.ia.algorithm' => array(IdentifierAssignmentEnum::Random => 'Random',
+ IdentifierAssignmentEnum::Sequential =>
'Sequential'),
+
'en.identifier' => array(IdentifierEnum::ePPN => 'ePPN',
IdentifierEnum::ePTID => 'ePTID',
IdentifierEnum::Mail => 'Mail',
@@ -242,6 +247,10 @@
'er.gr.res' => 'Groups named "admin" or prefixed "admin:" are
reserved',
'er.grm.already' => 'CO Person %1$s is already a member of group %2$s',
'er.grm.none' => 'No group memberships to add',
+ 'er.ia.already' => 'Identifier already assigned',
+ 'er.ia.exists' => 'The identifier "%1$s" is already in use',
+ 'er.ia.failed' => 'Failed to find a unique identifier to assign',
+ 'er.ia.none' => 'No identifier assignments configured',
'er.inv.exp' => 'Invitation Expired',
'er.inv.nf' => 'Invitation Not Found',
'er.nd.already' => 'NSF Demographic data already exists for this person',
@@ -352,6 +361,22 @@
'fd.group.own' => 'Owner',
'fd.groups' => 'Groups',
'fd.history.pt' => 'Petition History',
+ // Identifier Assignment
+ 'fd.ia.algorithm' => 'Algorithm',
+ 'fd.ia.algorithm.desc' => 'The algorithm to use when generating
identifiers',
+ 'fd.ia.exclusions' => 'Exclusions',
+ 'fd.ia.exclusions.desc' => '(Not yet implemented)',
+ 'fd.ia.format' => 'Format',
+ 'fd.ia.format.desc' => 'See <a
href="https://spaces.internet2.edu/display/COmanage/Configuring+Registry+Identifier+Assignment";>Configuring
Registry Identifier Assignment</a> for details',
+ 'fd.ia.format.prefab' => 'Select a Common Pattern',
+ 'fd.ia.format.p0' => 'Default (#)',
+ 'fd.ia.format.p1' => 'given.family(.#)@myvo.org',
+ 'fd.ia.format.p2' => 'given(.m).family(.#)@myvo.org',
+ 'fd.ia.format.p3' =>
'gmf#@myvo.org',
+ 'fd.ia.maximum' => 'Maximum',
+ 'fd.ia.maximum.desc' => 'The maximum value for randomly generated
identifiers',
+ 'fd.ia.minimum' => 'Minimum',
+ 'fd.ia.minimum.desc' => 'The minimum value for randomly generated
identifiers, or the starting value for sequences',
// The next set must be named fd.model.validation-field
'fd.identifier.identifier' => 'Identifier',
'fd.identifier.login' => 'Login',
@@ -428,8 +453,10 @@
'op.edit-f' => 'Edit %1$s for %2$s',
'op.enroll' => 'Enroll',
'op.find.inv' => 'Find a Person to Invite to %1$s',
- 'op.gr.memadd' => 'Add %1$s to Group',
+ 'op.gr.memadd' => 'Add Person %1$s to Group',
'op.grm.add' => 'Add Person to %1$s Group %2$s',
+ 'op.id.auto' => 'Autogenerate Identifiers',
+ 'op.id.auto.confirm' => 'Are you sure you wish to autogenerate
identifiers?',
'op.inv' => 'Invite',
'op.inv-a' => 'Invite %1$s',
'op.inv-t' => 'Invite %1$s to %2$s',
@@ -452,6 +479,7 @@
// Results
'rs.added' => 'Added',
'rs.added-a' => '"%1$s" Added',
+ 'rs.ia.ok' => 'Identifiers Assigned',
'rs.inv.conf' => 'Invitation Confirmed',
'rs.inv.dec' => 'Invitation Declined',
'rs.pt.approve' => 'Petition Approved',

Modified: registry/trunk/app/Model/AppModel.php
===================================================================
--- registry/trunk/app/Model/AppModel.php 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/Model/AppModel.php 2012-07-15 03:18:44 UTC (rev
314)
@@ -198,6 +198,39 @@
}

/**
+ * Perform a find, but using SELECT ... FOR UPDATE syntax. This function
should
+ * be called within a transaction.
+ *
+ * @since COmanage Registry v0.6
+ * @param Array Find conditions in the usual Cake format
+ * @param Array List of fields to retrieve
+ * @param Array Join conditions in the usual Cake format
+ * @return Array Result set as returned by Cake fetchAll() or read(),
which isn't necessarily the same format as find()
+ */
+
+ function findForUpdate($conditions, $fields, $joins = array()) {
+ $dbc = $this->getDataSource();
+
+ $args['conditions'] = $conditions;
+ $args['fields'] = $dbc->fields($this, null, $fields);
+ $args['table'] = $dbc->fullTableName($this->useTable);
+ $args['alias'] = $this->alias;
+ // Don't allow joins to be NULL, make it an empty array if not set
+ $args['joins'] = ($joins ? $joins : array());
+
+ // For the moment, we don't support these for no particular reason
+ $args['order'] = null;
+ $args['limit'] = null;
+ $args['group'] = null;
+
+ // Appending to the generated query should be fairly portable.
+
+ // We should perhaps be using read() and/or buildQuery() instead.
+
+ return $dbc->fetchAll($dbc->buildStatement($args, $this) . " FOR
UPDATE", array(), array('cache' => false));
+ }
+
+ /**
* For models that support Extended Types, obtain the valid types for the
specified CO.
*
* @since COmanage Registry v0.6

Modified: registry/trunk/app/Model/Co.php
===================================================================
--- registry/trunk/app/Model/Co.php 2012-07-15 03:16:19 UTC (rev 313)
+++ registry/trunk/app/Model/Co.php 2012-07-15 03:18:44 UTC (rev 314)
@@ -38,6 +38,7 @@
// A CO has zero or more groups
"CoGroup" => array('dependent' => true),
// A CO can have zero or more CO people
+ "CoIdentifierAssignment" => array('dependent' => true),
"CoPerson" => array('dependent' => true),
// A CO can have zero or more petitions
"CoPetition" => array('dependent' => true),

Modified: registry/trunk/app/Model/CoPetition.php
===================================================================
--- registry/trunk/app/Model/CoPetition.php 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/Model/CoPetition.php 2012-07-15 03:18:44 UTC (rev
314)
@@ -669,7 +669,7 @@
// Process the new status
$fail = false;

- // Start a tronsaction
+ // Start a transaction
$dbc = $this->getDataSource();
$dbc->begin();

@@ -740,6 +740,43 @@
}
}

+ // Maybe assign identifiers, but only for new approvals
+
+ if(!$fail && $newStatus == StatusEnum::Approved) {
+ $coID = $this->field('co_id');
+ $coPersonID = $this->field('enrollee_co_person_id');
+
+ if($coID && $coPersonID) {
+ $res = $this->EnrolleeCoPerson->Identifier->assign($coID,
$coPersonID);
+
+ if(!empty($res)) {
+ // See if any identifiers were assigned, and if so create a
history record
+ $assigned = array();
+
+ foreach(array_keys($res) as $idType) {
+ if($res[$idType] == 1) {
+ $assigned[] = $idType;
+ } elseif($res[$idType] != 2) {
+ // It'd probably be helpful if we caught this error
somewhere...
+ $fail = true;
+ }
+ }
+
+ if(!empty($assigned)) {
+ try {
+ $this->CoPetitionHistoryRecord->record($id,
+ $actorCoPersonID,
+
PetitionActionEnum::IdentifiersAssigned,
+ _txt('rs.ia.ok') . "
(" . implode(',', $assigned) . ")");
+ }
+ catch (Exception $e) {
+ $fail = true;
+ }
+ }
+ }
+ }
+ }
+
if(!$fail) {
// Commit


Modified: registry/trunk/app/Model/Identifier.php
===================================================================
--- registry/trunk/app/Model/Identifier.php 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/Model/Identifier.php 2012-07-15 03:18:44 UTC (rev
314)
@@ -53,11 +53,12 @@
),
'type' => array(
'rule' => array('validateExtendedType',
- array(IdentifierEnum::ePPN,
- IdentifierEnum::ePTID,
- IdentifierEnum::Mail,
- IdentifierEnum::OpenID,
- IdentifierEnum::UID)),
+ array('attribute' => 'Identifier',
+ 'default' => array(IdentifierEnum::ePPN,
+ IdentifierEnum::ePTID,
+ IdentifierEnum::Mail,
+ IdentifierEnum::OpenID,
+ IdentifierEnum::UID))),
'required' => false,
'allowEmpty' => false
),
@@ -65,6 +66,12 @@
'rule' => array('boolean'),
'required' => false
),
+ 'status' => array(
+ 'rule' => array('inList', array(StatusEnum::Active,
+ StatusEnum::Deleted)),
+ 'required' => true,
+ 'allowEmpty' => false
+ ),
'co_person_id' => array(
'rule' => 'numeric',
'required' => false
@@ -80,8 +87,110 @@
public $cm_enum_types = array(
'status' => 'status_t'
);
+
+ /**
+ * Autoassign identifiers for a CO Person.
+ *
+ * @since COmanage Registry v0.6
+ * @param Integer CO ID
+ * @param Integer CO Person ID
+ * @return Array Success for each attribute, where the key is the
attribute assigned and the value is 1 for success, 2 for already assigned, or
an error string
+ */

+ function assign($coId, $coPersonId) {
+ $ret = array();
+
+ // First, see if there are any identifiers to autoassign for this CO.
This will return the
+ // same thing if the answer is "no" or if the answer is "invalid CO ID".
+
+ $args = array();
+ $args['conditions']['Co.id'] = $coId;
+
+ $identifierAssignments =
$this->CoPerson->Co->CoIdentifierAssignment->find('all', $args);
+
+ if(!empty($identifierAssignments)) {
+ // Loop through each identifier and request assignment.
+
+ foreach($identifierAssignments as $ia) {
+ // Assign will throw an error if an identifier of this type already
exists.
+
+ try {
+ $this->CoPerson->Co->CoIdentifierAssignment->assign($ia,
$coPersonId);
+ $ret[ $ia['CoIdentifierAssignment']['identifier_type'] ] = 1;
+ }
+ catch(OverflowException $e) {
+ // An identifier already exists of this type for this CO Person
+ $ret[ $ia['CoIdentifierAssignment']['identifier_type'] ] = 2;
+ }
+ catch(Exception $e) {
+ $ret[ $ia['CoIdentifierAssignment']['identifier_type'] ] =
$e->getMessage();
+ }
+ }
+ }
+
+ return $ret;
+ }
+
/**
+ * Determine if an identifier of a given type is already assigned to a CO
Person.
+ * Only active identifiers are considered.
+ *
+ * IMPORTANT: This function should be called within a transaction to ensure
+ * actions taken based on availability are atomic.
+ *
+ * @since COmanage Registry v0.6
+ * @param Integer CO Person ID
+ * @param String Type of candidate identifier
+ * @return Boolean True if an identifier of the specified type is already
assigned, false otherwise
+ */
+
+ public function assigned($coPersonID, $identifierType) {
+ $args = array();
+ $args['conditions']['Identifier.co_person_id'] = $coPersonID;
+ $args['conditions']['Identifier.type'] = $identifierType;
+ $args['conditions']['Identifier.status'] = StatusEnum::Active;
+
+ $r = $this->findForUpdate($args['conditions'], array('identifier'));
+
+ return !empty($r);
+ }
+
+ /**
+ * Check if an identifier is available for assignment. An identifier is
available
+ * if it is not defined (regardless of status) within the same CO.
+ *
+ * IMPORTANT: This function should be called within a transaction to ensure
+ * actions taken based on availability are atomic.
+ *
+ * @since COmanage Registry v0.6
+ * @param String Candidate identifier
+ * @param String Type of candidate identifier
+ * @param Integer CO ID
+ * @return Boolean True if identifier is not in use, false otherwise
+ */
+
+ public function checkAvailability($identifier, $identifierType, $coId) {
+ // In order to allow ensure that another process doesn't perform the same
+ // availability check while we're running, we need to lock the
appropriate
+ // tables/rows at read time. We do this with findForUpdate instead of a
normal find.
+
+ $args = array();
+ $args['conditions']['CoPerson.co_id'] = $coId;
+ $args['conditions']['Identifier.identifier'] = $identifier;
+ $args['conditions']['Identifier.type'] = $identifierType;
+ $args['joins'][0]['table'] = 'co_people';
+ $args['joins'][0]['alias'] = 'CoPerson';
+ $args['joins'][0]['type'] = 'INNER';
+ $args['joins'][0]['conditions'][0] =
'CoPerson.id=Identifier.co_person_id';
+
+ $r = $this->findForUpdate($args['conditions'],
+ array('identifier'),
+ $args['joins']);
+
+ return empty($r);
+ }
+
+ /**
* Check if a given identifier type is in use by any members of a CO.
*
* @since COmanage Registry v0.6


Property changes on: registry/trunk/app/View/CoIdentifierAssignments/add.ctp
___________________________________________________________________
Added: svn:special
+ *


Property changes on: registry/trunk/app/View/CoIdentifierAssignments/edit.ctp
___________________________________________________________________
Added: svn:special
+ *


Property changes on: registry/trunk/app/View/CoIdentifierAssignments/view.ctp
___________________________________________________________________
Added: svn:special
+ *

Modified: registry/trunk/app/View/CoPeople/fields.inc
===================================================================
--- registry/trunk/app/View/CoPeople/fields.inc 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/View/CoPeople/fields.inc 2012-07-15 03:18:44 UTC (rev
314)
@@ -45,7 +45,7 @@

if($e)
{
- echo $this->Html->link(_txt('op.cancel'),
+ echo $this->Html->link(_txt('op.back'),
array('controller' => 'co_people', 'action' =>
'index', 'co' => $cur_co['Co']['id']),
array('class' => 'cancelbutton'));

@@ -80,10 +80,45 @@
<br />
';
}
+ else
+ {
+ echo $this->Html->link(_txt('op.back'),
+ array('controller' => 'co_people', 'action' =>
'index', 'co' => $cur_co['Co']['id']),
+ array('class' => 'backbutton')) . '
+ <br />
+ <br />
+ ';
+ }

// Line number, for rendering
$l = 1;
?>
+<script type="text/javascript">
+ <!-- JS specific to these fields -->
+
+ function js_confirm_autogenerate(url)
+ {
+ // Generate a dialog box confirming the autogeneration of identifiers.
+ // On confirmation, forward to <url>, which executes the autogeneration.
+
+ // Set the title of the dialog
+ $("#dialog").dialog("option", "title", "<?php print _txt('op.id.auto');
?>");
+
+ // Set the body of the dialog
+ $("#dialog-text").text('<?php print _txt('op.id.auto.confirm'); ?>');
+
+ // Set the dialog buttons
+ $("#dialog").dialog("option",
+ "buttons",
+ {
+ "<?php print _txt('op.cancel'); ?>": function() {
$(this).dialog("close"); },
+ "<?php print _txt('op.id.auto'); ?>": function() {
window.location=url; }
+ });
+
+ // Open the dialog
+ $('#dialog').dialog('open');
+ }
+</script>
<table id="<?php echo $this->action; ?>_co_person" class="ui-widget">
<tbody>
<tr>
@@ -211,9 +246,19 @@
}
}

- echo $this->Html->link(_txt('op.add'),
+ print $this->Html->link(_txt('op.add'),
array('controller' =>
'identifiers', 'action' => 'add', 'copersonid' =>
$co_people[0]['CoPerson']['id'], 'co' => $cur_co['Co']['id']),
- array('class' => 'addbutton'));
+ array('class' => 'addbutton')) .
"\n";
+
+ print '<a
+ class="autobutton"
+ title="' . _txt('op.id.auto') . '"
+ onclick="javascript:js_confirm_autogenerate(\''
. $this->Html->url(array('controller' => 'identifiers',
+
'action' => 'assign',
+
'copersonid' => $co_people[0]['CoPerson']['id'],
+
'co' => $cur_co['Co']['id'])) . '\')";>'
+ . _txt('op.id.auto')
+ . "</a>\n";
}
else
{

Modified: registry/trunk/app/View/Elements/dropMenu.ctp
===================================================================
--- registry/trunk/app/View/Elements/dropMenu.ctp 2012-07-15 03:16:19
UTC (rev 313)
+++ registry/trunk/app/View/Elements/dropMenu.ctp 2012-07-15 03:18:44
UTC (rev 314)
@@ -21,9 +21,7 @@
*/

// Load the list of COs
-if(isset($this->viewVars['menuContent']['cos']))
- $cos = $this->viewVars['menuContent']['cos'];
-else $cos = array();
+$cos = $this->viewVars['menuContent']['cos'];
?>

<div class="menubar">
@@ -79,6 +77,17 @@
print "</li>";
}

+ if(isset($permissions['menu']['idassign']) &&
$permissions['menu']['idassign']) {
+ print "<li>";
+ $args = array(
+ 'controller' => 'co_identifier_assignments',
+ 'action' => 'index',
+ 'co' => $menuCoId
+ );
+ print
$this->Html->link(_txt('ct.co_identifier_assignments.pl'), $args);
+ print "</li>";
+ }
+
if(isset($permissions['menu']['extattrs']) &&
$permissions['menu']['extattrs']) {
print "<li>";
$args = array(

Modified: registry/trunk/app/View/Identifiers/fields.inc
===================================================================
--- registry/trunk/app/View/Identifiers/fields.inc 2012-07-15 03:16:19
UTC (rev 313)
+++ registry/trunk/app/View/Identifiers/fields.inc 2012-07-15 03:18:44
UTC (rev 314)
@@ -38,7 +38,10 @@
echo $this->Html->link(_txt('op.cancel'),
isset($redirect) ? $redirect : array('controller' =>
'identifiers', 'action' => 'index'),
array('class' => 'cancelbutton'));
-
+ else
+ echo $this->Html->link(_txt('op.back'),
+ isset($redirect) ? $redirect : array('controller'
=> 'identifiers', 'action' => 'index'),
+ array('class' => 'backbutton'));

echo '
<br />
@@ -102,6 +105,31 @@
<?php echo ($e ? $this->Form->input('login') :
Sanitize::html($identifiers[0]['Identifier']['login'])); ?>
</td>
</tr>
+ <tr class="line2">
+ <td>
+ <?php echo _txt('fd.status'); ?>
+ </td>
+ <td>
+ <?php
+ global $cm_lang, $cm_texts;
+ $attrs = array();
+ $attrs['value'] = (isset($identifiers) ?
$identifiers[0]['Identifier']['status'] : StatusEnum::Active);
+ $attrs['empty'] = false;
+
+ if($e) {
+ print $this->Form->select('status',
+ $cm_texts[ $cm_lang ]['en.status'],
+ $attrs);
+
+ if($this->Form->isFieldError('status')) {
+ print $this->Form->error('status');
+ }
+ } else {
+ print _txt('en.status', null,
$identifiers[0]['Identifier']['status']);
+ }
+ ?>
+ </td>
+ </tr>
<tr>
<td>
<i><font class="required"><?php echo _txt('fd.req');
?></font></i><br />
@@ -114,4 +142,4 @@
</td>
</tr>
</tbody>
-</table>
+</table>
\ No newline at end of file

Modified: registry/trunk/app/View/Identifiers/index.ctp
===================================================================
--- registry/trunk/app/View/Identifiers/index.ctp 2012-07-15 03:16:19
UTC (rev 313)
+++ registry/trunk/app/View/Identifiers/index.ctp 2012-07-15 03:18:44
UTC (rev 314)
@@ -33,6 +33,7 @@
<th><?php echo $this->Paginator->sort('identifier',
_txt('fd.identifier.identifier')); ?></th>
<th><?php echo $this->Paginator->sort('type', _txt('fd.type')); ?></th>
<th><?php echo $this->Paginator->sort('login',
_txt('fd.identifier.login')); ?></th>
+ <th><?php echo $this->Paginator->sort('status', _txt('fd.status'));
?></th>
<!-- XXX Following needs to be I18N'd, and also render a full name, if
index view sticks around -->
<th><?php echo $this->Paginator->sort('OrgIdentity.Name.family', 'Org
Identity'); ?></th>
<th><?php echo $this->Paginator->sort('CoPerson.Name.family', 'CO
Person'); ?></th>
@@ -64,6 +65,13 @@
</td>
<td>
<?php
+ global $status_t;
+
+ if(!empty($a['Identifier']['status'])) print _txt('en.status',
null, $a['Identifier']['status']);
+ ?>
+ </td>
+ <td>
+ <?php
if(!empty($a['Identifier']['org_identity_id']))
{
// Generally, someone who has view permission on an attribute
number can also see a person

Modified: registry/trunk/app/View/Layouts/default.ctp
===================================================================
--- registry/trunk/app/View/Layouts/default.ctp 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/View/Layouts/default.ctp 2012-07-15 03:18:44 UTC (rev
314)
@@ -133,12 +133,18 @@
}
});

+ $(".autobutton").button({
+ icons: {
+ primary: 'ui-icon-script'
+ }
+ });
+
$(".backbutton").button({
icons: {
primary: 'ui-icon-circle-arrow-w'
}
});
-
+
$(".cancelbutton").button({
icons: {
primary: 'ui-icon-circle-close'

Modified: registry/trunk/app/View/Standard/edit.ctp
===================================================================
--- registry/trunk/app/View/Standard/edit.ctp 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/View/Standard/edit.ctp 2012-07-15 03:18:44 UTC (rev
314)
@@ -49,6 +49,8 @@
$h = _txt('op.edit-a', array(Sanitize::html($d[0][$req]['label'])));
elseif(isset($d[0][$req]['name']))
$h = _txt('op.edit-a', array(Sanitize::html($d[0][$req]['name'])));
+ elseif(isset($d[0][$req]['description']))
+ $h = _txt('op.edit-a',
array(Sanitize::html($d[0][$req]['description'])));
else
$h = _txt('op.edit');


Modified: registry/trunk/app/View/Standard/view.ctp
===================================================================
--- registry/trunk/app/View/Standard/view.ctp 2012-07-15 03:16:19 UTC (rev
313)
+++ registry/trunk/app/View/Standard/view.ctp 2012-07-15 03:18:44 UTC (rev
314)
@@ -33,7 +33,7 @@
// Figure out a heading
$h = "";

- // XXX This should probably get refactored into the models
+ // XXX This should probably get refactored into the models (duped in
edit.ctp)
if(isset($d[0]['Name']))
$h = _txt('op.view-a', array(Sanitize::html(generateCn($d[0]['Name']))));
elseif(isset($d[0]['CoPerson']['Name']))
@@ -50,8 +50,12 @@
$h = _txt('op.view-a', array(Sanitize::html($d[0][$req]['line1'])));
elseif(isset($d[0][$req]['label']))
$h = _txt('op.view-a', array(Sanitize::html($d[0][$req]['label'])));
+ elseif(isset($d[0][$req]['name']))
+ $h = _txt('op.edit-a', array(Sanitize::html($d[0][$req]['name'])));
+ elseif(isset($d[0][$req]['description']))
+ $h = _txt('op.edit-a',
array(Sanitize::html($d[0][$req]['description'])));
else
- $h = _txt('op.view-a', array(Sanitize::html($d[0][$req]['name'])));
+ $h = _txt('op.view');

$params = array('title' => $h);
print $this->element("pageTitle", $params);



  • [comanage-dev] r314 - in registry/trunk/app: Config/Schema Controller Lib Model View View/CoIdentifierAssignments View/CoPeople View/Elements View/Identifiers View/Identifiers/json View/Identifiers/xml View/Layouts View/Standard, svnlog, 07/14/2012

Archive powered by MHonArc 2.6.16.

Top of Page