Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CO-1336_Normalization_vs_Pipelines #279

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions app/Lib/enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,20 @@ class DataFilterContextEnum
const ProvisioningTarget = 'PT';
}

class NormalizerTypeEnum
{
const TrimWhitespace = 'TW';
const MixCase = 'MC';
const PunctuationToSpace = 'PS';

// Each type maps to a function having the first letter lowercase
public static $type = array(
NormalizerTypeEnum::TrimWhitespace => 'TrimWhitespace',
NormalizerTypeEnum::MixCase => 'MixCase',
NormalizerTypeEnum::PunctuationToSpace => 'PunctuationToSpace'
);
}

class DepartmentEnum {
const Department = 'department';
const ResearchInstitute = 'researchinstitute';
Expand Down
13 changes: 9 additions & 4 deletions app/Model/AppModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -1657,22 +1657,27 @@ public function validateEnumeration($coId, $attribute, $value) {
* @param integer $coId CO ID
* @param string $attribute Attribute, in Model.attribute form
* @param string $value Value to normalize
* @param array $options Save options
* @return string The normalized value
*/

public function normalizeEnumeration($coId, $attribute, $value) {
public function normalizeEnumeration($coId, $attribute, $value, $options = array()) {
// First, see if there is an enumeration defined for $coId + $attribute.

$args = array();
$args['joins'][0]['table'] = 'dictionaries';
$args['joins'][0]['alias'] = 'Dictionary';
$args['joins'][0]['type'] = 'INNER';
$args['joins'][0]['conditions'][0] = 'AttributeEnumeration.dictionary_id=Dictionary.id';
$args['conditions']['AttributeEnumeration.co_id'] = $coId;
$args['conditions']['AttributeEnumeration.attribute'] = $attribute;
$args['conditions']['AttributeEnumeration.status'] = SuspendableStatusEnum::Active;
$args['contain'] = false;

$AttributeEnumeration = ClassRegistry::init('AttributeEnumeration');
$attrEnum = $AttributeEnumeration->find('first', $args);
$has_dictionary = (boolean)$AttributeEnumeration->find('count', $args);

if(empty($attrEnum['AttributeEnumeration']['dictionary_id'])) {
if(!$has_dictionary) {
// If there is no dictionary attached to the Attribute Enumeration
// configuration then load the normalizer
$this->Behaviors->load('Normalization');
Expand All @@ -1682,7 +1687,7 @@ public function normalizeEnumeration($coId, $attribute, $value) {

$a = explode('.', $attribute, 2);
$data[ $a[0] ][ $a[1] ] = $value;
$newdata = $this->normalize($data, $coId);
$newdata = $this->normalize($data, $coId, $options);

$this->Behaviors->unload('Normalization');

Expand Down
19 changes: 14 additions & 5 deletions app/Model/Behavior/NormalizationBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ class NormalizationBehavior extends ModelBehavior {
* @throws RuntimeException
*/

public function beforeValidate(Model $model, $options = array()) {
$model->data = $this->normalize($model, $model->data);
public function beforeSave(Model $model, $options = array()) {
$model->data = $this->normalize($model, $model->data, false, $options);

return true;
}
Expand All @@ -48,13 +48,22 @@ public function beforeValidate(Model $model, $options = array()) {
* @param Model $model Model instance
* @param Array $data Data to normalize in usual format; need not belong to $model
* @param Integer $coId CO ID data belongs to, or null for Org Identity data, or false to determine from $data ($data must then belong to $model)
* @param array List of Save options
* @return boolean true on success
* @throws RuntimeException
*/

public function normalize(Model $model, $data, $coId = false) {
public function normalize(Model $model, $data, $coId = false, $options = array()) {
$mname = $model->alias;


// Are there any types of normalization that we need to skip
$normalization_dis = array();
foreach (DefaultNormalizerTypeEnum::$type as $key => $value) {
if(isset($options[$key]) && !$options[$key]) {
$normalization_dis[] = $key;
}
}

// If $coId is false, look for a CO ID. If we don't find one or if $coId is null,
// we're dealing with org identity data, which normalizations don't currently support.

Expand Down Expand Up @@ -113,7 +122,7 @@ public function normalize(Model $model, $data, $coId = false) {

if($pluginModel->isPlugin('normalizer')) {
try {
$data = $pluginModel->normalize($data);
$data = $pluginModel->normalize($data, $normalization_dis);
}
catch(Exception $e) {
throw new RuntimeException($e->getMessage());
Expand Down
3 changes: 2 additions & 1 deletion app/Model/CoPersonRole.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,8 @@ public function beforeSave($options = array()) {
// Normalize Enumeration
$this->data[$this->alias][$a] = $this->normalizeEnumeration($coId,
'CoPersonRole.'.$a,
$this->data[$this->alias][$a]);
$this->data[$this->alias][$a],
$options);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion app/Model/CoPipeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,9 @@ protected function syncOrgIdentityToCoPerson($coPipeline,
// We need to inject the CO so extended types can be saved
$this->Co->CoPerson->CoPersonRole->validate['affiliation']['content']['rule'][1]['coid'] = $orgIdentity['OrgIdentity']['co_id'];

if(!$this->Co->CoPerson->CoPersonRole->save($newCoPersonRole, array("provision" => false, "safeties" => $safeties))) {
if(!$this->Co->CoPerson->CoPersonRole->save($newCoPersonRole, array("provision" => false,
"safeties" => $safeties,
NormalizerTypeEnum::MixCase => false))) {
throw new RuntimeException(_txt('er.db.save-a', array('CoPersonRole')));
}

Expand Down Expand Up @@ -1247,6 +1249,7 @@ protected function syncOrgIdentityToCoPerson($coPipeline,
if(!$model->save($nr, array("provision" => false,
"safeties" => $safeties,
"skipAvailability" => true,
NormalizerTypeEnum::MixCase => !in_array($model, array('CoPersonRole', 'EnrolleeCoPersonRole')),
"trustVerified" => $trustVerified))) {

throw new RuntimeException(_txt('er.db.save-a',
Expand Down
36 changes: 21 additions & 15 deletions app/Plugin/DefaultNormalizer/Model/DefaultNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,51 +52,52 @@ public function cmPluginMenus() {
*
* @since COmanage Registry v0.9.2
* @param Array Data to be saved, in typical Cake format
* @param Array Type of normalizations that we will skip
* @return Array Data in the same format
*/

public function normalize($data) {
public function normalize($data, $normalization_dis = array()) {
$ret = $data;

$normalizations = array(
'Address' => array(
'mixCase' => array('street', 'locality', 'state', 'country'),
'trimWhitespace' => array('street', 'locality', 'state', 'postal_code', 'country')
NormalizerTypeEnum::MixCase => array('street', 'locality', 'state', 'country'),
NormalizerTypeEnum::TrimWhitespace => array('street', 'locality', 'state', 'postal_code', 'country')
),
'CoPersonRole' => array(
'mixCase' => array('title', 'o', 'ou'),
'trimWhitespace' => array('title', 'o', 'ou')
NormalizerTypeEnum::MixCase => array('title', 'o', 'ou'),
NormalizerTypeEnum::TrimWhitespace => array('title', 'o', 'ou')
),
// We get passed the alias, not the model name during enrollment.
// There's not an obvious generic way to figure the out, but for now this
// only happens here, so we simply duplicate the rules. (CO-1550)
'EnrolleeCoPersonRole' => array(
'mixCase' => array('title', 'o', 'ou'),
'trimWhitespace' => array('title', 'o', 'ou')
NormalizerTypeEnum::MixCase => array('title', 'o', 'ou'),
NormalizerTypeEnum::TrimWhitespace => array('title', 'o', 'ou')
),
'EmailAddress' => array(
// Note cake validation will likely prevent this from being called
'trimWhitespace' => array('mail')
NormalizerTypeEnum::TrimWhitespace => array('mail')
),
'Identifier' => array(
'trimWhiteSpace' => array('identifier')
NormalizerTypeEnum::TrimWhitespace => array('identifier')
),
'Name' => array(
// For now, we don't mix case to avoid dealing with issues like people who
// go by lowercase names, or McPherson-style capitalization
'trimWhitespace' => array('honorific', 'given', 'middle', 'family', 'suffix')
NormalizerTypeEnum::TrimWhitespace => array('honorific', 'given', 'middle', 'family', 'suffix')
),
'TelephoneNumber' => array(
// Following E.123 format, we only use spaces in telephone numbers
// (the + and extension label get added by formatTelephone at rendering time)
'punctuationToSpace' => array('country_code', 'area_code', 'number', 'extension'),
'trimWhitespace' => array('country_code', 'area_code', 'number', 'extension')
NormalizerTypeEnum::PunctuationToSpace => array('country_code', 'area_code', 'number', 'extension'),
NormalizerTypeEnum::TrimWhitespace => array('country_code', 'area_code', 'number', 'extension')
),
'Url' => array(
// We don't normalize an http:// prefix because cake validation will prevent
// a URL from being submitted without a prefix (and we wouldn't know the
// protocol anyway).
'trimWhitespace' => array('url')
NormalizerTypeEnum::TrimWhitespace => array('url')
)
);

Expand Down Expand Up @@ -134,7 +135,7 @@ public function normalize($data) {
// We only trim whitespace since we can't say too much about the contents
// of the extended attribute.

$normalizations[$model]['trimWhitespace'][] = $name;
$normalizations[$model][NormalizerTypeEnum::TrimWhitespace][] = $name;
}
}
}
Expand All @@ -147,9 +148,14 @@ public function normalize($data) {
// Run the appropriate normalizations for each field within the model

foreach(array_keys($normalizations[$model]) as $normalization) {
// Skip a normalization if found in the exception list
if(in_array($normalization, $normalization_dis)) {
continue;
}
foreach($normalizations[$model][$normalization] as $field) {
if(!empty($ret[$model][$field])) {
$ret[$model][$field] = $this->$normalization($ret[$model][$field], $field);
$func = lcfirst( (NormalizerTypeEnum::$type)[$normalization] );
$ret[$model][$field] = $this->$func($ret[$model][$field], $field);
}
}
}
Expand Down