Commit 81251662294d9b6e0fef1c39035e92cbe8545417
1 parent
36868ecb
Checkin of the tree-like metadata, basics of fieldsets and basics of the conditional metadata tree.
git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@3636 c91229c3-7414-0410-bfa2-8a42b809f60b
Showing
12 changed files
with
1044 additions
and
172 deletions
config/siteMap.inc
| ... | ... | @@ -138,6 +138,8 @@ $default->siteMap->addPage("docLinkManagement", "/presentation/lookAndFeel/knowl |
| 138 | 138 | $default->siteMap->addPage("manageHelp", "/presentation/lookAndFeel/knowledgeTree/administration/help/manageHelp.php", "Administration", SysAdmin, _("Help Administration"), true, 17); |
| 139 | 139 | |
| 140 | 140 | $default->siteMap->addPage("managePermissions", "/presentation/lookAndFeel/knowledgeTree/administration/permissions/managePermissions.php", "Administration", SysAdmin, _("Permissions Administration"), true, 18); |
| 141 | +$default->siteMap->addPage("manageFieldsets", "/presentation/lookAndFeel/knowledgeTree/administration/fieldsetmanagement/manageFieldsets.php", "Administration", SysAdmin, _("Fieldsets Administration"), true, 19); | |
| 142 | +$default->siteMap->addPage("manageLookupTrees", "/presentation/lookAndFeel/knowledgeTree/administration/docfieldmanagement/manageLookupTrees.php", "Administration", SysAdmin, _("Lookup Tree Administration"), true, 20); | |
| 141 | 143 | |
| 142 | 144 | $default->siteMap->addSectionColour("Administration", "th", "056DCE"); |
| 143 | 145 | $default->siteMap->addSectionColour("Administration", "td", "6699FF"); | ... | ... |
config/tableMappings.inc
| ... | ... | @@ -28,6 +28,8 @@ $default->sessions_table = "active_sessions"; |
| 28 | 28 | $default->data_types_table ="data_types"; |
| 29 | 29 | // document type fields |
| 30 | 30 | $default->document_fields_table = "document_fields"; |
| 31 | +// document type fields | |
| 32 | +$default->document_fieldset_table = "document_fieldsets"; | |
| 31 | 33 | // links document |
| 32 | 34 | $default->document_fields_link_table = "document_fields_link"; |
| 33 | 35 | // document subscriptions |
| ... | ... | @@ -38,6 +40,8 @@ $default->transaction_types_table = "document_transaction_types_lookup"; |
| 38 | 40 | $default->document_transactions_table = "document_transactions"; |
| 39 | 41 | // links document types to document type fields |
| 40 | 42 | $default->document_type_fields_table = "document_type_fields_link"; |
| 43 | +// links document types to document type fields | |
| 44 | +$default->document_type_fieldsets_table = "document_type_fieldsets_link"; | |
| 41 | 45 | // document type information |
| 42 | 46 | $default->document_types_table = "document_types_lookup"; |
| 43 | 47 | // stores documents |
| ... | ... | @@ -122,4 +126,8 @@ $default->permission_descriptor_groups_table = "permission_descriptor_groups"; |
| 122 | 126 | $default->permission_lookups_table = "permission_lookups"; |
| 123 | 127 | $default->permission_lookup_assignments_table = "permission_lookup_assignments"; |
| 124 | 128 | $default->groups_groups_table = "groups_groups_link"; |
| 129 | +$default->metadata_treenode_table = "metadata_lookup_tree"; | |
| 130 | +$default->metadata_condition_table = "metadata_lookup_condition"; | |
| 131 | +$default->md_condition_table = "metadata_lookup_condition"; | |
| 132 | +$default->md_condition_chain_table = "metadata_lookup_condition_chain"; | |
| 125 | 133 | ?> | ... | ... |
graphics/minus.png
0 → 100644
185 Bytes
graphics/plus.png
0 → 100644
191 Bytes
lib/documentmanagement/DocumentField.inc
| ... | ... | @@ -28,125 +28,39 @@ require_once("$default->fileSystemRoot/lib/documentmanagement/DocumentType.inc") |
| 28 | 28 | class DocumentField extends KTEntity { |
| 29 | 29 | |
| 30 | 30 | /** primary key value */ |
| 31 | - var $iId; | |
| 32 | - /** document field name */ | |
| 31 | + var $iId = -1; | |
| 33 | 32 | var $sName; |
| 34 | - /** document field data type */ | |
| 35 | 33 | var $sDataType; |
| 36 | - /** is_generic */ | |
| 37 | 34 | var $bIsGeneric; |
| 38 | - /**has lookup*/ | |
| 39 | 35 | var $bHasLookup; |
| 40 | - | |
| 41 | - /** | |
| 42 | - * Default constructor | |
| 43 | - * | |
| 44 | - * @param Name of document field | |
| 45 | - * @param Document field data type | |
| 46 | - * | |
| 47 | - */ | |
| 48 | - function DocumentField($sNewName, $sNewDataType, $bNewIsGeneric, $bNewHasLookup) { | |
| 49 | - //object not created yet | |
| 36 | + var $iParentFieldset; | |
| 37 | + var $bHasLookupTree; | |
| 38 | + | |
| 39 | + // FIXME deprecate constructor use. Use DocumentField::createFromArray instead. | |
| 40 | + function DocumentField($sNewName = null, $sNewDataType = null, $bNewIsGeneric = null, $bNewHasLookup = null, $iParentFieldset = null, $bHasLookupTree = null) { | |
| 41 | + | |
| 50 | 42 | $this->iId = -1; |
| 51 | 43 | $this->sName = $sNewName; |
| 52 | 44 | $this->sDataType = $sNewDataType; |
| 53 | 45 | $this->bIsGeneric = $bNewIsGeneric; |
| 54 | 46 | $this->bHasLookup = $bNewHasLookup; |
| 55 | - | |
| 56 | - } | |
| 57 | - | |
| 58 | - /** | |
| 59 | - * Get the document field's primary key value | |
| 60 | - * | |
| 61 | - * @return int document field's primary key value | |
| 62 | - * | |
| 63 | - */ | |
| 64 | - function getID() { | |
| 65 | - return $this->iId; | |
| 47 | + $this->iParentFieldset = $iParentFieldset; | |
| 48 | + $this->bHasLookupTree = $bHasLookupTree; | |
| 66 | 49 | } |
| 67 | 50 | |
| 68 | - /** | |
| 69 | - * Get the document field's name | |
| 70 | - * | |
| 71 | - * @return String document field's name | |
| 72 | - * | |
| 73 | - */ | |
| 74 | - function getName() { | |
| 75 | - return $this->sName; | |
| 76 | - } | |
| 77 | - | |
| 78 | - /** | |
| 79 | - * Set the document field's name | |
| 80 | - * | |
| 81 | - * @param Document field's new name | |
| 82 | - * | |
| 83 | - */ | |
| 84 | - function setName($sNewValue) { | |
| 85 | - $this->sName = $sNewValue; | |
| 86 | - } | |
| 87 | - | |
| 88 | - /** | |
| 89 | - * Get the document field's data type | |
| 90 | - * | |
| 91 | - * @return String document field's data type | |
| 92 | - * | |
| 93 | - */ | |
| 94 | - function getDataType() { | |
| 95 | - return $this->sDataType; | |
| 96 | - } | |
| 97 | - | |
| 98 | - /** | |
| 99 | - * Set the document field's data type | |
| 100 | - * | |
| 101 | - * @param Document field's new data type | |
| 102 | - * | |
| 103 | - */ | |
| 104 | - function setDataType($sNewValue) { | |
| 105 | - $this->sDataType = $sNewValue; | |
| 106 | - } | |
| 107 | - | |
| 108 | - | |
| 109 | - /** | |
| 110 | - * Get the document field's generic or not | |
| 111 | - * | |
| 112 | - * @return String document field's data type | |
| 113 | - * | |
| 114 | - */ | |
| 115 | - function getIsGeneric() { | |
| 116 | - return $this->bIsGeneric; | |
| 117 | - } | |
| 118 | - | |
| 119 | - /** | |
| 120 | - * Set the document field's genericness | |
| 121 | - * | |
| 122 | - * @param Document field's new data type | |
| 123 | - * | |
| 124 | - */ | |
| 125 | - function setIsGeneric($sNewValue) { | |
| 126 | - $this->bIsGeneric = $sNewValue; | |
| 127 | - } | |
| 128 | - | |
| 129 | - | |
| 130 | - | |
| 131 | - /** | |
| 132 | - * Get the document field's lookup or not | |
| 133 | - * | |
| 134 | - * @return String document field's data type | |
| 135 | - * | |
| 136 | - */ | |
| 137 | - function getHasLookup() { | |
| 138 | - return $this->bHasLookup; | |
| 139 | - } | |
| 140 | - | |
| 141 | - /** | |
| 142 | - * Set the document field's lookup | |
| 143 | - * | |
| 144 | - * @param Document field's new data type | |
| 145 | - * | |
| 146 | - */ | |
| 147 | - function setHasLookup($sNewValue) { | |
| 148 | - $this->bHasLookup = $sNewValue; | |
| 149 | - } | |
| 51 | + function getID() { return $this->iId; } | |
| 52 | + function getName() { return $this->sName; } | |
| 53 | + function setName($sNewValue) { $this->sName = $sNewValue; } | |
| 54 | + function getDataType() { return $this->sDataType; } | |
| 55 | + function setDataType($sNewValue) { $this->sDataType = $sNewValue; } | |
| 56 | + function getIsGeneric() { return $this->bIsGeneric; } | |
| 57 | + function setIsGeneric($sNewValue) { $this->bIsGeneric = $sNewValue; } | |
| 58 | + function getHasLookup() { return $this->bHasLookup; } | |
| 59 | + function setHasLookup($iNewValue) { $this->bHasLookup = $iNewValue; } | |
| 60 | + function getParentFieldset() { return $this->iParentFieldset; } | |
| 61 | + function setParentFieldset($iNewValue) { $this->iParentFieldset = $iNewValue; } | |
| 62 | + function getHasLookupTree() { return $this->bHasLookupTree; } | |
| 63 | + function setHasLookupTree($iNewValue) { $this->bHasLookupTree = KTUtil::anyToBool($iNewValue); } | |
| 150 | 64 | |
| 151 | 65 | function _fieldValues () { |
| 152 | 66 | return array( |
| ... | ... | @@ -154,6 +68,8 @@ class DocumentField extends KTEntity { |
| 154 | 68 | 'data_type' => $this->sDataType, |
| 155 | 69 | 'is_generic' => KTUtil::anyToBool($this->bIsGeneric), |
| 156 | 70 | 'has_lookup' => KTUtil::anyToBool($this->bHasLookup), |
| 71 | + 'parent_fieldset' => $this->iParentFieldset, | |
| 72 | + 'has_lookuptree' => KTUtil::anyToBool($this->bHasLookupTree), | |
| 157 | 73 | ); |
| 158 | 74 | } |
| 159 | 75 | |
| ... | ... | @@ -161,7 +77,16 @@ class DocumentField extends KTEntity { |
| 161 | 77 | global $default; |
| 162 | 78 | return $default->document_fields_table; |
| 163 | 79 | } |
| 80 | + | |
| 81 | + function &getList($sWhereClause = null) { | |
| 82 | + return KTEntityUtil::getList2('DocumentField', $sWhereClause); | |
| 83 | + } | |
| 84 | + | |
| 85 | + function &createFromArray($aOptions) { | |
| 86 | + return KTEntityUtil::createFromArray('DocumentField', $aOptions); | |
| 87 | + } | |
| 164 | 88 | |
| 89 | + // FIXME remove &get and rather use the autogenerated version. | |
| 165 | 90 | /** |
| 166 | 91 | * Static function. |
| 167 | 92 | * Given a document_fields primary key it will create a |
| ... | ... | @@ -178,6 +103,8 @@ class DocumentField extends KTEntity { |
| 178 | 103 | if ($sql->next_record()) { |
| 179 | 104 | $oDocumentField = & new DocumentField($sql->f("name"), $sql->f("data_type"), (bool)$sql->f("is_generic"), (bool)$sql->f("has_lookup")); |
| 180 | 105 | $oDocumentField->iId = $sql->f("id"); |
| 106 | + $oDocumentField->iParentFieldset = $sql->f("parent_fieldset"); | |
| 107 | + $oDocumentField->bHasLookupTree = (bool)$sql->f("has_lookuptree"); | |
| 181 | 108 | return $oDocumentField; |
| 182 | 109 | } |
| 183 | 110 | $_SESSION["errorMessage"] = $lang_err_object_not_exist . "id = " . $iDocumentID . " table = $default->document_fields_table"; |
| ... | ... | @@ -187,16 +114,6 @@ class DocumentField extends KTEntity { |
| 187 | 114 | return false; |
| 188 | 115 | } |
| 189 | 116 | |
| 190 | - /** | |
| 191 | - * Static- Get a list of document fieldss; | |
| 192 | - * | |
| 193 | - * @param String Where clause (not required) | |
| 194 | - * | |
| 195 | - * @return Array array of DocumentField objects, false otherwise | |
| 196 | - */ | |
| 197 | - function getList($sWhereClause = null) { | |
| 198 | - return KTEntityUtil::getList(DocumentField::_table(), 'DocumentField', $sWhereClause); | |
| 199 | - } | |
| 200 | 117 | |
| 201 | 118 | /** |
| 202 | 119 | * Returns the DocumentTypes mapped to this document field | ... | ... |
lib/documentmanagement/DocumentFieldSet.inc
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +require_once("$default->fileSystemRoot/lib/documentmanagement/DocumentType.inc"); | |
| 4 | +require_once(KT_LIB_DIR . "/ktentity.inc"); | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * class DocumentFieldSet | |
| 8 | + * | |
| 9 | + * Represents the basic grouping of fields into a fieldset. | |
| 10 | + */ | |
| 11 | +class DocumentFieldSet extends KTEntity { | |
| 12 | + | |
| 13 | + /** primary key value */ | |
| 14 | + var $iId = -1; | |
| 15 | + /** document fieldset name */ | |
| 16 | + var $sName; | |
| 17 | + /** document fieldset namespace */ | |
| 18 | + var $sName; | |
| 19 | + /** document fieldset mandatory flag*/ | |
| 20 | + var $bMandatory; | |
| 21 | + var $bIsConditional; | |
| 22 | + var $iMasterField; | |
| 23 | + | |
| 24 | + var $_bUsePearError = true; | |
| 25 | + | |
| 26 | + function getId() { return $this->iId; } | |
| 27 | + function getName() { return $this->sName; } | |
| 28 | + | |
| 29 | + function setName($sNewValue) { $this->sName = $sNewValue; } | |
| 30 | + function getNamespace() { return $this->sNamespace; } | |
| 31 | + function setNamespace($sNewcreValue) { $this->sNamespace = $sNewValue; } | |
| 32 | + function getMandatory() { return $this->bMandatory; } | |
| 33 | + function setMandatory($bNewValue) { $this->bMandatory = $bNewValue; } | |
| 34 | + function getIsConditional () { return $this->bIsConditional; } | |
| 35 | + function setIsConditional ($bNewValue) { $this->bIsConditional = $bNewValue; } | |
| 36 | + function getMasterField () { return $this->bIsConditional; } | |
| 37 | + function setMasterField ($iNewValue) { $this->bIsConditional = $iNewValue; } | |
| 38 | + | |
| 39 | + var $_aFieldToSelect = array( | |
| 40 | + "iId" => "id", | |
| 41 | + "sName" => "name", | |
| 42 | + "sNamespace" => "namespace", | |
| 43 | + "bMandatory" => "mandatory", | |
| 44 | + "bIsConditional" => "is_conditional", | |
| 45 | + "iMasterField" => "master_field", | |
| 46 | + ); | |
| 47 | + | |
| 48 | + // returns TRUE if all children are lookup enabled, false otherwise. | |
| 49 | + function canBeMadeConditional() { | |
| 50 | + if ($this->getIsConditional()) { | |
| 51 | + return false; | |
| 52 | + } | |
| 53 | + | |
| 54 | + // DEBUG | |
| 55 | + return false; | |
| 56 | + } | |
| 57 | + | |
| 58 | + function _fieldValues () { | |
| 59 | + return array( | |
| 60 | + 'name' => $this->sName, | |
| 61 | + 'namespace' => $this->sNamespace, | |
| 62 | + 'mandatory' => $this->bMandatory, | |
| 63 | + 'is_conditional' => KTUtil::anyToBool($this->bMandatory), | |
| 64 | + 'master_field' => $this->iMasterField, | |
| 65 | + ); | |
| 66 | + } | |
| 67 | + | |
| 68 | + function _table () { | |
| 69 | + global $default; | |
| 70 | + return $default->document_fieldset_table; | |
| 71 | + } | |
| 72 | + | |
| 73 | + // Static function | |
| 74 | + function &get($iId) { return KTEntityUtil::get('DocumentFieldSet', $iId); } | |
| 75 | + function &getList($sWhereClause = null) { return KTEntityUtil::getList2('DocumentFieldSet', $sWhereClause); } | |
| 76 | + function &createFromArray($aOptions) { return KTEntityUtil::createFromArray('DocumentFieldSet', $aOptions); } | |
| 77 | +} | |
| 78 | + | |
| 79 | +?> | ... | ... |
lib/documentmanagement/MDCondition.inc
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +require_once(KT_LIB_DIR . "/ktentity.inc"); | |
| 4 | + | |
| 5 | +require_once(KT_LIB_DIR . "/documentmanagement/DocumentField.inc"); | |
| 6 | +require_once(KT_LIB_DIR . "/documentmanagement/MetaData.inc"); | |
| 7 | + | |
| 8 | +class MDConditionNode extends KTEntity { | |
| 9 | + /** boilerplate DB code. */ | |
| 10 | + /** primary key */ | |
| 11 | + var $iId = -1; | |
| 12 | + var $iFieldId; | |
| 13 | + var $sName; | |
| 14 | + var $iParentNode; | |
| 15 | + | |
| 16 | + var $_aFieldToSelect = array( | |
| 17 | + "iId" => "id", | |
| 18 | + "iFieldId" => "document_field_id", | |
| 19 | + "iLookupId" => "metadata_lookup_id", | |
| 20 | + "sName" => "name", // this can be null - if it isn't we are looking at a rooted subtree | |
| 21 | + ); | |
| 22 | + | |
| 23 | + var $_bUsePearError = true; | |
| 24 | + | |
| 25 | + function getID() { return $this->iId; } | |
| 26 | + function setID($iId) { $this->iId = $iId; } | |
| 27 | + function getFieldId() { return $this->iFieldId; } | |
| 28 | + function setFieldId($iFieldId) { $this->iFieldId = $iFieldId; } | |
| 29 | + function getLookupId() { return $this->iLookupId; } | |
| 30 | + function setLookupId($iLookupId) { $this->$iLookupId = $iLookupId; } | |
| 31 | + | |
| 32 | + function _table () { | |
| 33 | + global $default; | |
| 34 | + return $default->metadata_condition_table; | |
| 35 | + } | |
| 36 | + | |
| 37 | + // Static Functions (dull) | |
| 38 | + function &get($iId) { return KTEntityUtil::get("MDConditionNode", $iId); } | |
| 39 | + function &createFromArray($aOptions) { return KTEntityUtil::createFromArray("MDConditionNode", $aOptions); } | |
| 40 | + function &getList($sWhereClause = null) { global $default; return KTEntityUtil::getList2("MDConditionNode", $sWhereClause); } | |
| 41 | + | |
| 42 | + /** end boilerplate. anything interesting goes below here. */ | |
| 43 | + | |
| 44 | +} | |
| 45 | + | |
| 46 | +class MDConditionChain extends KTEntity { | |
| 47 | + /** boilerplate DB code. */ | |
| 48 | + /** primary key */ | |
| 49 | + var $iId = -1; | |
| 50 | + var $iParentCondition; | |
| 51 | + var $iChildCondition; | |
| 52 | + | |
| 53 | + var $_aFieldToSelect = array( | |
| 54 | + "iId" => "id", | |
| 55 | + "iChildCondition" => "child_condition", | |
| 56 | + "iParentCondition" => "parent_condition", | |
| 57 | + ); | |
| 58 | + | |
| 59 | + var $_bUsePearError = true; | |
| 60 | + | |
| 61 | + function getID() { return $this->iId; } | |
| 62 | + function setID($iId) { $this->iId = $iId; } | |
| 63 | + function getParentConditionId() { return $this->iParentCondition; } | |
| 64 | + function setParentConditionId($iParentCondition) { $this->$iParentCondition = $iParentCondition; } | |
| 65 | + function getChildConditionId() { return $this->iChildCondition; } | |
| 66 | + function setChildConditionId($iChildCondition) { $this->$iChildCondition = $iParentCondition; } | |
| 67 | + | |
| 68 | + function _table () { | |
| 69 | + global $default; | |
| 70 | + return $default->md_condition_chain_table; | |
| 71 | + } | |
| 72 | + | |
| 73 | + // Static Functions (dull) | |
| 74 | + function &get($iId) { return KTEntityUtil::get("MDConditionChain", $iId); } | |
| 75 | + function &createFromArray($aOptions) { return KTEntityUtil::createFromArray("MDConditionChain", $aOptions); } | |
| 76 | + function &getList($sWhereClause = null) { global $default; return KTEntityUtil::getList2("MDConditionChain", $sWhereClause); } | |
| 77 | + | |
| 78 | + /** end boilerplate. anything interesting goes below here. */ | |
| 79 | + | |
| 80 | +} | ... | ... |
lib/documentmanagement/MDTree.inc
0 → 100644
| 1 | +<?php | |
| 2 | + | |
| 3 | +require_once(KT_LIB_DIR . "/ktentity.inc"); | |
| 4 | +//require_once("../../../../../config/dmsDefaults.php"); // gak. | |
| 5 | +require_once(KT_LIB_DIR . "/documentmanagement/DocumentField.inc"); | |
| 6 | +require_once(KT_LIB_DIR . "/documentmanagement/MetaData.inc"); | |
| 7 | + | |
| 8 | +class MDTreeNode extends KTEntity { | |
| 9 | + /** boilerplate DB code. */ | |
| 10 | + /** primary key */ | |
| 11 | + var $iId = -1; | |
| 12 | + var $iFieldId; | |
| 13 | + var $sName; | |
| 14 | + var $iParentNode; | |
| 15 | + | |
| 16 | + var $_aFieldToSelect = array( | |
| 17 | + "iId" => "id", | |
| 18 | + "iFieldId" => "document_field_id", | |
| 19 | + "sName" => "name", | |
| 20 | + "iParentNode" => "metadata_lookup_tree_parent", | |
| 21 | + ); | |
| 22 | + | |
| 23 | + var $_bUsePearError = true; | |
| 24 | + | |
| 25 | + function getID() { return $this->iId; } | |
| 26 | + function setID($iId) { $this->iId = $iId; } | |
| 27 | + function getFieldId() { return $this->iFieldId; } | |
| 28 | + function setFieldId($iFieldId) { $this->iFieldId = $iFieldId; } | |
| 29 | + function getName() { return $this ->sName; } | |
| 30 | + function setName($sName) { $this->sName = $sName; } | |
| 31 | + function getParentNode() { return $this->iParentNode; } | |
| 32 | + function setParentNode($iNode) { $this->iParentNode = $iParentNode; } | |
| 33 | + | |
| 34 | + function _table () { | |
| 35 | + global $default; | |
| 36 | + return $default->metadata_treenode_table; | |
| 37 | + } | |
| 38 | + | |
| 39 | + // Static Functions (dull) | |
| 40 | + function &get($iId) { return KTEntityUtil::get('MDTreeNode', $iId); } | |
| 41 | + function &createFromArray($aOptions) { return KTEntityUtil::createFromArray('MDTreeNode', $aOptions); } | |
| 42 | + function &getList($sWhereClause = null) { global $default; return KTEntityUtil::getList2('MDTreeNode', $sWhereClause); } | |
| 43 | + | |
| 44 | + /** end boilerplate. anything interesting goes below here. */ | |
| 45 | + | |
| 46 | +} | |
| 47 | + | |
| 48 | +/* simple class to encapsulate tree-as-a-whole behaviour. | |
| 49 | + NBM - should this move, be refactored? It certainly doesn't belong in the DB, | |
| 50 | + since its just an aggregate utility. | |
| 51 | +*/ | |
| 52 | +class MDTree { | |
| 53 | + var $contents = null; // private. | |
| 54 | + var $mapnodes = null; | |
| 55 | + var $root = null; | |
| 56 | + var $field_id; | |
| 57 | + var $lookups; | |
| 58 | + | |
| 59 | + function getRoot() { return $this->root; } | |
| 60 | + function getMapping() { return $this->mapnodes; } | |
| 61 | + function clear() { | |
| 62 | + $this->contents = null; | |
| 63 | + $this->mapnodes = null; | |
| 64 | + $this->root = null; | |
| 65 | + $this->lookups = null; | |
| 66 | + $this->field_id = null; | |
| 67 | + } | |
| 68 | + | |
| 69 | + /* function buildForField | |
| 70 | + * | |
| 71 | + * build a tree for a particular field instance. | |
| 72 | + * sets contents, so we can edit "stuff". | |
| 73 | + */ | |
| 74 | + function buildForField($iFieldId) | |
| 75 | + { | |
| 76 | + global $default; | |
| 77 | + // before we start, we need to check that | |
| 78 | + // the specified field exists and is organised into a tree. | |
| 79 | + $organisedField =& DocumentField::get($iFieldId); | |
| 80 | + if (PEAR::isError($organisedField) || ($organisedField === false)) { | |
| 81 | + $this->clear(); // make sure we don't get pollution. | |
| 82 | + return ; // and leave all null. WHY DOESN'T PHP HAVE EXCEPTIONS? | |
| 83 | + } | |
| 84 | + | |
| 85 | + if ($organisedField->getHasLookupTree() === false) { | |
| 86 | + $this->clear(); // make sure we don't get pollution. | |
| 87 | + return ; // not a tree-lookup. | |
| 88 | + } | |
| 89 | + // right. we are now ready to start with the treebuild. | |
| 90 | + // root is a virtual node (id: 0). | |
| 91 | + $this->field_id = $iFieldId; | |
| 92 | + $orderedTreeNodes =& MDTreeNode::getList('WHERE document_field_id = '.$iFieldId.' ORDER BY metadata_lookup_tree_parent, name ASC'); | |
| 93 | + | |
| 94 | + // since we have these nodes ordered by parent, we can perform a build | |
| 95 | + // we can build: | |
| 96 | + // $this->mapnodes [node_id => node] | |
| 97 | + // $this->root [node_id => subtree_root_arr] | |
| 98 | + // $this->contents [node_id => subtree_root_arr] | |
| 99 | + // THIS IS IMPORTANT: BOTH subtree_root_arr are the same object. | |
| 100 | + // Without this, we CAN'T build the tree this way. PLEASE, let PHP support | |
| 101 | + // this magic. | |
| 102 | + | |
| 103 | + // initialise. | |
| 104 | + | |
| 105 | + $this->mapnodes = array(); // will hold the actual nodes, mapped by id. | |
| 106 | + $this->contents = array(); // will hold references to each nodes subtree. | |
| 107 | + $this->contents[0] = array(); | |
| 108 | + | |
| 109 | + foreach ($orderedTreeNodes as $treeNode) { | |
| 110 | + | |
| 111 | + // step 1: set the map entry for this item. | |
| 112 | + $iParent = $treeNode->getParentNode(); | |
| 113 | + $iCurrId = $treeNode->getId(); | |
| 114 | + $this->mapnodes[$iCurrId] = $treeNode; // always works, setting our own value. | |
| 115 | + | |
| 116 | + $parent_arr = null; | |
| 117 | + if (!array_key_exists($iParent, $this->contents)) { $this->contents[$iParent] = array(); } | |
| 118 | + if (!array_key_exists($iCurr, $this->contents)) { $this->contents[$iCurrId] = array(); } | |
| 119 | + | |
| 120 | + $this->contents[$iParent][] = $iCurrId; | |
| 121 | + //$default->log->debug("MDTree::buildForField bound to subtree " . print_r($this->contents, true)); | |
| 122 | + } | |
| 123 | + | |
| 124 | + $md_list =& MetaData::getList('document_field_id = ' .$organisedField->getId()); | |
| 125 | + $this->lookups = array(); | |
| 126 | + foreach ($md_list as $lookup_value) { | |
| 127 | + | |
| 128 | + // failsafe. unparented and orphaned items go into root. | |
| 129 | + $iParentId = $lookup_value->getTreeParent(); | |
| 130 | + if ($iParentId === null) $iParentId = 0; | |
| 131 | + if (array_key_exists($iParentId, $this->contents)) { | |
| 132 | + $target_set =& $this->contents[$iParentId]; | |
| 133 | + } | |
| 134 | + else | |
| 135 | + { | |
| 136 | + $target_set =& $this->contents[0]; | |
| 137 | + } | |
| 138 | + | |
| 139 | + $leafArray = null; | |
| 140 | + if (!array_key_exists("leaves", $target_set)) { | |
| 141 | + $target_set["leaves"] = array($lookup_value->getId()); | |
| 142 | + } | |
| 143 | + else | |
| 144 | + { | |
| 145 | + | |
| 146 | + array_push($target_set["leaves"], $lookup_value->getId()); | |
| 147 | + } | |
| 148 | + | |
| 149 | + $this->lookups[$lookup_value->getId()] = $lookup_value; | |
| 150 | + | |
| 151 | + } | |
| 152 | + $this->root =& $this->contents[0]; | |
| 153 | + $default->log->debug("MDTree::buildForField done: " . print_r($this, true)); | |
| 154 | + | |
| 155 | + } | |
| 156 | + | |
| 157 | + // handle deleting subtrees | |
| 158 | + function deleteNode($iNode) { | |
| 159 | + $stack = array(); | |
| 160 | + array_push($stack, $iNode); | |
| 161 | + while (count($stack) != 0) | |
| 162 | + { | |
| 163 | + $currentNode = array_pop($stack); | |
| 164 | + foreach ($this->contents[$currentNode] as $label => $value) | |
| 165 | + { | |
| 166 | + if ($label === "leaves") | |
| 167 | + { | |
| 168 | + foreach ($value as $leaf) | |
| 169 | + { | |
| 170 | + $this->lookups[$leaf]->setTreeParent(0); | |
| 171 | + $this->lookups[$leaf]->update(); | |
| 172 | + $this->contents[0]["leaves"][] = $leaf; | |
| 173 | + } | |
| 174 | + } | |
| 175 | + else array_push($stack, $value); | |
| 176 | + } | |
| 177 | + $this->mapnodes[$currentNode]->delete(); | |
| 178 | + } | |
| 179 | + // finally, we prune the appropriate item from its parent. | |
| 180 | + $iParent = $this->mapnodes[$iNode]->getParentNode(); | |
| 181 | + foreach ($this->contents[$iParent] as $index => $val) | |
| 182 | + if ($iNode === $val) unset($this->contents[$iParent][$index]); | |
| 183 | + } | |
| 184 | + | |
| 185 | + // add a node to the mapping after the fact (e.g. created later in the process.) | |
| 186 | + function addNode($oNode) { | |
| 187 | + $iParent = $oNode->getParentNode(); | |
| 188 | + $this->mapnodes[$oNode->getId()] =& $oNode; | |
| 189 | + $this->contents[$oNode->getId()] = array(); | |
| 190 | + array_push($this->contents[$iParent], $oNode->getId()); | |
| 191 | + } | |
| 192 | + | |
| 193 | + function reparentKeyword($lookup_id, $destination_parent_id) | |
| 194 | + { | |
| 195 | + global $default; | |
| 196 | + | |
| 197 | + $oKeyword = $this->lookups[$lookup_id]; | |
| 198 | + $oldParent = $oKeyword->getTreeParent(); | |
| 199 | + $oNewParent = $this->mapnodes[$destination_parent_id]; | |
| 200 | + // we will have failed by here if its bogus. | |
| 201 | + //$default->log->debug('MDTree::reparentKeyword '.print_r($oNewParent, true)); | |
| 202 | + | |
| 203 | + // if its 0 or NULL, we reparent to null. | |
| 204 | + if (($oNewParent === null) or ($desintation_parent_id === 0)) { | |
| 205 | + $new_home = 0; | |
| 206 | + } else { | |
| 207 | + $new_home = $oNewParent->getId(); | |
| 208 | + } | |
| 209 | + $oKeyword->setTreeParent($new_home); | |
| 210 | + // don't assume we're reparenting from 0. | |
| 211 | + $KWIndex = array_search($lookup_id, $this->contents[$oldParent]["leaves"]); | |
| 212 | + unset($this->contents[$oldParent]["leaves"][$KWIndex]); | |
| 213 | + $this->contents[$new_home]["leaves"][] = $oKeyword->getId(); | |
| 214 | + $oKeyword->update(); | |
| 215 | + } | |
| 216 | + | |
| 217 | + | |
| 218 | + // STUB FUNCTIONS: need to be filled in. | |
| 219 | + | |
| 220 | + | |
| 221 | + // REALLY need to deprecate this, but how? | |
| 222 | + function render($bEditable) { return null; } // render using a template (with edit / buttons.) FIXME build a widget / renderer. | |
| 223 | + | |
| 224 | + | |
| 225 | + /* ----------------------- EVIL HACK -------------------------- | |
| 226 | + * | |
| 227 | + * This whole thing needs to replaced, as soon as I work out how | |
| 228 | + * to non-sucking Smarty recursion. | |
| 229 | + */ | |
| 230 | + | |
| 231 | + function _evilTreeRecursion($subnode, $treeToRender, $inputname) | |
| 232 | + { | |
| 233 | + $treeStr = "<ul>"; | |
| 234 | + foreach ($treeToRender->contents[$subnode] as $subnode_id => $subnode_val) | |
| 235 | + { | |
| 236 | + if ($subnode_id !== "leaves") { | |
| 237 | + $treeStr .= '<li class="treenode">' . $treeToRender->mapnodes[$subnode_val]->getName(); | |
| 238 | + $treeStr .= $this->_evilTreeRecursion($subnode_val, $treeToRender, $inputname); | |
| 239 | + $treeStr .= '</li>'; | |
| 240 | + } | |
| 241 | + else | |
| 242 | + { | |
| 243 | + foreach ($subnode_val as $leaf) | |
| 244 | + { | |
| 245 | + $treeStr .= '<li class="leafnode"><input type="radio" name="'.$inputname.'" value="'.$treeToRender->lookups[$leaf]->getName().'">' . $treeToRender->lookups[$leaf]->getName() .'</input>'; | |
| 246 | + | |
| 247 | + $treeStr .= '</li>'; } | |
| 248 | + } | |
| 249 | + } | |
| 250 | + $treeStr .= '</ul>'; | |
| 251 | + return $treeStr; | |
| 252 | + | |
| 253 | + } | |
| 254 | + | |
| 255 | + // I can't seem to do recursion in smarty, and recursive templates seems a bad solution. | |
| 256 | + // Come up with a better way to do this (? NBM) | |
| 257 | + function _evilTreeRenderer($treeToRender, $inputname) { | |
| 258 | + //global $default; | |
| 259 | + $treeStr = "<!-- this is rendered with an unholy hack. sorry. -->"; | |
| 260 | + $stack = array(); | |
| 261 | + $exitstack = array(); | |
| 262 | + | |
| 263 | + // since the root is virtual, we need to fake it here. | |
| 264 | + // the inner section is generised. | |
| 265 | + $treeStr .= '<ul class="kt_treenodes"><li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">Root</a>'; | |
| 266 | + $treeStr .= '<ul>'; | |
| 267 | + //$default->log->debug("EVILRENDER: " . print_r($treeToRender, true)); | |
| 268 | + foreach ($treeToRender->getRoot() as $node_id => $subtree_nodes) | |
| 269 | + { | |
| 270 | + //$default->log->debug("EVILRENDER: ".$node_id." => ".$subtree_nodes." (".($node_id === "leaves").")"); | |
| 271 | + // leaves are handled differently. | |
| 272 | + if ($node_id !== "leaves") { | |
| 273 | + // $default->log->debug("EVILRENDER: " . print_r($subtree_nodes, true)); | |
| 274 | + $treeStr .= '<li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">' . $treeToRender->mapnodes[$subtree_nodes]->getName().'</a>'; | |
| 275 | + $treeStr .= $this->_evilTreeRecursion($subtree_nodes, $treeToRender, $inputname); | |
| 276 | + $treeStr .= '</li>'; | |
| 277 | + } | |
| 278 | + else | |
| 279 | + { | |
| 280 | + foreach ($subtree_nodes as $leaf) | |
| 281 | + { | |
| 282 | + $treeStr .= '<li class="leafnode"><input type="radio" name="'.$inputname.'" value="'.$treeToRender->lookups[$leaf]->getName().'">' . $treeToRender->lookups[$leaf]->getName() .'</input>'; | |
| 283 | + $treeStr .= '</li>'; | |
| 284 | + } | |
| 285 | + } | |
| 286 | + } | |
| 287 | + $treeStr .= '</ul></li>'; | |
| 288 | + $treeStr .= '</ul>'; | |
| 289 | + | |
| 290 | + return $treeStr; | |
| 291 | + | |
| 292 | + } | |
| 293 | +} | |
| 294 | + | |
| 295 | +?> | ... | ... |
lib/documentmanagement/MetaData.inc
| ... | ... | @@ -27,11 +27,13 @@ |
| 27 | 27 | class MetaData extends KTEntity { |
| 28 | 28 | |
| 29 | 29 | /** primary key value */ |
| 30 | - var $iId; | |
| 30 | + var $iId = -1; | |
| 31 | 31 | //document field id |
| 32 | 32 | var $iDocFieldId; |
| 33 | 33 | /** MetaData name */ |
| 34 | 34 | var $sName; |
| 35 | + /** _if_ this field is a tree, which node in said tree is this one's parent. */ | |
| 36 | + var $iTreeParent; | |
| 35 | 37 | |
| 36 | 38 | /** |
| 37 | 39 | * Default constructor |
| ... | ... | @@ -40,68 +42,28 @@ class MetaData extends KTEntity { |
| 40 | 42 | * @param MetaData data type |
| 41 | 43 | * |
| 42 | 44 | */ |
| 43 | - function MetaData($iNewDocFieldID,$sNewName) { | |
| 45 | + function MetaData($iNewDocFieldID = null,$sNewName = null, $iNewParent = null) { | |
| 44 | 46 | //object not created yet |
| 45 | 47 | $this->iId = -1; |
| 46 | 48 | $this->iDocFieldID = $iNewDocFieldID; |
| 47 | 49 | $this->sName = $sNewName; |
| 48 | - | |
| 49 | - } | |
| 50 | - | |
| 51 | - /** | |
| 52 | - * Get the MetaData's primary key value | |
| 53 | - * | |
| 54 | - * @return int MetaData's primary key value | |
| 55 | - * | |
| 56 | - */ | |
| 57 | - function getID() { | |
| 58 | - return $this->iId; | |
| 59 | - } | |
| 60 | - | |
| 61 | - /** | |
| 62 | - * Get the MetaData's name | |
| 63 | - * | |
| 64 | - * @return String MetaData's name | |
| 65 | - * | |
| 66 | - */ | |
| 67 | - function getName() { | |
| 68 | - return $this->sName; | |
| 50 | + $this->iTreeParent = $iNewParent; | |
| 69 | 51 | } |
| 70 | 52 | |
| 71 | - | |
| 72 | - /** | |
| 73 | - * Set the MetaData's name | |
| 74 | - * | |
| 75 | - * @param MetaData's new name | |
| 76 | - * | |
| 77 | - */ | |
| 78 | - function setName($sNewValue) { | |
| 79 | - $this->sName = $sNewValue; | |
| 80 | - } | |
| 81 | - /** | |
| 82 | - * Set the MetaData's docField | |
| 83 | - * | |
| 84 | - * @param MetaData's new name | |
| 85 | - * | |
| 86 | - */ | |
| 87 | - function setDocFieldID($sNewValue) { | |
| 88 | - $this->iDocFieldID = $sNewValue; | |
| 89 | - } | |
| 90 | - | |
| 91 | - /** | |
| 92 | - * Get the MetaData's docfield | |
| 93 | - * | |
| 94 | - * @return String MetaData's name | |
| 95 | - * | |
| 96 | - */ | |
| 97 | - function getDocFieldID() { | |
| 98 | - return $this->iDocFieldID; | |
| 99 | - } | |
| 53 | + function getID() { return $this->iId; } | |
| 54 | + function getName() { return $this->sName; } | |
| 55 | + function setName($sNewValue) { $this->sName = $sNewValue; } | |
| 56 | + function getDocFieldID() { return $this->iDocFieldID; } | |
| 57 | + function setDocFieldID($iNewValue) { $this->iDocFieldID = $iNewValue; } | |
| 58 | + function getTreeParent() { return $this->iTreeParent; } | |
| 59 | + function setTreeParent($iNewValue) { $this->iTreeParent = $iNewValue; } | |
| 60 | + | |
| 100 | 61 | |
| 101 | 62 | function _fieldValues () { |
| 102 | 63 | return array( |
| 103 | 64 | 'document_field_id' => $this->iDocFieldID, |
| 104 | 65 | 'name' => $this->sName, |
| 66 | + 'treeorg_parent' => $this->iTreeParent, | |
| 105 | 67 | ); |
| 106 | 68 | } |
| 107 | 69 | |
| ... | ... | @@ -152,6 +114,7 @@ class MetaData extends KTEntity { |
| 152 | 114 | if ($sql->next_record()) { |
| 153 | 115 | $oDocumentType = & new MetaData($sql->f("document_field_id"),$sql->f("name")); |
| 154 | 116 | $oDocumentType->iId = $sql->f("id"); |
| 117 | + $oDocumentType->iTreeParent = $sql->f("treeorg_parent"); | |
| 155 | 118 | return $oDocumentType; |
| 156 | 119 | } |
| 157 | 120 | $_SESSION["errorMessage"] = $lang_err_object_not_exist . "id = " . $iDocumentID . " table = document_types"; | ... | ... |
lib/visualpatterns/PatternMetaData.inc
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | require_once("PatternListBox.inc"); |
| 4 | +require_once(KT_LIB_DIR . "/documentmanagement/MDTree.inc"); | |
| 5 | + | |
| 4 | 6 | /** |
| 5 | 7 | * $Id$ |
| 6 | 8 | * |
| ... | ... | @@ -44,12 +46,12 @@ class PatternMetaData { |
| 44 | 46 | |
| 45 | 47 | function render() { |
| 46 | 48 | global $default; |
| 47 | - $sQuery = "SELECT has_lookup, data_type FROM $default->document_fields_table WHERE name LIKE '" . DBUtil::escapeSimple($this->sMetaDataField) . "'";/*ok*/ | |
| 49 | + $sQuery = "SELECT has_lookup, data_type, has_lookuptree, id FROM $default->document_fields_table WHERE name LIKE '" . DBUtil::escapeSimple($this->sMetaDataField) . "'";/*ok*/ | |
| 48 | 50 | |
| 49 | 51 | $sql = $default->db; |
| 50 | 52 | $sql->query($sQuery); |
| 51 | 53 | if ($sql->next_record()) { |
| 52 | - if ($sql->f("has_lookup")) { | |
| 54 | + if ($sql->f("has_lookup") and (!$sql->f("has_lookuptree"))) { | |
| 53 | 55 | //is a lookup, so display a drop down list |
| 54 | 56 | $sWhereClause = "DF.name LIKE '" . $this->sMetaDataField . "'"; |
| 55 | 57 | $sFromClause = "INNER JOIN $default->document_fields_table AS DF ON ST.document_field_id = DF.id"; |
| ... | ... | @@ -60,6 +62,10 @@ class PatternMetaData { |
| 60 | 62 | $oPatternListBox->setFromClause($sFromClause); |
| 61 | 63 | $oPatternListBox->setWhereClause($sWhereClause); |
| 62 | 64 | return $oPatternListBox->render(); |
| 65 | + } else if ($sql->f("has_lookup") and ($sql->f("has_lookuptree"))) { | |
| 66 | + $fieldTree = new MDTree(); | |
| 67 | + $fieldTree->buildForField($sql->f("id")); | |
| 68 | + return $fieldTree->_evilTreeRenderer($fieldTree, $this->sFormName); | |
| 63 | 69 | } else { |
| 64 | 70 | $textboxlength = null; |
| 65 | 71 | switch($sql->f("data_type")) { | ... | ... |
presentation/lookAndFeel/knowledgeTree/administration/docfieldmanagement/manageLookupTrees.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once("../../../../../config/dmsDefaults.php"); | |
| 3 | +require_once(KT_DIR . "/presentation/Html.inc"); | |
| 4 | +require_once(KT_LIB_DIR . "/templating/templating.inc.php"); | |
| 5 | +require_once(KT_LIB_DIR . "/documentmanagement/DocumentField.inc"); | |
| 6 | +require_once(KT_LIB_DIR . "/documentmanagement/MetaData.inc"); | |
| 7 | +require_once(KT_LIB_DIR . "/documentmanagement/MDTree.inc"); | |
| 8 | +require_once(KT_LIB_DIR . "/dispatcher.inc.php"); | |
| 9 | +$sectionName = "Administration"; | |
| 10 | +require_once(KT_DIR . "/presentation/webpageTemplate.inc"); | |
| 11 | + | |
| 12 | +class ManageLookupTreeDispatcher extends KTAdminDispatcher { | |
| 13 | + function do_main() { | |
| 14 | + $oTemplating = new KTTemplating; | |
| 15 | + $aTreeFields =& DocumentField::getList('has_lookuptree = 1'); | |
| 16 | + $aLookupFields =& DocumentField::getList('has_lookup = 1 AND (has_lookuptree IS NULL or has_lookuptree = 0)'); | |
| 17 | + $oTemplate = $oTemplating->loadTemplate("ktcore/manage_lookuptrees"); | |
| 18 | + $aTemplateData = array( | |
| 19 | + "treefields" => $aTreeFields, | |
| 20 | + "lookupfields" => $aLookupFields, | |
| 21 | + ); | |
| 22 | + return $oTemplate->render($aTemplateData); | |
| 23 | + } | |
| 24 | + | |
| 25 | + function handleOutput($data) { | |
| 26 | + global $main; | |
| 27 | + $main->bFormDisabled = true; | |
| 28 | + $main->setCentralPayload($data); | |
| 29 | + $main->render(); | |
| 30 | + } | |
| 31 | + | |
| 32 | + function do_createTree() { | |
| 33 | + // extract. | |
| 34 | + $field_id = KTUtil::arrayGet($_REQUEST, 'field_id'); | |
| 35 | + | |
| 36 | + // validate | |
| 37 | + if (empty($field_id)) { return $this->errorRedirectToMain("Must select a field to convert."); } | |
| 38 | + $oField =& DocumentField::get($field_id); | |
| 39 | + if (PEAR::isError($oField)) { return $this->errorRedirectToMain("Invalid field."); } | |
| 40 | + | |
| 41 | + // set as a metadata tree. | |
| 42 | + $oField->setHasLookupTree(1); | |
| 43 | + $oField->update(); | |
| 44 | + $this->errorRedirectToMain("Converted ".$oField->getName()." to a tree."); | |
| 45 | + } | |
| 46 | + | |
| 47 | + | |
| 48 | + // create and display the tree editing form. | |
| 49 | + function do_editTree() { | |
| 50 | + global $default; | |
| 51 | + // extract. | |
| 52 | + $field_id = KTUtil::arrayGet($_REQUEST, 'field_id'); | |
| 53 | + $current_node = KTUtil::arrayGet($_REQUEST, 'current_node', 0); | |
| 54 | + $subaction = KTUtil::arrayGet($_REQUEST, 'subaction'); | |
| 55 | + | |
| 56 | + // validate | |
| 57 | + if (empty($field_id)) { return $this->errorRedirectToMain("Must select a field to edit."); } | |
| 58 | + $oField =& DocumentField::get($field_id); | |
| 59 | + if (PEAR::isError($oField)) { return $this->errorRedirectToMain("Invalid field."); } | |
| 60 | + | |
| 61 | + // under here we do the subaction rendering. | |
| 62 | + // we do this so we don't have to do _very_ strange things with multiple actions. | |
| 63 | + $default->log->debug("Subaction: " . $subaction); | |
| 64 | + $fieldTree =& new MDTree(); | |
| 65 | + $fieldTree->buildForField($oField->getId()); | |
| 66 | + | |
| 67 | + if ($subaction !== null) { | |
| 68 | + if ($subaction === "addCategory") { | |
| 69 | + $new_category = KTUtil::arrayGet($_REQUEST, 'category_name'); | |
| 70 | + if (empty($new_category)) { return $this->errorRedirectTo("editTree", "Must enter a name for the new category.", array("field_id" => $field_id)); } | |
| 71 | + else { $this->subact_addCategory($field_id, $current_node, $new_category, $fieldTree);} | |
| 72 | + } | |
| 73 | + if ($subaction === "deleteCategory") { | |
| 74 | + $this->subact_deleteCategory($fieldTree, $current_node); | |
| 75 | + $current_node = 0; // clear out, and don't try and render the newly deleted category. | |
| 76 | + } | |
| 77 | + if ($subaction === "linkKeywords") { | |
| 78 | + $keywords = KTUtil::arrayGet($_REQUEST, 'keywordsToAdd'); | |
| 79 | + $this->subact_linkKeywords($fieldTree, $current_node, $keywords); | |
| 80 | + $current_node = 0; // clear out, and don't try and render the newly deleted category. | |
| 81 | + } | |
| 82 | + if ($subaction === "unlinkKeyword") { | |
| 83 | + $keyword = KTUtil::arrayGet($_REQUEST, 'keyword_id'); | |
| 84 | + $this->subact_unlinkKeyword($fieldTree, $keyword); | |
| 85 | + } | |
| 86 | + } | |
| 87 | + | |
| 88 | + if ($fieldTree->root === null) { | |
| 89 | + return $this->errorRedirectToMain("Error building tree. Is this a valid tree-lookup field?"); | |
| 90 | + } | |
| 91 | + | |
| 92 | + // FIXME extract this from MDTree (helper method?) | |
| 93 | + $free_metadata = MetaData::getList('document_field_id = '.$oField->getId().' AND (treeorg_parent = 0 OR treeorg_parent IS NULL)'); | |
| 94 | + | |
| 95 | + // render edit template. | |
| 96 | + $oTemplating = new KTTemplating; | |
| 97 | + $oTemplate = $oTemplating->loadTemplate("ktcore/edit_lookuptrees"); | |
| 98 | + $renderedTree = $this->_evilTreeRenderer($fieldTree); | |
| 99 | + $aTemplateData = array( | |
| 100 | + "field" => $oField, | |
| 101 | + "tree" => $fieldTree, | |
| 102 | + "renderedTree" => $renderedTree, | |
| 103 | + "currentNode" => $current_node, | |
| 104 | + "freechildren" => $free_metadata, | |
| 105 | + ); | |
| 106 | + return $oTemplate->render($aTemplateData); | |
| 107 | + } | |
| 108 | + | |
| 109 | + function subact_addCategory($field_id, $current_node, $new_category, &$constructedTree) { | |
| 110 | + $newCategory = MDTreeNode::createFromArray(array ( | |
| 111 | + "iFieldId" => $field_id, | |
| 112 | + "sName" => $new_category, | |
| 113 | + "iParentNode" => $current_node, | |
| 114 | + )); | |
| 115 | + if (PEAR::isError($newCategory)) | |
| 116 | + { | |
| 117 | + return false; | |
| 118 | + } | |
| 119 | + $constructedTree->addNode($newCategory); | |
| 120 | + return true; | |
| 121 | + } | |
| 122 | + | |
| 123 | + function subact_deleteCategory(&$constructedTree, $current_node) { | |
| 124 | + $constructedTree->deleteNode($current_node); | |
| 125 | + return true; | |
| 126 | + } | |
| 127 | + | |
| 128 | + function subact_unlinkKeyword(&$constructedTree, $keyword) { | |
| 129 | + $oKW = MetaData::get($keyword); | |
| 130 | + $constructedTree->reparentKeyword($oKW->getId(), 0); | |
| 131 | + return true; | |
| 132 | + } | |
| 133 | + | |
| 134 | + | |
| 135 | + function subact_linkKeywords(&$constructedTree, $current_node, $keywords) { | |
| 136 | + foreach ($keywords as $md_id) | |
| 137 | + { | |
| 138 | + $constructedTree->reparentKeyword($md_id, $current_node); | |
| 139 | + } | |
| 140 | + return true; | |
| 141 | + } | |
| 142 | + | |
| 143 | + /* ----------------------- EVIL HACK -------------------------- | |
| 144 | + * | |
| 145 | + * This whole thing needs to replaced, as soon as I work out how | |
| 146 | + * to non-sucking Smarty recursion. | |
| 147 | + */ | |
| 148 | + | |
| 149 | + function _evilTreeRecursion($subnode, $treeToRender) | |
| 150 | + { | |
| 151 | + $treeStr = "<ul>"; | |
| 152 | + foreach ($treeToRender->contents[$subnode] as $subnode_id => $subnode_val) | |
| 153 | + { | |
| 154 | + if ($subnode_id !== "leaves") { | |
| 155 | + $treeStr .= '<li class="treenode">' . $treeToRender->mapnodes[$subnode_val]->getName(); | |
| 156 | + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, false, $subnode_val); | |
| 157 | + $treeStr .= $this->_evilTreeRecursion($subnode_val, $treeToRender); | |
| 158 | + $treeStr .= '</li>'; | |
| 159 | + } | |
| 160 | + else | |
| 161 | + { | |
| 162 | + foreach ($subnode_val as $leaf) | |
| 163 | + { | |
| 164 | + $treeStr .= '<li class="leafnode">' . $treeToRender->lookups[$leaf]->getName(); | |
| 165 | + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, true, $leaf); | |
| 166 | + $treeStr .= '</li>'; } | |
| 167 | + } | |
| 168 | + } | |
| 169 | + $treeStr .= '</ul>'; | |
| 170 | + return $treeStr; | |
| 171 | + | |
| 172 | + } | |
| 173 | + | |
| 174 | + // I can't seem to do recursion in smarty, and recursive templates seems a bad solution. | |
| 175 | + // Come up with a better way to do this (? NBM) | |
| 176 | + function _evilTreeRenderer($treeToRender) { | |
| 177 | + //global $default; | |
| 178 | + $treeStr = "<!-- this is rendered with an unholy hack. sorry. -->"; | |
| 179 | + $stack = array(); | |
| 180 | + $exitstack = array(); | |
| 181 | + | |
| 182 | + // since the root is virtual, we need to fake it here. | |
| 183 | + // the inner section is generised. | |
| 184 | + $treeStr .= '<ul class="kt_treenodes"><li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">Root</a>'; | |
| 185 | + $treeStr .= ' (<a href="manageLookupTrees.php?action=editTree&field_id='.$treeToRender->field_id.'¤t_node=0">edit</a>)'; | |
| 186 | + $treeStr .= '<ul>'; | |
| 187 | + //$default->log->debug("EVILRENDER: " . print_r($treeToRender, true)); | |
| 188 | + foreach ($treeToRender->getRoot() as $node_id => $subtree_nodes) | |
| 189 | + { | |
| 190 | + //$default->log->debug("EVILRENDER: ".$node_id." => ".$subtree_nodes." (".($node_id === "leaves").")"); | |
| 191 | + // leaves are handled differently. | |
| 192 | + if ($node_id !== "leaves") { | |
| 193 | + // $default->log->debug("EVILRENDER: " . print_r($subtree_nodes, true)); | |
| 194 | + $treeStr .= '<li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">' . $treeToRender->mapnodes[$subtree_nodes]->getName() . '</a>'; | |
| 195 | + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, false, $subtree_nodes); | |
| 196 | + $treeStr .= $this->_evilTreeRecursion($subtree_nodes, $treeToRender); | |
| 197 | + $treeStr .= '</li>'; | |
| 198 | + } | |
| 199 | + else | |
| 200 | + { | |
| 201 | + foreach ($subtree_nodes as $leaf) | |
| 202 | + { | |
| 203 | + $treeStr .= '<li class="leafnode">' . $treeToRender->lookups[$leaf]->getName(); | |
| 204 | + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, true, $leaf); | |
| 205 | + $treeStr .= '</li>'; | |
| 206 | + } | |
| 207 | + } | |
| 208 | + } | |
| 209 | + $treeStr .= '</ul></li>'; | |
| 210 | + $treeStr .= '</ul>'; | |
| 211 | + | |
| 212 | + return $treeStr; | |
| 213 | + } | |
| 214 | + | |
| 215 | + // don't hate me. | |
| 216 | + function _evilActionHelper($iFieldId, $bIsKeyword, $current_node) { | |
| 217 | + $actionStr = " ("; | |
| 218 | + if ($bIsKeyword === true) { | |
| 219 | + $actionStr .= '<a href="manageLookupTrees.php?action=editTree&field_id='.$iFieldId.'&keyword_id='.$current_node.'&subaction=unlinkKeyword">unlink</a>'; | |
| 220 | + } | |
| 221 | + else | |
| 222 | + { | |
| 223 | + $actionStr .= '<a href="manageLookupTrees.php?action=editTree&field_id='.$iFieldId.'¤t_node='.$current_node.'">add items</a> '; | |
| 224 | + $actionStr .= '| <a href="manageLookupTrees.php?action=editTree&field_id='.$iFieldId.'¤t_node='.$current_node.'&subaction=deleteCategory">delete</a>'; | |
| 225 | + } | |
| 226 | + $actionStr .= ")"; | |
| 227 | + return $actionStr; | |
| 228 | + } | |
| 229 | + | |
| 230 | +} | |
| 231 | + | |
| 232 | +$oDispatcher = new ManageLookupTreeDispatcher(); | |
| 233 | +$oDispatcher->dispatch(); | |
| 234 | + | |
| 235 | +?> | ... | ... |
presentation/lookAndFeel/knowledgeTree/handleConditional.php
0 → 100644
| 1 | +<?php | |
| 2 | +require_once("../../../config/dmsDefaults.php"); | |
| 3 | +require_once(KT_DIR . "/presentation/Html.inc"); | |
| 4 | +require_once(KT_LIB_DIR . "/templating/templating.inc.php"); | |
| 5 | +require_once(KT_LIB_DIR . "/documentmanagement/DocumentFieldSet.inc"); | |
| 6 | +require_once(KT_LIB_DIR . "/documentmanagement/DocumentField.inc"); | |
| 7 | +require_once(KT_LIB_DIR . "/documentmanagement/MDCondition.inc"); | |
| 8 | +require_once(KT_LIB_DIR . "/database/dbutil.inc"); | |
| 9 | +require_once(KT_LIB_DIR . "/util/ktutil.inc"); | |
| 10 | +require_once(KT_LIB_DIR . "/dispatcher.inc.php"); | |
| 11 | +$sectionName = "Administration"; | |
| 12 | +require_once(KT_DIR . "/presentation/webpageTemplate.inc"); | |
| 13 | + | |
| 14 | +class HandleConditionalDispatcher extends KTDispatcher { | |
| 15 | + function do_main() { | |
| 16 | + global $default; | |
| 17 | + $fieldset_id = KTUtil::arrayGet($_REQUEST, 'fieldset_id'); | |
| 18 | + $active_fields = KTUtil::arrayGet($_REQUEST, 'fields'); | |
| 19 | + | |
| 20 | + | |
| 21 | + if (empty($fieldset_id)) { | |
| 22 | + return 'invalid fieldset_id'; | |
| 23 | + } | |
| 24 | + | |
| 25 | + $fieldsToRender = array(); // contains "name" => rows. | |
| 26 | + | |
| 27 | + $oFieldSet = DocumentFieldSet::get($fieldset_id); | |
| 28 | + if (empty($active_fields)) { | |
| 29 | + $res = $this->getMasterFieldInfo($oFieldSet); | |
| 30 | + $fieldsToRender[$oFieldSet->getMasterField()] = $res; | |
| 31 | + } else { | |
| 32 | + // urgh. we use this to generate our list of things to extract from the input. | |
| 33 | + $pairings = array(); | |
| 34 | + foreach ($active_fields as $field_id) { | |
| 35 | + $current = KTUtil::arrayGet($_REQUEST, 'conditional_field_'.$field_id); | |
| 36 | + if ($current === null) { | |
| 37 | + return 'invalid input sequence.'; | |
| 38 | + } | |
| 39 | + else { | |
| 40 | + $pairings[$field_id] = $current; | |
| 41 | + } | |
| 42 | + | |
| 43 | + } | |
| 44 | + $res = $this->validatePath($oFieldSet, $pairings, true); | |
| 45 | + if ($res === true) { | |
| 46 | + return 'validated input.'; | |
| 47 | + } | |
| 48 | + else if ($res === false) { | |
| 49 | + return 'invalid input'; | |
| 50 | + } | |
| 51 | + // quick collation process. | |
| 52 | + foreach ($res as $aRow) { | |
| 53 | + $fieldsToRender[$aRow["document_field_id"]][] = $aRow; | |
| 54 | + } | |
| 55 | + } | |
| 56 | + | |
| 57 | + $default->log->debug('validatePath: results '.print_r($fieldsToRender,true)); | |
| 58 | + | |
| 59 | + $oTemplating = new KTTemplating; | |
| 60 | + | |
| 61 | + $oTemplate = $oTemplating->loadTemplate("ktcore/handle_conditional"); | |
| 62 | + $aTemplateData = array( | |
| 63 | + "fieldset" => $oFieldSet->getId(), | |
| 64 | + "oldfields" => $pairings, | |
| 65 | + "fieldsToRender" => $fieldsToRender, | |
| 66 | + ); | |
| 67 | + return $oTemplate->render($aTemplateData); | |
| 68 | + } | |
| 69 | + | |
| 70 | + function handleOutput($data) { | |
| 71 | + print $data; | |
| 72 | + } | |
| 73 | + | |
| 74 | + function getMasterFieldInfo($oFieldSet) { | |
| 75 | + global $default; | |
| 76 | + $masterField = $oFieldSet->getMasterField(); | |
| 77 | + $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 = ? "; | |
| 78 | + return DBUtil::getResultArray(array($sQuery, array($masterField))); | |
| 79 | + } | |
| 80 | + | |
| 81 | + // either returns the set of pathid's for the input, | |
| 82 | + // or false (FIXME: should be PEAR::raiseError) | |
| 83 | + function validatePath($oFieldSet, $aPairings, $bPartial) { | |
| 84 | + /* An explanation of what happens below, since NBM's comment was "Put that crack-pipe back in the freezer." | |
| 85 | + * | |
| 86 | + * $aPairings are the inputs we were handed. Within these, there are 3 | |
| 87 | + * important things: | |
| 88 | + * 1. we have a limited set of document_fields within the $oFieldSet. | |
| 89 | + * 2. one of these fields is the "master field" - the _ONLY_ one without | |
| 90 | + * any parent conditions. | |
| 91 | + * 3. some fields may get passed _out_ as <input type="hidden" name="conditional_field_x" value="-1" /> | |
| 92 | + * which indicates that there is NO VALUE for that field (again, saved in the db as "-1" so we don't go mad. | |
| 93 | + * | |
| 94 | + * We essentially have 3 stacks: inputs, parent_conditions, free_field_ids | |
| 95 | + * | |
| 96 | + * $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) | |
| 97 | + * or return the possible next choices. | |
| 98 | + * | |
| 99 | + * We start with the master-field, and get its entry in the table. If it isn't there, fail. | |
| 100 | + * i. push its field onto the "parent_conditions" stack, and remove the field_id from the "option_fields". | |
| 101 | + * ii. remove its entry from the inputs. | |
| 102 | + * While we have inputs -> | |
| 103 | + * find any matches that have a (field_id, lookup_id) in the input set, and parent_condition in the parent_conditions stack. | |
| 104 | + * if no values found, FAIL - invalid input (we can't match what we've been given). | |
| 105 | + * otherwise -> | |
| 106 | + * 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. | |
| 107 | + * If $bPartial == true -> | |
| 108 | + * 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 | |
| 109 | + * the next set of "inputs" - (column, lookup) pairs with parent-rules that have been activated. | |
| 110 | + * If $bPartial == false and free_field_id's still has anything in it WE FAIL OUT. | |
| 111 | + */ | |
| 112 | + global $default; | |
| 113 | + $free_field_ids = array(); | |
| 114 | + $parent_conditions = array(); | |
| 115 | + $inputs = $aPairings; // please tell me this does a copy ... | |
| 116 | + | |
| 117 | + // step 1: generate free_field_ids. | |
| 118 | + $childFields = DocumentField::getList('parent_fieldset = '.$oFieldSet->getId()); | |
| 119 | + foreach ($childFields as $oField) { | |
| 120 | + $free_field_ids[$oField->getId()] = 1; // placeholder. | |
| 121 | + } | |
| 122 | + $master_field = $oFieldSet->getMasterField(); // this is the id of the master field. | |
| 123 | + if (!array_key_exists($master_field, $inputs)) { | |
| 124 | + return false; // no master field in the input. | |
| 125 | + } | |
| 126 | + | |
| 127 | + // step 2: get the first parent, to get the ball rolling. | |
| 128 | + $sQuery = "SELECT * FROM $default->md_condition_table WHERE document_field_id = ? and metadata_lookup_id = ? "; | |
| 129 | + $aParams = array($master_field, $inputs[$master_field]); | |
| 130 | + $res = DBUtil::getOneResult(array($sQuery, $aParams)); | |
| 131 | + | |
| 132 | + if (PEAR::isError($res)) { | |
| 133 | + return false; // no value matched on the master field input, the rest MUST fail. | |
| 134 | + } | |
| 135 | + else { | |
| 136 | + unset($free_field_ids[$master_field]); // master is no longer free. | |
| 137 | + $rule_id = $res["id"]; | |
| 138 | + $parent_conditions[$rule_id] = 1; | |
| 139 | + unset($inputs[$master_field]); | |
| 140 | + } | |
| 141 | + | |
| 142 | + $default->log->debug('validatePath: parent_conditions '.print_r($parent_conditions,true)); | |
| 143 | + | |
| 144 | + | |
| 145 | + while (count($inputs) != 0) { // we'll return out inside here if necessary. | |
| 146 | + // check for items in inputs, with parents in parent_conditions. | |
| 147 | + | |
| 148 | + // $testStr = ""; | |
| 149 | + // $testarr = array(); | |
| 150 | + // for ($i=0; $i<3; $i++) { | |
| 151 | + // $testarr[] = "( ? )"; | |
| 152 | + // } | |
| 153 | + // $testStr = "(".join(" OR ", $testarr).")"; | |
| 154 | + // return $testStr; | |
| 155 | + | |
| 156 | + // 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)) | |
| 157 | + $sParentClause = "md_chain.parent_condition IN ("; | |
| 158 | + $aInputParts = array(); | |
| 159 | + for ($i=0; $i<count($parent_conditions); $i++) { | |
| 160 | + if ($i == count($parent_conditions)-1) { | |
| 161 | + $sParentClause .= '?'; | |
| 162 | + } else { | |
| 163 | + $sParentClause .= '? ,'; | |
| 164 | + } | |
| 165 | + } | |
| 166 | + $sParentClause .= ')'; | |
| 167 | + | |
| 168 | + $aInputs = array(); | |
| 169 | + | |
| 170 | + foreach ($inputs as $fid => $lookid) { | |
| 171 | + $aInputs[] = $fid; | |
| 172 | + $aInputs[] = $lookid; | |
| 173 | + $aInputParts[] = '(md_cond.document_field_id = ? AND md_cond.metadata_lookup_id = ?)'; | |
| 174 | + } | |
| 175 | + $sInputs = join(" OR ", $aInputParts); | |
| 176 | + $sInputs = '(' . $sInputs . ')'; | |
| 177 | + | |
| 178 | + | |
| 179 | + $default->log->debug('validatePath: parent_conditions '.print_r($parent_conditions,true)); | |
| 180 | + | |
| 181 | + $sFieldClause = "md_cond.document_field_id IN ("; | |
| 182 | + for ($i=0; $i<count($free_field_ids); $i++) { | |
| 183 | + if ($i == count($free_field_ids)-1) { | |
| 184 | + $sFieldClause .= '?'; | |
| 185 | + } else { | |
| 186 | + $sFieldClause .= '? ,'; | |
| 187 | + } | |
| 188 | + } | |
| 189 | + $sFieldClause .= ')'; | |
| 190 | + $default->log->debug('validatePath: sParentClause '.print_r($sParentClause,true)); | |
| 191 | + | |
| 192 | + $sWhere = KTUtil::whereToString(array(array($sParentClause, array_keys($parent_conditions)), array($sInputs, $aInputs))); | |
| 193 | + $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 "; | |
| 194 | + $default->log->debug('validatePath: '.print_r(array($sQuery . $sWhere[0], $sWhere[1]),true)); | |
| 195 | + $res = DBUtil::getResultArray(array($sQuery . $sWhere[0], $sWhere[1])); | |
| 196 | + if (PEAR::isError($res)) { | |
| 197 | + return false; | |
| 198 | + } | |
| 199 | + | |
| 200 | + // if there's anything is $res, its a match (must be - we can't have crossed chains.) | |
| 201 | + if (count($res) == 0) { | |
| 202 | + return false; // fail - no matches from inputs against parent_conditions. | |
| 203 | + } else { | |
| 204 | + // we must have a match - MAY have multiple matches. | |
| 205 | + foreach ($res as $aRow) { | |
| 206 | + $default->log->debug('validatePath: output_row '.print_r($aRow,true)); | |
| 207 | + $parent_conditions[$aRow["rule_id"]] = 1; // add this as a possible parent condition. | |
| 208 | + unset($free_field_ids[$aRow["field_id"]]); // no longer free | |
| 209 | + unset($inputs[$aRow["field_id"]]); // no longer an un-processed input, so reduce the input-count. | |
| 210 | + } | |
| 211 | + } | |
| 212 | + } | |
| 213 | + | |
| 214 | + // ok: we got this far, and have run out of inputs without running out of matches. | |
| 215 | + // IF we're looking for a partial match, and still have free fields, return the set of free-and-parent matches. | |
| 216 | + // OTHERWISE if we have free fields, fail | |
| 217 | + // finally, pass the input as valid. | |
| 218 | + | |
| 219 | + if (($bPartial === true) and (count($free_field_ids) > 0)) { | |
| 220 | + // generate the set of matches for free_fields with appropriate parents. | |
| 221 | + // UNFORTUNATELY, there is no "nice" way to do this. | |
| 222 | + // Wax On. Wax Off. | |
| 223 | + | |
| 224 | + $sParentClause = "md_chain.parent_condition IN ("; | |
| 225 | + for ($i=0; $i<count($parent_conditions); $i++) { | |
| 226 | + if ($i == count($parent_conditions)-1) { | |
| 227 | + $sParentClause .= '?'; | |
| 228 | + } else { | |
| 229 | + $sParentClause .= '? ,'; | |
| 230 | + } | |
| 231 | + } | |
| 232 | + $sParentClause .= ')'; | |
| 233 | + $default->log->debug('validatePath: parent_conditions '.print_r($parent_conditions,true)); | |
| 234 | + | |
| 235 | + $sFieldClause = "md_cond.document_field_id IN ("; | |
| 236 | + for ($i=0; $i<count($free_field_ids); $i++) { | |
| 237 | + if ($i == count($free_field_ids)-1) { | |
| 238 | + $sFieldClause .= '?'; | |
| 239 | + } else { | |
| 240 | + $sFieldClause .= '? ,'; | |
| 241 | + } | |
| 242 | + } | |
| 243 | + $sFieldClause .= ')'; | |
| 244 | + $default->log->debug('validatePath: sParentClause '.print_r($sParentClause,true)); | |
| 245 | + | |
| 246 | + $aWhere = KTUtil::whereToString(array(array($sParentClause, array_keys($parent_conditions)), array($sFieldClause,array_keys($free_field_ids)))); | |
| 247 | + $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 "; | |
| 248 | + $default->log->debug('validatePath: sParentClause '.print_r(array($sQuery . $aWhere[0], $aWhere[1]), true)); | |
| 249 | + $sOrderClause = " ORDER BY document_field_id ASC, name ASC"; | |
| 250 | + return DBUtil::getResultArray(array($sQuery . $aWhere[0] . $sOrderClause, $aWhere[1])); // FIXME catch errors? | |
| 251 | + } else if (count($free_field_ids) != 0) { | |
| 252 | + return false; // incomplete - could actually catch this at the start. | |
| 253 | + } else { | |
| 254 | + return true; // note - this ALSO matches whenever $bPartial is true, but we have completed. UP THE STACK: true => valid and committable. | |
| 255 | + } | |
| 256 | + } | |
| 257 | + | |
| 258 | + // FIXME: this need s to move into MDCondition.inc, or manageConditionalMetadata.php | |
| 259 | + // actually, this needs to die - its DEBUG only, really. | |
| 260 | + function do_createCondition() { | |
| 261 | + global $default; | |
| 262 | + $fieldset_id = KTUtil::arrayGet($_REQUEST, 'fieldset_id'); | |
| 263 | + $parent_id = KTUtil::arrayGet($_REQUEST, 'parent_id'); | |
| 264 | + $field_id = KTUtil::arrayGet($_REQUEST, 'field_id'); | |
| 265 | + $lookup_id = KTUtil::arrayGet($_REQUEST, 'lookup_id'); | |
| 266 | + | |
| 267 | + $resObj = MDConditionNode::createFromArray(array( | |
| 268 | + "iFieldId" => $field_id, | |
| 269 | + "iLookupId" => $lookup_id, | |
| 270 | + )); | |
| 271 | + | |
| 272 | + $default->log->debug("CREATE_CONDITION_DEBUG: ".print_r($resObj,true)); | |
| 273 | + | |
| 274 | + $resObj2 = MDConditionChain::createFromArray(array( | |
| 275 | + "iParentCondition" => $parent_id, // may be null. | |
| 276 | + "iChildCondition" => $resObj->getId(), | |
| 277 | + )); | |
| 278 | + | |
| 279 | + $default->log->debug("CREATE_CONDITION_DEBUG: ".print_r($resObj2,true)); | |
| 280 | + } | |
| 281 | + | |
| 282 | +} | |
| 283 | + | |
| 284 | +$oDispatcher = new HandleConditionalDispatcher(); | |
| 285 | +$oDispatcher->dispatch(); | |
| 286 | + | |
| 287 | +?> | ... | ... |