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,6 +138,8 @@ $default->siteMap->addPage("docLinkManagement", "/presentation/lookAndFeel/knowl | ||
| 138 | $default->siteMap->addPage("manageHelp", "/presentation/lookAndFeel/knowledgeTree/administration/help/manageHelp.php", "Administration", SysAdmin, _("Help Administration"), true, 17); | 138 | $default->siteMap->addPage("manageHelp", "/presentation/lookAndFeel/knowledgeTree/administration/help/manageHelp.php", "Administration", SysAdmin, _("Help Administration"), true, 17); |
| 139 | 139 | ||
| 140 | $default->siteMap->addPage("managePermissions", "/presentation/lookAndFeel/knowledgeTree/administration/permissions/managePermissions.php", "Administration", SysAdmin, _("Permissions Administration"), true, 18); | 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 | $default->siteMap->addSectionColour("Administration", "th", "056DCE"); | 144 | $default->siteMap->addSectionColour("Administration", "th", "056DCE"); |
| 143 | $default->siteMap->addSectionColour("Administration", "td", "6699FF"); | 145 | $default->siteMap->addSectionColour("Administration", "td", "6699FF"); |
config/tableMappings.inc
| @@ -28,6 +28,8 @@ $default->sessions_table = "active_sessions"; | @@ -28,6 +28,8 @@ $default->sessions_table = "active_sessions"; | ||
| 28 | $default->data_types_table ="data_types"; | 28 | $default->data_types_table ="data_types"; |
| 29 | // document type fields | 29 | // document type fields |
| 30 | $default->document_fields_table = "document_fields"; | 30 | $default->document_fields_table = "document_fields"; |
| 31 | +// document type fields | ||
| 32 | +$default->document_fieldset_table = "document_fieldsets"; | ||
| 31 | // links document | 33 | // links document |
| 32 | $default->document_fields_link_table = "document_fields_link"; | 34 | $default->document_fields_link_table = "document_fields_link"; |
| 33 | // document subscriptions | 35 | // document subscriptions |
| @@ -38,6 +40,8 @@ $default->transaction_types_table = "document_transaction_types_lookup"; | @@ -38,6 +40,8 @@ $default->transaction_types_table = "document_transaction_types_lookup"; | ||
| 38 | $default->document_transactions_table = "document_transactions"; | 40 | $default->document_transactions_table = "document_transactions"; |
| 39 | // links document types to document type fields | 41 | // links document types to document type fields |
| 40 | $default->document_type_fields_table = "document_type_fields_link"; | 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 | // document type information | 45 | // document type information |
| 42 | $default->document_types_table = "document_types_lookup"; | 46 | $default->document_types_table = "document_types_lookup"; |
| 43 | // stores documents | 47 | // stores documents |
| @@ -122,4 +126,8 @@ $default->permission_descriptor_groups_table = "permission_descriptor_groups"; | @@ -122,4 +126,8 @@ $default->permission_descriptor_groups_table = "permission_descriptor_groups"; | ||
| 122 | $default->permission_lookups_table = "permission_lookups"; | 126 | $default->permission_lookups_table = "permission_lookups"; |
| 123 | $default->permission_lookup_assignments_table = "permission_lookup_assignments"; | 127 | $default->permission_lookup_assignments_table = "permission_lookup_assignments"; |
| 124 | $default->groups_groups_table = "groups_groups_link"; | 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,125 +28,39 @@ require_once("$default->fileSystemRoot/lib/documentmanagement/DocumentType.inc") | ||
| 28 | class DocumentField extends KTEntity { | 28 | class DocumentField extends KTEntity { |
| 29 | 29 | ||
| 30 | /** primary key value */ | 30 | /** primary key value */ |
| 31 | - var $iId; | ||
| 32 | - /** document field name */ | 31 | + var $iId = -1; |
| 33 | var $sName; | 32 | var $sName; |
| 34 | - /** document field data type */ | ||
| 35 | var $sDataType; | 33 | var $sDataType; |
| 36 | - /** is_generic */ | ||
| 37 | var $bIsGeneric; | 34 | var $bIsGeneric; |
| 38 | - /**has lookup*/ | ||
| 39 | var $bHasLookup; | 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 | $this->iId = -1; | 42 | $this->iId = -1; |
| 51 | $this->sName = $sNewName; | 43 | $this->sName = $sNewName; |
| 52 | $this->sDataType = $sNewDataType; | 44 | $this->sDataType = $sNewDataType; |
| 53 | $this->bIsGeneric = $bNewIsGeneric; | 45 | $this->bIsGeneric = $bNewIsGeneric; |
| 54 | $this->bHasLookup = $bNewHasLookup; | 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 | function _fieldValues () { | 65 | function _fieldValues () { |
| 152 | return array( | 66 | return array( |
| @@ -154,6 +68,8 @@ class DocumentField extends KTEntity { | @@ -154,6 +68,8 @@ class DocumentField extends KTEntity { | ||
| 154 | 'data_type' => $this->sDataType, | 68 | 'data_type' => $this->sDataType, |
| 155 | 'is_generic' => KTUtil::anyToBool($this->bIsGeneric), | 69 | 'is_generic' => KTUtil::anyToBool($this->bIsGeneric), |
| 156 | 'has_lookup' => KTUtil::anyToBool($this->bHasLookup), | 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,7 +77,16 @@ class DocumentField extends KTEntity { | ||
| 161 | global $default; | 77 | global $default; |
| 162 | return $default->document_fields_table; | 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 | * Static function. | 91 | * Static function. |
| 167 | * Given a document_fields primary key it will create a | 92 | * Given a document_fields primary key it will create a |
| @@ -178,6 +103,8 @@ class DocumentField extends KTEntity { | @@ -178,6 +103,8 @@ class DocumentField extends KTEntity { | ||
| 178 | if ($sql->next_record()) { | 103 | if ($sql->next_record()) { |
| 179 | $oDocumentField = & new DocumentField($sql->f("name"), $sql->f("data_type"), (bool)$sql->f("is_generic"), (bool)$sql->f("has_lookup")); | 104 | $oDocumentField = & new DocumentField($sql->f("name"), $sql->f("data_type"), (bool)$sql->f("is_generic"), (bool)$sql->f("has_lookup")); |
| 180 | $oDocumentField->iId = $sql->f("id"); | 105 | $oDocumentField->iId = $sql->f("id"); |
| 106 | + $oDocumentField->iParentFieldset = $sql->f("parent_fieldset"); | ||
| 107 | + $oDocumentField->bHasLookupTree = (bool)$sql->f("has_lookuptree"); | ||
| 181 | return $oDocumentField; | 108 | return $oDocumentField; |
| 182 | } | 109 | } |
| 183 | $_SESSION["errorMessage"] = $lang_err_object_not_exist . "id = " . $iDocumentID . " table = $default->document_fields_table"; | 110 | $_SESSION["errorMessage"] = $lang_err_object_not_exist . "id = " . $iDocumentID . " table = $default->document_fields_table"; |
| @@ -187,16 +114,6 @@ class DocumentField extends KTEntity { | @@ -187,16 +114,6 @@ class DocumentField extends KTEntity { | ||
| 187 | return false; | 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 | * Returns the DocumentTypes mapped to this document field | 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,11 +27,13 @@ | ||
| 27 | class MetaData extends KTEntity { | 27 | class MetaData extends KTEntity { |
| 28 | 28 | ||
| 29 | /** primary key value */ | 29 | /** primary key value */ |
| 30 | - var $iId; | 30 | + var $iId = -1; |
| 31 | //document field id | 31 | //document field id |
| 32 | var $iDocFieldId; | 32 | var $iDocFieldId; |
| 33 | /** MetaData name */ | 33 | /** MetaData name */ |
| 34 | var $sName; | 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 | * Default constructor | 39 | * Default constructor |
| @@ -40,68 +42,28 @@ class MetaData extends KTEntity { | @@ -40,68 +42,28 @@ class MetaData extends KTEntity { | ||
| 40 | * @param MetaData data type | 42 | * @param MetaData data type |
| 41 | * | 43 | * |
| 42 | */ | 44 | */ |
| 43 | - function MetaData($iNewDocFieldID,$sNewName) { | 45 | + function MetaData($iNewDocFieldID = null,$sNewName = null, $iNewParent = null) { |
| 44 | //object not created yet | 46 | //object not created yet |
| 45 | $this->iId = -1; | 47 | $this->iId = -1; |
| 46 | $this->iDocFieldID = $iNewDocFieldID; | 48 | $this->iDocFieldID = $iNewDocFieldID; |
| 47 | $this->sName = $sNewName; | 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 | function _fieldValues () { | 62 | function _fieldValues () { |
| 102 | return array( | 63 | return array( |
| 103 | 'document_field_id' => $this->iDocFieldID, | 64 | 'document_field_id' => $this->iDocFieldID, |
| 104 | 'name' => $this->sName, | 65 | 'name' => $this->sName, |
| 66 | + 'treeorg_parent' => $this->iTreeParent, | ||
| 105 | ); | 67 | ); |
| 106 | } | 68 | } |
| 107 | 69 | ||
| @@ -152,6 +114,7 @@ class MetaData extends KTEntity { | @@ -152,6 +114,7 @@ class MetaData extends KTEntity { | ||
| 152 | if ($sql->next_record()) { | 114 | if ($sql->next_record()) { |
| 153 | $oDocumentType = & new MetaData($sql->f("document_field_id"),$sql->f("name")); | 115 | $oDocumentType = & new MetaData($sql->f("document_field_id"),$sql->f("name")); |
| 154 | $oDocumentType->iId = $sql->f("id"); | 116 | $oDocumentType->iId = $sql->f("id"); |
| 117 | + $oDocumentType->iTreeParent = $sql->f("treeorg_parent"); | ||
| 155 | return $oDocumentType; | 118 | return $oDocumentType; |
| 156 | } | 119 | } |
| 157 | $_SESSION["errorMessage"] = $lang_err_object_not_exist . "id = " . $iDocumentID . " table = document_types"; | 120 | $_SESSION["errorMessage"] = $lang_err_object_not_exist . "id = " . $iDocumentID . " table = document_types"; |
lib/visualpatterns/PatternMetaData.inc
| 1 | <?php | 1 | <?php |
| 2 | 2 | ||
| 3 | require_once("PatternListBox.inc"); | 3 | require_once("PatternListBox.inc"); |
| 4 | +require_once(KT_LIB_DIR . "/documentmanagement/MDTree.inc"); | ||
| 5 | + | ||
| 4 | /** | 6 | /** |
| 5 | * $Id$ | 7 | * $Id$ |
| 6 | * | 8 | * |
| @@ -44,12 +46,12 @@ class PatternMetaData { | @@ -44,12 +46,12 @@ class PatternMetaData { | ||
| 44 | 46 | ||
| 45 | function render() { | 47 | function render() { |
| 46 | global $default; | 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 | $sql = $default->db; | 51 | $sql = $default->db; |
| 50 | $sql->query($sQuery); | 52 | $sql->query($sQuery); |
| 51 | if ($sql->next_record()) { | 53 | if ($sql->next_record()) { |
| 52 | - if ($sql->f("has_lookup")) { | 54 | + if ($sql->f("has_lookup") and (!$sql->f("has_lookuptree"))) { |
| 53 | //is a lookup, so display a drop down list | 55 | //is a lookup, so display a drop down list |
| 54 | $sWhereClause = "DF.name LIKE '" . $this->sMetaDataField . "'"; | 56 | $sWhereClause = "DF.name LIKE '" . $this->sMetaDataField . "'"; |
| 55 | $sFromClause = "INNER JOIN $default->document_fields_table AS DF ON ST.document_field_id = DF.id"; | 57 | $sFromClause = "INNER JOIN $default->document_fields_table AS DF ON ST.document_field_id = DF.id"; |
| @@ -60,6 +62,10 @@ class PatternMetaData { | @@ -60,6 +62,10 @@ class PatternMetaData { | ||
| 60 | $oPatternListBox->setFromClause($sFromClause); | 62 | $oPatternListBox->setFromClause($sFromClause); |
| 61 | $oPatternListBox->setWhereClause($sWhereClause); | 63 | $oPatternListBox->setWhereClause($sWhereClause); |
| 62 | return $oPatternListBox->render(); | 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 | } else { | 69 | } else { |
| 64 | $textboxlength = null; | 70 | $textboxlength = null; |
| 65 | switch($sql->f("data_type")) { | 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 | +?> |