/** * Hooked Function to check if a field is unique * @param I2CE_FormField $field_obj */ public function validate_formfield($field_obj) { if (!$field_obj->hasOption('unique') || !$field_obj->getOption('unique') || !$field_obj->isValid()) { return; } if (!$field_obj->hasOption('unique_field')) { return; } $unique = $field_obj->getOption('unique_field'); if (strpos($unique, ':') === false) { //the value is not a mapped thing. this is handled by hooked mehtod defined in I2CE_FormStorage return; } $form_obj = $field_obj->getContainer(); if (!$form_obj instanceof I2CE_Form) { return; } $factory = I2CE_FormFactory::instance(); //$unique should have the form 'unqique_field:form2(+field2):..:..:formM(+fieldM):...:formN //example $unique = 'region:country' or 'region+region+country:country' are the same. // means that $field_obj needs to be unqiue when reseticted to the set of forms within a country and all of its regions // the country and the region that is specified is the // in this case, we need that region is a field of $form_obj //example: $unqiue = 'county:district+region:region:country' or 'county:district:region:country' are the same // means that $field_obj needs to be unique when resitrcicted to a country, any of its regions any of those regions // in this case, we need that county is a field of $form_obj //example: $unqiue = '[location]county:district+region:region:country' or 'county:district:region:country' are the same // means that $field_obj needs to be unique when resitrcicted to a country, any of its regions any of those regions // in this case, we need that location is a field of $form_obj $unique_fields = explode(',', $unique); $matches = null; $names = array(); $main_where = array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => $field_obj->getName(), 'data' => array('value' => $field_obj->getDBValue())); foreach ($unique_fields as $unique_field) { if ($matches === false) { break; } if (strpos($unique_field, ':') === false) { //this field is not mapped... just handle it as a regular value. if (!($unique_field_obj = $form_obj->getField($unique_field)) instanceof I2CE_FormField) { I2CE::raiseError("Invalid field {$unqiue_field}"); return; } if ($unique_field_obj->hasHeader('default')) { $names[] = $unique_field_obj->getHeader('default'); } else { $names[] = $unique_field_obj->getName(); } $where = array($main_where); if ($unique_field_obj->getDBValue()->isValid()) { $where[] = array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => $unique_field_obj->getName(), 'data' => array('value' => $unique_field_obj->getDBValue())); } else { $where[] = array('operator' => 'OR', 'operand' => array(0 => array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => $unique_field_obj->getName(), 'data' => array('value' => $unique_field_obj->getDBValue())), 1 => array('operator' => 'FIELD_LIMIT', 'style' => 'null', 'field' => $unique_field_obj->getName()))); } if (count($where) > 1) { $where = array('operator' => 'AND', 'operand' => $where); } $found = I2CE_FormStorage::search($form_obj->getName(), false, $where); foreach ($found as &$f) { $f = (string) $f; } $matches = count($found) > 0 && in_array((string) $form_obj->getId(), $found, true); } else { $field_path = explode(':', $unique_field); $restricted_field = false; if (preg_match('/^\\[(.*?)\\](.*)$/', $field_path[0])) { $restricted_field = $matches[1]; $field_path[0] = $matches[2]; } else { if (preg_match('/^(.*?)\\+(.*)$/', $field_path[0], $matches)) { $restricted_field = $matches[1]; } else { $restricted_field = $field_path[0]; } } $restricted_field_obj = $form_obj->getField($restricted_field); if (!$restricted_field_obj instanceof I2CE_FormField_MAP) { I2CE::raiseError("Invalid field passed as restricted field for " . $form_obj->getName() . ": {$unique_field}"); return; } if ($restricted_field_obj->hasHeader('default')) { $names[] = $restricted_field_obj->getHeader('default'); } else { $names[] = $restricted_field_obj->getName(); } //now let's split up field_path into the forms and the fields $top_formid = I2CE_List::walkupFieldPath($field_path, $restricted_field_obj->getDBValue()); if ($top_formid === false) { //the value is not set. or inappropriately set. error silently. //this is handled by hooked method defined in I2CE_Module_Form. return; } //now we get all forms under $top_formid defined by the field path $field_name = $field_obj->getName(); $field_val = $field_obj->getDBValue(); $form_id = $form_obj->getID(); $dtree_path = $field_path; array_unshift($dtree_path, $form_obj->getName()); list($top_form, $top_id) = explode('|', $top_formid, 2); $dtree_limits = array($top_form => array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => 'id', 'data' => array('value' => $top_id)), $form_obj->getName() => $main_where); $options = I2CE_List::buildDataTree($dtree_path, array($form_obj->getName()), $dtree_limits); $options = I2CE_List::flattenDataTree($options); if (count($options) == 1) { // If there's only one match and it is this form then don't block // changes. if ($options[0]['value'] != $form_obj->getNameId()) { $matches = true; } } elseif (count($options) > 1) { $matches = true; } /* array_pop($field_path); $options = I2CE_List::monsterMash( $form_obj->getName(), //facility $restricted_field, //location $top_formid, //country|10 $field_path, //array(county+district,district+region,region+country) $field_name, //name false ); //starts get all facility where location = country|10 // get all regions region|X where region+country = country|10 // this means we need to start with // link_field = country (e.g link_field_path[$len-1] // list(sub_form,sub_link_field) = explode(+,end(subfields) ) == (region,country) // //next get all facility where location = residence|X $option_matches = false; foreach ($options as $id=>$data) { if (array_key_exists($field_name,$data) && ($data[$field_name] == $field_val) && ( $id != $form_id)) { $option_matches =true; break; } } $matches = ($option_matches); */ } } if ($matches === true) { if (count($names) > 1) { $field_obj->setInvalidMessage('unique_fields', null, ' ' . implode(', ', $names)); } else { if (count($names) == 1) { $field_obj->setInvalidMessage('unique_field', null, ' ' . implode(', ', $names)); } else { $field_obj->setInvalidMessage('unique'); } } return; } }
/** * Hooked Function to check if a field is unique or unique restricted to a certain field * @param I2CE_FormField $field_obj * @returns boolean */ public function validate_formfield($field_obj) { if (!$field_obj->hasOption('unique') || !$field_obj->getOption('unique') || !$field_obj->isValid() || !$field_obj->issetValue() || $field_obj->getDBValue() == "") { return; } $where = array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => $field_obj->getName(), 'data' => array('value' => $field_obj->getDBValue())); $form_obj = $field_obj->getContainer(); if (!$form_obj instanceof I2CE_Form) { I2CE::raiseError(get_class($form_obj)); return; } $names = array(); $search_parent = false; if ($field_obj->hasOption('unique_field')) { $unique = $field_obj->getOption('unique_field'); if (strpos($unique, ':') !== false) { //the value is a mapped thing. this is handled by hooked mehtod defined in I2CE_Module_List return; } $unique_fields = explode(',', $unique); $unique_where = array($where); foreach ($unique_fields as $unique_field) { if ($unique_field == "parent") { $search_parent = $form_obj->getParent(); if ($search_parent == "") { // If there is no parent then we can't validate // by parent so ignore this return; } continue; } if (!($unique_field_obj = $form_obj->getField($unique_field)) instanceof I2CE_FormField) { I2CE::raiseError("Invalid field {$unique_field}"); return; } if ($unique_field_obj->hasHeader('default')) { $names[] = $unique_field_obj->getHeader('default'); } else { $names[] = $unique_field_obj->getName(); } if ($unique_field_obj->isValid()) { $unique_where[] = array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => $unique_field_obj->getName(), 'data' => array('value' => $unique_field_obj->getDBValue())); } else { $unique_where[] = array('operator' => 'OR', 'operand' => array(0 => array('operator' => 'FIELD_LIMIT', 'style' => 'equals', 'field' => $unique_field_obj->getName(), 'data' => array('value' => $unique_field_obj->getDBValue())), 1 => array('operator' => 'FIELD_LIMIT', 'style' => 'null', 'field' => $unique_field_obj->getName()))); } } if (count($unique_where) > 1) { //we added somehitng $where = array('operator' => 'AND', 'operand' => $unique_where); } } $found = I2CE_FormStorage::search($form_obj->getName(), $search_parent, $where, array(), 1); if ($found !== false && '' . $found != '' . $form_obj->getId()) { I2CE::raiseMessage("found is {$found} and id is " . $form_obj->getId() . " and names are " . print_r($names, true)); if (count($names) > 1) { $field_obj->setInvalidMessage('unique_fields', null, ' ' . implode(', ', $names)); //$field_obj->setInvalid("This must be unique and another record has this value for the given value of the fields " .implode(',',$names) ); } else { if (count($names) == 1) { $field_obj->setInvalidMessage('unique_field', null, ' ' . implode(', ', $names)); //$field_obj->setInvalid("This must be unique and another record has this value for the given value of the field " .implode(',',$names) ); } else { $field_obj->setInvalidMessage('unique'); //$field_obj->setInvalid("This must be unique and another record has this value." ); } } } }
/** * Hooked Function to check if a fieldObj is valid * @param I2CE_FormField $fieldObj */ public function validate_formfield($fieldObj) { if ($fieldObj->hasOption('required') && $fieldObj->getOption('required') && !$fieldObj->isValid()) { $fieldObj->setInvalidMessage("required"); } }