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))}getId()}">{i18n}Manage
-complex conditional{/i18n}
{/if}
-
-
-
-{else}
-
-{i18n}The fieldset is currently designated as Simple{/i18n}
-
-{if ($oMasterField && empty($free_fields))}
-{/if}