Commit 26e9877a353ba216bdc92b4988380d8bded464e1

Authored by Neil Blakey-Milner
1 parent f7807987

Integrate Manage Lookup Trees into document field management.


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@4462 c91229c3-7414-0410-bfa2-8a42b809f60b
plugins/ktcore/admin/documentFields.php
... ... @@ -537,6 +537,206 @@ class KTDocumentFieldDispatcher extends KTStandardDispatcher {
537 537 $this->successRedirectToMain(_('Fieldset deleted'));
538 538 }
539 539 // }}}
  540 +
  541 +
  542 +// {{{ TREE
  543 + // create and display the tree editing form.
  544 + function do_editTree() {
  545 + global $default;
  546 + // extract.
  547 + $field_id = KTUtil::arrayGet($_REQUEST, 'field_id');
  548 + $current_node = KTUtil::arrayGet($_REQUEST, 'current_node', 0);
  549 + $subaction = KTUtil::arrayGet($_REQUEST, 'subaction');
  550 +
  551 + // validate
  552 + if (empty($field_id)) { return $this->errorRedirectToMain(_("Must select a field to edit.")); }
  553 + $oField =& DocumentField::get($field_id);
  554 + if (PEAR::isError($oField)) { return $this->errorRedirectToMain(_("Invalid field.")); }
  555 +
  556 + // under here we do the subaction rendering.
  557 + // we do this so we don't have to do _very_ strange things with multiple actions.
  558 + //$default->log->debug("Subaction: " . $subaction);
  559 + $fieldTree =& new MDTree();
  560 + $fieldTree->buildForField($oField->getId());
  561 +
  562 + if ($subaction !== null) {
  563 + $target = 'editTree';
  564 + $msg = _('Changes saved.');
  565 + if ($subaction === "addCategory") {
  566 + $new_category = KTUtil::arrayGet($_REQUEST, 'category_name');
  567 + if (empty($new_category)) { return $this->errorRedirectTo("editTree", _("Must enter a name for the new category."), array("field_id" => $field_id)); }
  568 + else { $this->subact_addCategory($field_id, $current_node, $new_category, $fieldTree);}
  569 + $msg = _('Category added'). ': ' . $new_category;
  570 + }
  571 + if ($subaction === "deleteCategory") {
  572 + $this->subact_deleteCategory($fieldTree, $current_node);
  573 + $current_node = 0; // clear out, and don't try and render the newly deleted category.
  574 + $msg = _('Category removed.');
  575 + }
  576 + if ($subaction === "linkKeywords") {
  577 + $keywords = KTUtil::arrayGet($_REQUEST, 'keywordsToAdd');
  578 + $this->subact_linkKeywords($fieldTree, $current_node, $keywords);
  579 + $current_node = 0; // clear out, and don't try and render the newly deleted category.
  580 + $msg = _('Keywords added to category.');
  581 + }
  582 + if ($subaction === "unlinkKeyword") {
  583 + $keyword = KTUtil::arrayGet($_REQUEST, 'keyword_id');
  584 + $this->subact_unlinkKeyword($fieldTree, $keyword);
  585 + $msg = _('Keyword moved to base of tree.');
  586 + }
  587 + // now redirect
  588 + $query = 'field_id=' . $field_id;
  589 + return $this->successRedirectTo($target, $msg, $query);
  590 + }
  591 +
  592 + if ($fieldTree->root === null) {
  593 + return $this->errorRedirectToMain(_("Error building tree. Is this a valid tree-lookup field?"));
  594 + }
  595 +
  596 + // FIXME extract this from MDTree (helper method?)
  597 + $free_metadata = MetaData::getList('document_field_id = '.$oField->getId().' AND (treeorg_parent = 0 OR treeorg_parent IS NULL)');
  598 +
  599 + // render edit template.
  600 + $oTemplating = new KTTemplating;
  601 + $oTemplate = $oTemplating->loadTemplate("ktcore/edit_lookuptrees");
  602 + $renderedTree = $this->_evilTreeRenderer($fieldTree);
  603 +
  604 + $this->oPage->setTitle(_('Edit Lookup Tree'));
  605 +
  606 + //$this->oPage->requireJSResource('thirdparty/js/MochiKit/Base.js');
  607 +
  608 + $aTemplateData = array(
  609 + "field" => $oField,
  610 + "tree" => $fieldTree,
  611 + "renderedTree" => $renderedTree,
  612 + "currentNode" => $current_node,
  613 + "freechildren" => $free_metadata,
  614 + "context" => $this,
  615 + );
  616 + return $oTemplate->render($aTemplateData);
  617 + }
  618 +
  619 + function subact_addCategory($field_id, $current_node, $new_category, &$constructedTree) {
  620 + $newCategory = MDTreeNode::createFromArray(array (
  621 + "iFieldId" => $field_id,
  622 + "sName" => $new_category,
  623 + "iParentNode" => $current_node,
  624 + ));
  625 + if (PEAR::isError($newCategory))
  626 + {
  627 + return false;
  628 + }
  629 + $constructedTree->addNode($newCategory);
  630 + return true;
  631 + }
  632 +
  633 + function subact_deleteCategory(&$constructedTree, $current_node) {
  634 + $constructedTree->deleteNode($current_node);
  635 + return true;
  636 + }
  637 +
  638 + function subact_unlinkKeyword(&$constructedTree, $keyword) {
  639 + $oKW = MetaData::get($keyword);
  640 + $constructedTree->reparentKeyword($oKW->getId(), 0);
  641 + return true;
  642 + }
  643 +
  644 +
  645 + function subact_linkKeywords(&$constructedTree, $current_node, $keywords) {
  646 + foreach ($keywords as $md_id)
  647 + {
  648 + $constructedTree->reparentKeyword($md_id, $current_node);
  649 + }
  650 + return true;
  651 + }
  652 +
  653 + /* ----------------------- EVIL HACK --------------------------
  654 + *
  655 + * This whole thing needs to replaced, as soon as I work out how
  656 + * to non-sucking Smarty recursion.
  657 + */
  658 +
  659 + function _evilTreeRecursion($subnode, $treeToRender)
  660 + {
  661 + $treeStr = "<ul>";
  662 + foreach ($treeToRender->contents[$subnode] as $subnode_id => $subnode_val)
  663 + {
  664 + if ($subnode_id !== "leaves") {
  665 + $treeStr .= '<li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">' . $treeToRender->mapnodes[$subnode_val]->getName() . '</a>';
  666 + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, false, $subnode_val);
  667 + $treeStr .= $this->_evilTreeRecursion($subnode_val, $treeToRender);
  668 + $treeStr .= '</li>';
  669 + }
  670 + else
  671 + {
  672 + foreach ($subnode_val as $leaf)
  673 + {
  674 + $treeStr .= '<li class="leafnode">' . $treeToRender->lookups[$leaf]->getName();
  675 + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, true, $leaf);
  676 + $treeStr .= '</li>'; }
  677 + }
  678 + }
  679 + $treeStr .= '</ul>';
  680 + return $treeStr;
  681 +
  682 + }
  683 +
  684 + // I can't seem to do recursion in smarty, and recursive templates seems a bad solution.
  685 + // Come up with a better way to do this (? NBM)
  686 + function _evilTreeRenderer($treeToRender) {
  687 + //global $default;
  688 + $treeStr = "<!-- this is rendered with an unholy hack. sorry. -->";
  689 + $stack = array();
  690 + $exitstack = array();
  691 +
  692 + // since the root is virtual, we need to fake it here.
  693 + // the inner section is generised.
  694 + $treeStr .= '<ul class="kt_treenodes"><li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">Root</a>';
  695 + $treeStr .= ' (<a href="?action=editTree&field_id='.$treeToRender->field_id.'&current_node=0">edit</a>)';
  696 + $treeStr .= '<ul>';
  697 + //$default->log->debug("EVILRENDER: " . print_r($treeToRender, true));
  698 + foreach ($treeToRender->getRoot() as $node_id => $subtree_nodes)
  699 + {
  700 + //$default->log->debug("EVILRENDER: ".$node_id." => ".$subtree_nodes." (".($node_id === "leaves").")");
  701 + // leaves are handled differently.
  702 + if ($node_id !== "leaves") {
  703 + // $default->log->debug("EVILRENDER: " . print_r($subtree_nodes, true));
  704 + $treeStr .= '<li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">' . $treeToRender->mapnodes[$subtree_nodes]->getName() . '</a>';
  705 + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, false, $subtree_nodes);
  706 + $treeStr .= $this->_evilTreeRecursion($subtree_nodes, $treeToRender);
  707 + $treeStr .= '</li>';
  708 + }
  709 + else
  710 + {
  711 + foreach ($subtree_nodes as $leaf)
  712 + {
  713 + $treeStr .= '<li class="leafnode">' . $treeToRender->lookups[$leaf]->getName();
  714 + $treeStr .= $this->_evilActionHelper($treeToRender->field_id, true, $leaf);
  715 + $treeStr .= '</li>';
  716 + }
  717 + }
  718 + }
  719 + $treeStr .= '</ul></li>';
  720 + $treeStr .= '</ul>';
  721 +
  722 + return $treeStr;
  723 + }
  724 +
  725 + // don't hate me.
  726 + function _evilActionHelper($iFieldId, $bIsKeyword, $current_node) {
  727 + $actionStr = " (";
  728 + if ($bIsKeyword === true) {
  729 + $actionStr .= '<a href="?action=editTree&field_id='.$iFieldId.'&keyword_id='.$current_node.'&subaction=unlinkKeyword">unlink</a>';
  730 + }
  731 + else
  732 + {
  733 + $actionStr .= '<a href="?action=editTree&field_id='.$iFieldId.'&current_node='.$current_node.'">add items</a> ';
  734 + $actionStr .= '| <a href="?action=editTree&field_id='.$iFieldId.'&current_node='.$current_node.'&subaction=deleteCategory">delete</a>';
  735 + }
  736 + $actionStr .= ")";
  737 + return $actionStr;
  738 + }
  739 +// }}}
