rows.
$oFieldSet = DocumentFieldSet::get($fieldset_id);
if (empty($active_fields)) {
$res = $this->getMasterFieldInfo($oFieldSet);
$fieldsToRender[$oFieldSet->getMasterField()] = $res;
} else {
// urgh. we use this to generate our list of things to extract from the input.
$pairings = array();
foreach ($active_fields as $field_id) {
$current = KTUtil::arrayGet($_REQUEST, 'conditional_field_'.$field_id);
if ($current === null) {
return 'invalid input sequence.';
}
else {
$pairings[$field_id] = $current;
}
}
$res = $this->validatePath($oFieldSet, $pairings, true);
if ($res === true) {
return 'validated input.';
}
else if ($res === false) {
return 'invalid input';
}
// quick collation process.
foreach ($res as $aRow) {
$fieldsToRender[$aRow["document_field_id"]][] = $aRow;
}
}
$default->log->debug('validatePath: results '.print_r($fieldsToRender,true));
$oTemplating = new KTTemplating;
$oTemplate = $oTemplating->loadTemplate("ktcore/handle_conditional");
$aTemplateData = array(
"fieldset" => $oFieldSet->getId(),
"oldfields" => $pairings,
"fieldsToRender" => $fieldsToRender,
);
return $oTemplate->render($aTemplateData);
}
function handleOutput($data) {
print $data;
}
function getMasterFieldInfo($oFieldSet) {
global $default;
$masterField = $oFieldSet->getMasterField();
$sQuery = "SELECT md_cond.document_field_id AS document_field_id, md_cond.metadata_lookup_id AS val, md_lookup.name AS name FROM $default->md_condition_table AS md_cond LEFT JOIN $default->md_condition_chain_table AS md_chain ON (md_cond.id = md_chain.child_condition) LEFT JOIN $default->metadata_table AS md_lookup ON (md_cond.metadata_lookup_id = md_lookup.id) WHERE md_cond.document_field_id = ? ";
return DBUtil::getResultArray(array($sQuery, array($masterField)));
}
// either returns the set of pathid's for the input,
// or false (FIXME: should be PEAR::raiseError)
function validatePath($oFieldSet, $aPairings, $bPartial) {
/* An explanation of what happens below, since NBM's comment was "Put that crack-pipe back in the freezer."
*
* $aPairings are the inputs we were handed. Within these, there are 3
* important things:
* 1. we have a limited set of document_fields within the $oFieldSet.
* 2. one of these fields is the "master field" - the _ONLY_ one without
* any parent conditions.
* 3. some fields may get passed _out_ as
* which indicates that there is NO VALUE for that field (again, saved in the db as "-1" so we don't go mad.
*
* We essentially have 3 stacks: inputs, parent_conditions, free_field_ids
*
* $bPartial indicates what we need to do once we've run out of inputs to validate: either fail (if we don't have coverage, and its not partial)
* or return the possible next choices.
*
* We start with the master-field, and get its entry in the table. If it isn't there, fail.
* i. push its field onto the "parent_conditions" stack, and remove the field_id from the "option_fields".
* ii. remove its entry from the inputs.
* While we have inputs ->
* find any matches that have a (field_id, lookup_id) in the input set, and parent_condition in the parent_conditions stack.
* if no values found, FAIL - invalid input (we can't match what we've been given).
* otherwise ->
* remove them from the input stack, push their id's onto the parent_condition stack, and remove their field_id's from the field_id stack.
* If $bPartial == true ->
* get anything which has a parent_condition in the parent_condition set, and a field_id in the free_field_id's set -> this will give you
* the next set of "inputs" - (column, lookup) pairs with parent-rules that have been activated.
* If $bPartial == false and free_field_id's still has anything in it WE FAIL OUT.
*/
global $default;
$free_field_ids = array();
$parent_conditions = array();
$inputs = $aPairings; // please tell me this does a copy ...
// step 1: generate free_field_ids.
$childFields = DocumentField::getList('parent_fieldset = '.$oFieldSet->getId());
foreach ($childFields as $oField) {
$free_field_ids[$oField->getId()] = 1; // placeholder.
}
$master_field = $oFieldSet->getMasterField(); // this is the id of the master field.
if (!array_key_exists($master_field, $inputs)) {
return false; // no master field in the input.
}
// step 2: get the first parent, to get the ball rolling.
$sQuery = "SELECT * FROM $default->md_condition_table WHERE document_field_id = ? and metadata_lookup_id = ? ";
$aParams = array($master_field, $inputs[$master_field]);
$res = DBUtil::getOneResult(array($sQuery, $aParams));
if (PEAR::isError($res)) {
return false; // no value matched on the master field input, the rest MUST fail.
}
else {
unset($free_field_ids[$master_field]); // master is no longer free.
$rule_id = $res["id"];
$parent_conditions[$rule_id] = 1;
unset($inputs[$master_field]);
}
$default->log->debug('validatePath: parent_conditions '.print_r($parent_conditions,true));
while (count($inputs) != 0) { // we'll return out inside here if necessary.
// check for items in inputs, with parents in parent_conditions.
// $testStr = "";
// $testarr = array();
// for ($i=0; $i<3; $i++) {
// $testarr[] = "( ? )";
// }
// $testStr = "(".join(" OR ", $testarr).")";
// return $testStr;
// we need something like "parent_conditions IN (1,2,3) AND ((f=1 AND v=2) OR (f=2 AND v=5) OR (f=4 AND v=7))
$sParentClause = "md_chain.parent_condition IN (";
$aInputParts = array();
for ($i=0; $i $lookid) {
$aInputs[] = $fid;
$aInputs[] = $lookid;
$aInputParts[] = '(md_cond.document_field_id = ? AND md_cond.metadata_lookup_id = ?)';
}
$sInputs = join(" OR ", $aInputParts);
$sInputs = '(' . $sInputs . ')';
$default->log->debug('validatePath: parent_conditions '.print_r($parent_conditions,true));
$sFieldClause = "md_cond.document_field_id IN (";
for ($i=0; $ilog->debug('validatePath: sParentClause '.print_r($sParentClause,true));
$sWhere = KTUtil::whereToString(array(array($sParentClause, array_keys($parent_conditions)), array($sInputs, $aInputs)));
$sQuery = "SELECT md_cond.id as rule_id, md_cond.document_field_id AS field_id FROM $default->md_condition_table AS md_cond LEFT JOIN $default->md_condition_chain_table AS md_chain ON (md_cond.id = md_chain.child_condition) WHERE ";
$default->log->debug('validatePath: '.print_r(array($sQuery . $sWhere[0], $sWhere[1]),true));
$res = DBUtil::getResultArray(array($sQuery . $sWhere[0], $sWhere[1]));
if (PEAR::isError($res)) {
return false;
}
// if there's anything is $res, its a match (must be - we can't have crossed chains.)
if (count($res) == 0) {
return false; // fail - no matches from inputs against parent_conditions.
} else {
// we must have a match - MAY have multiple matches.
foreach ($res as $aRow) {
$default->log->debug('validatePath: output_row '.print_r($aRow,true));
$parent_conditions[$aRow["rule_id"]] = 1; // add this as a possible parent condition.
unset($free_field_ids[$aRow["field_id"]]); // no longer free
unset($inputs[$aRow["field_id"]]); // no longer an un-processed input, so reduce the input-count.
}
}
}
// ok: we got this far, and have run out of inputs without running out of matches.
// IF we're looking for a partial match, and still have free fields, return the set of free-and-parent matches.
// OTHERWISE if we have free fields, fail
// finally, pass the input as valid.
if (($bPartial === true) and (count($free_field_ids) > 0)) {
// generate the set of matches for free_fields with appropriate parents.
// UNFORTUNATELY, there is no "nice" way to do this.
// Wax On. Wax Off.
$sParentClause = "md_chain.parent_condition IN (";
for ($i=0; $ilog->debug('validatePath: parent_conditions '.print_r($parent_conditions,true));
$sFieldClause = "md_cond.document_field_id IN (";
for ($i=0; $ilog->debug('validatePath: sParentClause '.print_r($sParentClause,true));
$aWhere = KTUtil::whereToString(array(array($sParentClause, array_keys($parent_conditions)), array($sFieldClause,array_keys($free_field_ids))));
$sQuery = "SELECT md_cond.document_field_id AS document_field_id, md_cond.metadata_lookup_id AS val, md_lookup.name as name FROM $default->md_condition_table AS md_cond LEFT JOIN $default->md_condition_chain_table AS md_chain ON (md_cond.id = md_chain.child_condition) LEFT JOIN $default->metadata_table AS md_lookup ON (md_cond.metadata_lookup_id = md_lookup.id) WHERE ";
$default->log->debug('validatePath: sParentClause '.print_r(array($sQuery . $aWhere[0], $aWhere[1]), true));
$sOrderClause = " ORDER BY document_field_id ASC, name ASC";
return DBUtil::getResultArray(array($sQuery . $aWhere[0] . $sOrderClause, $aWhere[1])); // FIXME catch errors?
} else if (count($free_field_ids) != 0) {
return false; // incomplete - could actually catch this at the start.
} else {
return true; // note - this ALSO matches whenever $bPartial is true, but we have completed. UP THE STACK: true => valid and committable.
}
}
// FIXME: this need s to move into MDCondition.inc, or manageConditionalMetadata.php
// actually, this needs to die - its DEBUG only, really.
function do_createCondition() {
global $default;
$fieldset_id = KTUtil::arrayGet($_REQUEST, 'fieldset_id');
$parent_id = KTUtil::arrayGet($_REQUEST, 'parent_id');
$field_id = KTUtil::arrayGet($_REQUEST, 'field_id');
$lookup_id = KTUtil::arrayGet($_REQUEST, 'lookup_id');
$resObj = MDConditionNode::createFromArray(array(
"iFieldId" => $field_id,
"iLookupId" => $lookup_id,
));
$default->log->debug("CREATE_CONDITION_DEBUG: ".print_r($resObj,true));
$resObj2 = MDConditionChain::createFromArray(array(
"iParentCondition" => $parent_id, // may be null.
"iChildCondition" => $resObj->getId(),
));
$default->log->debug("CREATE_CONDITION_DEBUG: ".print_r($resObj2,true));
}
}
$oDispatcher = new HandleConditionalDispatcher();
$oDispatcher->dispatch();
?>