diff --git a/lib/metadata/fieldsetregistry.inc.php b/lib/metadata/fieldsetregistry.inc.php index 7baeab1..4475318 100644 --- a/lib/metadata/fieldsetregistry.inc.php +++ b/lib/metadata/fieldsetregistry.inc.php @@ -97,12 +97,53 @@ class KTFieldsetRegistry { // FIXME delegate. $oFieldset =& $fieldsetOrType; - if ($oFieldset->getIsConditional()) { - return PEAR::raiseError(_kt("Conditional Fieldsets are not yet implemented")); - } else { + $widgets = array(); $fields = $oFieldset->getFields(); + if ($oFieldset->getIsConditional()) { + $iMasterId = $oFieldset->getMasterFieldId(); + + $oMasterField = DocumentField::get($iMasterId); + + $newfields = array(); + $newfields[] = $oMasterField; + foreach($fields as $oField) { + if($oField->getId() != $iMasterId) { + $newfields[] = $oField; + } + } + + foreach ($newfields as $oField) { + $fname = 'metadata_' . $oField->getId(); + $value = null; + + if (!is_null($oDocument)) { + $oFL = DocumentFieldLink::getByDocumentAndField($oDocument, $oField); + if (!is_null($oFL) && (!PEAR::isError($oFL))) { + $value = $oFL->getValue(); + } + } + + $widgets[] = $this->oWF->get('ktcore.widgets.conditionalselection', + array( + 'label' => $oField->getName(), + 'required' => $oField->getIsMandatory(), + 'name' => $fname, + 'value' => $value, + 'description' => $oField->getDescription(), + 'vocab' => MetaData::getEnabledByDocumentField($oField), + 'id_method' => 'getName', + 'label_method' => 'getName', + 'unselected_label' => _kt("No selection."), + 'simple_select' => false, + 'master' => ($oField->getId() == $iMasterId), + 'masterid' => $iMasterId, + 'fieldset' => $oFieldset->getId(), + 'field' => $oField->getId(), + )); + } + } else { foreach ($fields as $oField) { $fname = 'metadata_' . $oField->getId(); @@ -165,13 +206,17 @@ class KTFieldsetRegistry { } } - return array($this->oWF->get('ktcore.widgets.fieldset',array( + + } + + return array($this->oWF->get('ktcore.widgets.fieldset', + array( 'label' => $oFieldset->getName(), 'description' => $oFieldset->getDescription(), 'name' => $sContainerName, 'widgets' => $widgets, ))); - } + } @@ -184,7 +229,26 @@ class KTFieldsetRegistry { // FIXME delegate. $oFieldset =& $fieldsetOrType; if ($oFieldset->getIsConditional()) { - return PEAR::raiseError(_kt("Conditional Fieldsets are not yet implemented")); + $validators = array(); + $fields = $oFieldset->getFields(); + + if ($bIncludeAuto) { + $widgets = $this->widgetsForFieldset($oFieldset, $sContainerName, $sDocument); + $validators = kt_array_merge($validators, $widgets[0]->getValidators()); + } + + foreach ($fields as $oField) { + $fname = 'metadata_' . $oField->getId(); + + // Change back to 'membership' + $validators[] = $this->oVF->get('ktcore.validators.membership', + array( + 'test' => $fname, + 'output' => $fname, + 'vocab' => MetaData::getEnabledValuesByDocumentField($oField), + 'id_method' => 'getName', + )); + } } else { $validators = array(); $fields = $oFieldset->getFields(); @@ -243,13 +307,14 @@ class KTFieldsetRegistry { } } - return array($this->oVF->get('ktcore.validators.fieldset',array( + } + return array($this->oVF->get('ktcore.validators.fieldset', + array( 'test' => $sContainerName, 'output' => $sContainerName, 'validators' => $validators, ))); } } -} ?> diff --git a/plugins/ktcore/KTCorePlugin.php b/plugins/ktcore/KTCorePlugin.php index 3e4b597..5e59514 100644 --- a/plugins/ktcore/KTCorePlugin.php +++ b/plugins/ktcore/KTCorePlugin.php @@ -181,6 +181,8 @@ class KTCorePlugin extends KTPlugin { $this->registerWidget('KTDescriptorSelectionWidget', 'ktcore.widgets.descriptorselection', 'KTWidgets.php'); $this->registerWidget('KTCoreFolderCollectionWidget', 'ktcore.widgets.foldercollection', 'KTWidgets.php'); + $this->registerWidget('KTCoreConditionalSelectionWidget', 'ktcore.widgets.conditionalselection', 'KTWidgets.php'); + $this->registerPage('collection', 'KTCoreCollectionPage', 'KTWidgets.php'); $this->registerPage('notifications', 'KTNotificationOverflowPage', 'KTMiscPages.php'); diff --git a/plugins/ktcore/KTWidgets.php b/plugins/ktcore/KTWidgets.php index ce22ff3..3226c47 100644 --- a/plugins/ktcore/KTWidgets.php +++ b/plugins/ktcore/KTWidgets.php @@ -767,4 +767,160 @@ class KTCoreCollectionPage extends KTStandardDispatcher { } -?> + +// based on the selection widget, this carries a mapping array, +// which is converted to JSON and inserted into the output. javascript +// enforces the various relationships between conditional fields. + +class KTCoreConditionalSelectionWidget extends KTCoreSelectionWidget { + var $sNamespace = 'ktcore.widgets.conditionalselection'; + + var $sIdMethod; + var $sLabelMethod; + + var $bIsMaster; + var $bMappings; + + function _getFieldIdForMetadataId($iMetadata) { + $sTable = 'metadata_lookup'; + $sQuery = "SELECT document_field_id FROM " . $sTable . " WHERE id = ?"; + $aParams = array($iMetadata); + + $res = DBUtil::getOneResultKey(array($sQuery, $aParams), 'document_field_id'); + if (PEAR::isError($res)) { + return false; + } + return $res; + } + + + function configure($aOptions) { + $res = parent::configure($aOptions); + if (PEAR::isError($res)) { + return $res; + } + + $this->sIdMethod = KTUtil::arrayGet($aOptions, 'id_method', 'getId'); + $this->sLabelMethod = KTUtil::arrayGet($aOptions, 'label_method'); + if (empty($this->sLabelMethod)) { + return PEAR::raiseError(_kt('No label method specified.')); + } + $existing_entities = (array) KTUtil::arrayGet($aOptions, 'existing_entities'); + + if (empty($this->value)) { + $this->value = array(); + foreach ($existing_entities as $oEntity) { + $this->value[] = call_user_func(array(&$oEntity, $this->sIdMethod)); + } + } + + $this->iField = KTUtil::arrayGet($aOptions, 'field'); + $this->iMasterId = KTUtil::arrayGet($aOptions, 'masterid'); + + // if we're the master, we have to build the dependancy array and store it as JSON + // also, include the javascript + if(KTUtil::arrayGet($aOptions, 'master', false)) { + $this->bMaster = true; + $this->aJavascript = array('resources/js/conditional_selection.js'); + + $oFieldset = KTFieldset::get(KTUtil::arrayGet($aOptions, 'fieldset')); + $aLookups = array(); + $aConnections = array(); + + foreach($oFieldset->getFields() as $oField) { + $c = array(); + + foreach($oField->getEnabledValues() as $oMetadata) { + $a = array(); + // print '
';
+
+		    $nvals = KTMetadataUtil::getNextValuesForLookup($oMetadata->getId());
+		    if($nvals) {
+			foreach($nvals as $i=>$aVals) {
+			    $a = array_merge($a, $aVals);
+			    
+			    foreach($aVals as $id) {
+			      $field = $this->_getFieldIdForMetadataId($id);
+			      // print 'id ' . $id . ' is in field ' . $field . "
"; + if(!in_array($field, $c)) { + $c[] = $field; + } + } + } + } + + $aLookups[$oMetadata->getId()] = $a; + } + $aConnections[$oField->getId()] = $c; + } + + //exit(0); + + $oJSON = new Services_JSON; + $this->sLookupsJSON = $oJSON->encode($aLookups); + $this->sConnectionsJSON = $oJSON->encode($aConnections); + } + + + $new_vocab = array(); + foreach ($this->aVocab as $oEntity) { + $id = call_user_func(array(&$oEntity, $this->sIdMethod)); + $label = call_user_func(array(&$oEntity, $this->sLabelMethod)); + $new_vocab[$id] = array($label, $oEntity->getId()); + } + $this->aVocab = $new_vocab; + } + + function getWidget() { + $bHasErrors = false; + if (count($this->aErrors) != 0) { $bHasErrors = true; } + + $this->sTemplate = 'ktcore/forms/widgets/conditional_selection'; + + $oTemplating =& KTTemplating::getSingleton(); + $oTemplate = $oTemplating->loadTemplate($this->sTemplate); + + $unselected = KTUtil::arrayGet($this->aOptions, 'unselected_label'); + if (!empty($unselected)) { + $vocab = array(); + $vocab[] = $unselected; + foreach ($this->aVocab as $k => $v) { + $vocab[$k] = $v; + } + $this->aVocab = $vocab; + if (empty($this->value)) { + $this->value = '0'; + } + } + + if ($this->bMulti) { + $this->_valuesearch = array(); + $value = (array) $this->value; + foreach ($value as $v) { + $this->_valuesearch[$v] = true; + } + } + + $aTemplateData = array( + 'context' => $this, + 'name' => $this->sName, + 'has_id' => ($this->sId !== null), + 'id' => $this->sId, + 'has_value' => ($this->value !== null), + 'value' => $this->value, + 'options' => $this->aOptions, + 'vocab' => $this->aVocab, + 'lookups' => $this->sLookupsJSON, + 'connections' => $this->sConnectionsJSON, + 'master' => $this->bMaster, + 'masterid' => $this->iMasterId, + 'field' => $this->iField, + ); + return $oTemplate->render($aTemplateData); + } + + + +} + + diff --git a/plugins/ktcore/admin/fieldsets/conditional.inc.php b/plugins/ktcore/admin/fieldsets/conditional.inc.php index 6c23ecb..31065f2 100644 --- a/plugins/ktcore/admin/fieldsets/conditional.inc.php +++ b/plugins/ktcore/admin/fieldsets/conditional.inc.php @@ -414,6 +414,16 @@ ordering!"); $oField = $data['master_field']; + // remove all existing behaviors + $aFieldIds = array(); + foreach($this->oFieldset->getFields() as $i) { + $aFieldIds[] = $i->getId(); + } + + $sTable = KTUtil::getTableName('field_behaviours'); + $aQuery = array("DELETE FROM $sTable WHERE field_id IN (" . DBUtil::paramArray($aFieldIds) . ")", $aFieldIds); + $res = DBUtil::runQuery($aQuery); + $res = KTMetadataUtil::removeFieldOrdering($this->oFieldset); $this->oFieldset->setMasterFieldId($oField->getId()); $res = $this->oFieldset->update(); diff --git a/resources/js/conditional_selection.js b/resources/js/conditional_selection.js new file mode 100755 index 0000000..df27143 --- /dev/null +++ b/resources/js/conditional_selection.js @@ -0,0 +1,172 @@ +// 'lookups' and 'connections' are produced by the master conditional widget +var NOSELECTION = 'No selection.'; + +function ConditionalSelection() { +} + +function in_array(a, val) { + if(!a.length) { + return; + } + for(var i=0;i +var lookups_{$masterid} = {$lookups}; +var connections_{$masterid} = {$connections}; + +{/if} + + +{if empty($vocab)} +
{$context->sEmptyMessage}
+{else} + +{/if} diff --git a/templates/ktcore/metadata/conditional/conditional_admin_overview.smarty b/templates/ktcore/metadata/conditional/conditional_admin_overview.smarty index 17aeb48..9e7a5eb 100644 --- a/templates/ktcore/metadata/conditional/conditional_admin_overview.smarty +++ b/templates/ktcore/metadata/conditional/conditional_admin_overview.smarty @@ -29,30 +29,6 @@ values in the other fields. Only lookup fields can be added to

-

- {i18n}Rename Behaviours{/i18n} - {i18n}Rename Behaviours{/i18n} -

- -{if $oFieldset->getIsComplex()} -

{i18n}The fieldset is currently designated as Complex.{/i18n} {i18n}Changing the conditional type set will remove all existing field -ordering!{/i18n}

- - -

{i18n}Change to simple{/i18n} -{i18n}Change to simple{/i18n}

- -{else} - -

{i18n}The fieldset is currently designated as Simple.{/i18n}

- -

{i18n}Change to complex{/i18n} -{i18n}Change to complex{/i18n}

- -{/if} -
diff --git a/templates/ktcore/metadata/conditional/manageConditional.smarty b/templates/ktcore/metadata/conditional/manageConditional.smarty index c878bc5..3bab28f 100644 --- a/templates/ktcore/metadata/conditional/manageConditional.smarty +++ b/templates/ktcore/metadata/conditional/manageConditional.smarty @@ -1,16 +1,11 @@

{i18n}Manage conditional fieldset{/i18n}

{i18n}Conditional fieldsets allow you to restrict the options -a user has for values in some fields based on the values in other fields. There -are two kinds of conditional fieldsets: Simple and Complex -. Simple fieldsets should be sufficient for most things: they allow you to say that +a user has for values in some fields based on the values in other fields, allowing you to say that the values of one field are restricted to a certain subset of values if another field has a specific value. For example, you could say that if the field "Street" is "Jeffrey", then the field "Residents" must be one of "Jones","Smith" or "Friedman".{/i18n}

-

{i18n}Complex fieldsets allow you to give far more detailed structure to -your information: The value of "Residents" can depend not only on "Street", but on -how the user was allowed to select the specific street (given another field).{/i18n}

{* don't show warnings until the basics are done. *} @@ -42,29 +37,6 @@ to complete{/i18n}: {$sIncomplete}

{i18n}Conditional type{/i18n}

-{if $oFieldset->getIsComplex()} -

{i18n}The fieldset is currently designated as Complex{/i18n}

- -{if ($oMasterField && empty($free_fields))}

{i18n}Manage -complex conditional{/i18n}

{/if} - -
- - - -
- -{else} - -

{i18n}The fieldset is currently designated as Simple{/i18n}

- -{if ($oMasterField && empty($free_fields))}

{i18n}Manage simple conditional{/i18n} -

-{/if}