540 740 }
541 741  
542 742 ?>
... ...
plugins/ktcore/admin/manageLookupTrees.php deleted
1   -<?php
2   -
3   -require_once("../../../../../config/dmsDefaults.php");
4   -
5   -
6   -
7   -require_once(KT_LIB_DIR . "/templating/templating.inc.php");
8   -require_once(KT_LIB_DIR . "/templating/kt3template.inc.php");
9   -
10   -require_once(KT_LIB_DIR . "/documentmanagement/DocumentField.inc");
11   -require_once(KT_LIB_DIR . "/documentmanagement/MetaData.inc");
12   -require_once(KT_LIB_DIR . "/documentmanagement/MDTree.inc");
13   -require_once(KT_LIB_DIR . "/dispatcher.inc.php");
14   -
15   -class ManageLookupTreeDispatcher extends KTAdminDispatcher {
16   - function do_main() {
17   - $oTemplating = new KTTemplating;
18   - $aTreeFields =& DocumentField::getList('has_lookuptree = 1');
19   - $aLookupFields =& DocumentField::getList('has_lookup = 1 AND (has_lookuptree IS NULL or has_lookuptree = 0)');
20   - $oTemplate = $oTemplating->loadTemplate("ktcore/manage_lookuptrees");
21   - $aTemplateData = array(
22   - "treefields" => $aTreeFields,
23   - "lookupfields" => $aLookupFields,
24   - );
25   - return $oTemplate->render($aTemplateData);
26   - }
27   -
28   - function do_createTree() {
29   - // extract.
30   - $field_id = KTUtil::arrayGet($_REQUEST, 'field_id');
31   -
32   - // validate
33   - if (empty($field_id)) { return $this->errorRedirectToMain(_("Must select a field to convert.")); }
34   - $oField =& DocumentField::get($field_id);
35   - if (PEAR::isError($oField)) { return $this->errorRedirectToMain(_("Invalid field.")); }
36   -
37   - // set as a metadata tree.
38   - $oField->setHasLookupTree(1);
39   - $oField->update();
40   - $this->errorRedirectToMain(sprintf(_("Converted %s to a tree."), $oField->getName()));
41   - }
42   -
43   -
44   - // create and display the tree editing form.
45   - function do_editTree() {
46   - global $default;
47   - // extract.
48   - $field_id = KTUtil::arrayGet($_REQUEST, 'field_id');
49   - $current_node = KTUtil::arrayGet($_REQUEST, 'current_node', 0);
50   - $subaction = KTUtil::arrayGet($_REQUEST, 'subaction');
51   -
52   - // validate
53   - if (empty($field_id)) { return $this->errorRedirectToMain(_("Must select a field to edit.")); }
54   - $oField =& DocumentField::get($field_id);
55   - if (PEAR::isError($oField)) { return $this->errorRedirectToMain(_("Invalid field.")); }
56   -
57   - // under here we do the subaction rendering.
58   - // we do this so we don't have to do _very_ strange things with multiple actions.
59   - //$default->log->debug("Subaction: " . $subaction);
60   - $fieldTree =& new MDTree();
61   - $fieldTree->buildForField($oField->getId());
62   -
63   - if ($subaction !== null) {
64   - $target = 'editTree';
65   - $msg = _('Changes saved.');
66   - if ($subaction === "addCategory") {
67   - $new_category = KTUtil::arrayGet($_REQUEST, 'category_name');
68   - if (empty($new_category)) { return $this->errorRedirectTo("editTree", _("Must enter a name for the new category."), array("field_id" => $field_id)); }
69   - else { $this->subact_addCategory($field_id, $current_node, $new_category, $fieldTree);}
70   - $msg = _('Category added'). ': ' . $new_category;
71   - }
72   - if ($subaction === "deleteCategory") {
73   - $this->subact_deleteCategory($fieldTree, $current_node);
74   - $current_node = 0; // clear out, and don't try and render the newly deleted category.
75   - $msg = _('Category removed.');
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   - $msg = _('Keywords added to category.');
82   - }
83   - if ($subaction === "unlinkKeyword") {
84   - $keyword = KTUtil::arrayGet($_REQUEST, 'keyword_id');
85   - $this->subact_unlinkKeyword($fieldTree, $keyword);
86   - $msg = _('Keyword moved to base of tree.');
87   - }
88   - // now redirect
89   - $query = 'field_id=' . $field_id;
90   - return $this->successRedirectTo($target, $msg, $query);
91   - }
92   -
93   - if ($fieldTree->root === null) {
94   - return $this->errorRedirectToMain(_("Error building tree. Is this a valid tree-lookup field?"));
95   - }
96   -
97   - // FIXME extract this from MDTree (helper method?)
98   - $free_metadata = MetaData::getList('document_field_id = '.$oField->getId().' AND (treeorg_parent = 0 OR treeorg_parent IS NULL)');
99   -
100   - // render edit template.
101   - $oTemplating = new KTTemplating;
102   - $oTemplate = $oTemplating->loadTemplate("ktcore/edit_lookuptrees");
103   - $renderedTree = $this->_evilTreeRenderer($fieldTree);
104   -
105   - $this->oPage->setTitle(_('Edit Lookup Tree'));
106   -
107   - //$this->oPage->requireJSResource('thirdparty/js/MochiKit/Base.js');
108   -
109   - $aTemplateData = array(
110   - "field" => $oField,
111   - "tree" => $fieldTree,
112   - "renderedTree" => $renderedTree,
113   - "currentNode" => $current_node,
114   - "freechildren" => $free_metadata,
115   - "context" => $this,
116   - );
117   - return $oTemplate->render($aTemplateData);
118   - }
119   -
120   - function subact_addCategory($field_id, $current_node, $new_category, &$constructedTree) {
121   - $newCategory = MDTreeNode::createFromArray(array (
122   - "iFieldId" => $field_id,
123   - "sName" => $new_category,
124   - "iParentNode" => $current_node,
125   - ));
126   - if (PEAR::isError($newCategory))
127   - {
128   - return false;
129   - }
130   - $constructedTree->addNode($newCategory);
131   - return true;
132   - }
133   -
134   - function subact_deleteCategory(&$constructedTree, $current_node) {
135   - $constructedTree->deleteNode($current_node);
136   - return true;
137   - }
138   -
139   - function subact_unlinkKeyword(&$constructedTree, $keyword) {
140   - $oKW = MetaData::get($keyword);
141   - $constructedTree->reparentKeyword($oKW->getId(), 0);
142   - return true;
143   - }
144   -
145   -
146   - function subact_linkKeywords(&$constructedTree, $current_node, $keywords) {
147   - foreach ($keywords as $md_id)
148   - {
149   - $constructedTree->reparentKeyword($md_id, $current_node);
150   - }
151   - return true;
152   - }
153   -
154   - /* ----------------------- EVIL HACK --------------------------
155   - *
156   - * This whole thing needs to replaced, as soon as I work out how
157   - * to non-sucking Smarty recursion.
158   - */
159   -
160   - function _evilTreeRecursion($subnode, $treeToRender)
161   - {
162   - $treeStr = "<ul>";
163   - foreach ($treeToRender->contents[$subnode] as $subnode_id => $subnode_val)
164   - {
165   - if ($subnode_id !== "leaves") {
166   - $treeStr .= '<li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">' . $treeToRender->mapnodes[$subnode_val]->getName() . '</a>';
167   - $treeStr .= $this->_evilActionHelper($treeToRender->field_id, false, $subnode_val);
168   - $treeStr .= $this->_evilTreeRecursion($subnode_val, $treeToRender);
169   - $treeStr .= '</li>';
170   - }
171   - else
172   - {
173   - foreach ($subnode_val as $leaf)
174   - {
175   - $treeStr .= '<li class="leafnode">' . $treeToRender->lookups[$leaf]->getName();
176   - $treeStr .= $this->_evilActionHelper($treeToRender->field_id, true, $leaf);
177   - $treeStr .= '</li>'; }
178   - }
179   - }
180   - $treeStr .= '</ul>';
181   - return $treeStr;
182   -
183   - }
184   -
185   - // I can't seem to do recursion in smarty, and recursive templates seems a bad solution.
186   - // Come up with a better way to do this (? NBM)
187   - function _evilTreeRenderer($treeToRender) {
188   - //global $default;
189   - $treeStr = "<!-- this is rendered with an unholy hack. sorry. -->";
190   - $stack = array();
191   - $exitstack = array();
192   -
193   - // since the root is virtual, we need to fake it here.
194   - // the inner section is generised.
195   - $treeStr .= '<ul class="kt_treenodes"><li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">Root</a>';
196   - $treeStr .= ' (<a href="manageLookupTrees.php?action=editTree&field_id='.$treeToRender->field_id.'&current_node=0">edit</a>)';
197   - $treeStr .= '<ul>';
198   - //$default->log->debug("EVILRENDER: " . print_r($treeToRender, true));
199   - foreach ($treeToRender->getRoot() as $node_id => $subtree_nodes)
200   - {
201   - //$default->log->debug("EVILRENDER: ".$node_id." => ".$subtree_nodes." (".($node_id === "leaves").")");
202   - // leaves are handled differently.
203   - if ($node_id !== "leaves") {
204   - // $default->log->debug("EVILRENDER: " . print_r($subtree_nodes, true));
205   - $treeStr .= '<li class="treenode"><a class="pathnode" onclick="toggleElementClass(\'active\', this.parentNode);">' . $treeToRender->mapnodes[$subtree_nodes]->getName() . '</a>';
206   - $treeStr .= $this->_evilActionHelper($treeToRender->field_id, false, $subtree_nodes);
207   - $treeStr .= $this->_evilTreeRecursion($subtree_nodes, $treeToRender);
208   - $treeStr .= '</li>';
209   - }
210   - else
211   - {
212   - foreach ($subtree_nodes as $leaf)
213   - {
214   - $treeStr .= '<li class="leafnode">' . $treeToRender->lookups[$leaf]->getName();
215   - $treeStr .= $this->_evilActionHelper($treeToRender->field_id, true, $leaf);
216   - $treeStr .= '</li>';
217   - }
218   - }
219   - }
220   - $treeStr .= '</ul></li>';
221   - $treeStr .= '</ul>';
222   -
223   - return $treeStr;
224   - }
225   -
226   - // don't hate me.
227   - function _evilActionHelper($iFieldId, $bIsKeyword, $current_node) {
228   - $actionStr = " (";
229   - if ($bIsKeyword === true) {
230   - $actionStr .= '<a href="manageLookupTrees.php?action=editTree&field_id='.$iFieldId.'&keyword_id='.$current_node.'&subaction=unlinkKeyword">unlink</a>';
231   - }
232   - else
233   - {
234   - $actionStr .= '<a href="manageLookupTrees.php?action=editTree&field_id='.$iFieldId.'&current_node='.$current_node.'">add items</a> ';
235   - $actionStr .= '| <a href="manageLookupTrees.php?action=editTree&field_id='.$iFieldId.'&current_node='.$current_node.'&subaction=deleteCategory">delete</a>';
236   - }
237   - $actionStr .= ")";
238   - return $actionStr;
239   - }
240   -
241   -}
242   -
243   -$oDispatcher = new ManageLookupTreeDispatcher();
244   -$oDispatcher->dispatch();
245   -
246   -?>
templates/ktcore/metadata/editField.smarty
... ... @@ -52,7 +52,7 @@
52 52 {if $oField->getHasLookup() and $oField->getHasLookupTree()}
53 53 {assign var=iFieldId value=$oField->getId()}
54 54 <a
55   -href="{"manageLookupTrees"|generateControllerUrl:"action=editTree&field_id=$iFieldId"}">{i18n}Manage
  55 +href="?action=editTree&field_id={$iFieldId}">{i18n}Manage
56 56 lookup tree{/i18n}</a>
57 57 {/if}
58 58  
... ...