advanced_search.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <?php
  2. // By Rom
  3. require_once('../application/nicewebpage.class.inc.php');
  4. require_once('../application/dialogstack.class.inc.php');
  5. require_once('../application/startup.inc.php');
  6. // #@# not used, but... require_once('../classes/usercontext.class.inc.php');
  7. $oPage = new nice_web_page("ITop finder");
  8. $oPage->no_cache();
  9. MetaModel::CheckDefinitions();
  10. // new API - MetaModel::DBCheckFormat();
  11. // not necessary, and time consuming!
  12. // MetaModel::DBCheckIntegrity();
  13. function ReadParam($sName, $defaultValue = "")
  14. {
  15. return isset($_REQUEST[$sName]) ? $_REQUEST[$sName] : $defaultValue;
  16. }
  17. function Page1_AskClass($oPage)
  18. {
  19. $oPage->add("<form method=\"post\" action=\"\">\n");
  20. //$oPage->add("<input type=\"hidden\" name=\"tnut\" value=\"blah\">");
  21. $oPage->p("Please select the type of object that you want to look for:");
  22. $oPage->MakeClassesSelect("class", "", 50, UR_ACTION_READ);
  23. $oPage->add("<input type=\"submit\" name=\"userconfig\" value=\"Configure filters\">\n");
  24. $oPage->add("</form>\n");
  25. }
  26. function Page2_ConfigFilters($oPage, $oFilter)
  27. {
  28. $sClass = $oFilter->GetClass();
  29. $oPage->p("Objects of class <em>$sClass</em>");
  30. $oPage->add("<form method=\"post\" action=\"\">\n");
  31. $oPage->add("<input type=\"hidden\" name=\"class\" value=\"$sClass\">\n");
  32. // Full text input
  33. //
  34. $oPage->add("<div>\n");
  35. $oPage->add("Full text: ");
  36. $sFullText = "";
  37. foreach($oFilter->GetCriteria_FullText() as $sFullText)
  38. {
  39. // #@# Known limitation: do not consider other full text conditions...
  40. continue;
  41. }
  42. $oPage->add("<input type=\"text\" name=\"flt_fulltext\" value=\"$sFullText\">\n");
  43. $oPage->add("</div>\n");
  44. // Attribute-related criteria
  45. //
  46. foreach (MetaModel::GetClassFilterDefs($sClass) as $sFltCode => $oFltDef)
  47. {
  48. // Set its current values
  49. $sOpCode = "__none__";
  50. $sValue = "";
  51. foreach($oFilter->GetCriteria() as $aCritInfo)
  52. {
  53. if ($aCritInfo["filtercode"] == "pkey")
  54. {
  55. // ???
  56. }
  57. elseif ($aCritInfo["filtercode"] == $sFltCode)
  58. {
  59. $sOpCode = $aCritInfo["opcode"];
  60. $sValue = $aCritInfo["value"];
  61. break;
  62. }
  63. }
  64. $oPage->add("<div>\n");
  65. //$oPage->add($oFltDef->GetType()." (".$oFltDef->GetTypeDesc().")");
  66. $oPage->add(" ".$oFltDef->GetLabel()." ");
  67. $aOperators = array_merge(array("__none__" => ""), $oFltDef->GetOperators());
  68. $oPage->add_select($aOperators, "flt_ops[$sFltCode]", $sOpCode, 100);
  69. $oPage->add("\n");
  70. $oPage->add("<input type=\"text\" name=\"flt_values[$sFltCode]\" value=\"$sValue\">\n");
  71. $oPage->add("</div>\n");
  72. }
  73. // Ext key criteria
  74. //
  75. foreach (MetaModel::EnumReferencedClasses($sClass) as $sExtKeyAttCode => $sRemoteClass)
  76. {
  77. // Set its current values
  78. $oSubFilter = $oFilter->GetCriteria_PointingTo($sExtKeyAttCode);
  79. if (!$oSubFilter)
  80. {
  81. $oSubFilter = new CMDBSearchFilter($sRemoteClass);
  82. }
  83. $oPage->add("<div>\n");
  84. $oAtt = MetaModel::GetAttributeDef($oFilter->GetClass(), $sExtKeyAttCode);
  85. $oPage->add($oAtt->GetLabel()." having ({$oSubFilter->DescribeConditions()})");
  86. //$oPage->add("having $oFilter->DescribeConditionPointTo($sExtKeyAttCode));
  87. $oPage->add("\n");
  88. $oPage->add(dialogstack::RenderEditableField("Edit...", "flt_pointto[$sExtKeyAttCode]", $oSubFilter->serialize(), true));
  89. $oPage->add("</div>\n");
  90. }
  91. // Ext key criteria, the other way
  92. //
  93. foreach (MetaModel::EnumReferencingClasses($sClass, true) as $sRemoteClass => $aRemoteKeys)
  94. {
  95. foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
  96. {
  97. // Set its current values
  98. $oSubFilter = $oFilter->GetCriteria_ReferencedBy($sRemoteClass, $sExtKeyAttCode);
  99. if (!$oSubFilter)
  100. {
  101. $oSubFilter = new CMDBSearchFilter($sRemoteClass);
  102. }
  103. $oPage->add("<div>\n");
  104. //$oPage->add($oFilter->DescribeConditionRefBy($sRemoteClass, $sExtKeyAttCode));
  105. $oAtt = MetaModel::GetAttributeDef($sRemoteClass, $sExtKeyAttCode);
  106. $oPage->add("being ".$oAtt->GetLabel()." for ".$sRemoteClass."(e)s in ({$oSubFilter->DescribeConditions()})");
  107. $oPage->add("\n");
  108. $oPage->add(dialogstack::RenderEditableField("Edit...", "flt_refedby[$sRemoteClass][$sExtKeyAttCode]", $oSubFilter->serialize(), true));
  109. $oPage->add("</div>\n");
  110. }
  111. }
  112. // Ext key criteria -> link objects
  113. //
  114. foreach (MetaModel::EnumLinkingClasses($sClass) as $sLinkClass => $aRemoteClasses)
  115. {
  116. foreach($aRemoteClasses as $sExtKeyAttCode => $sRemoteClass)
  117. {
  118. // Set its current values
  119. //$oSubFilter = $oFilter->GetCriteria_PointingTo($sExtKeyAttCode);
  120. $oSubFilter = null;
  121. if (!$oSubFilter)
  122. {
  123. $oSubFilter = new CMDBSearchFilter($sRemoteClass);
  124. }
  125. $oPage->add("<div>\n");
  126. //$oPage->add(" ".MetaModel::GetName($sRemoteClass)." ");
  127. $oPage->add(" Linked to '".MetaModel::GetLinkLabel($sLinkClass, $sExtKeyAttCode)."' by ");
  128. $oSubFilter = new CMDBSearchFilter($sRemoteClass);
  129. $oPage->add($oSubFilter->__DescribeHTML());
  130. $oPage->add("\n");
  131. $oPage->add(dialogstack::RenderEditableField("Edit...", "flt_linkedwith[$sRemoteClass][$sExtKeyAttCode]", $oSubFilter->serialize(), true));
  132. $oPage->add("</div>\n");
  133. }
  134. }
  135. $oPage->add("<input type=\"submit\" name=\"makeit\" value=\"Search\">\n");
  136. $oPage->add("</form>\n");
  137. }
  138. function MakeFilterFromArgs()
  139. {
  140. $sClass = ReadParam("class");
  141. $sFilterFullText = ReadParam("flt_fulltext", "");
  142. $aFilterOps = ReadParam("flt_ops", array());
  143. $aFilterValues = ReadParam("flt_values", array());
  144. $aPointTo = ReadParam("flt_pointto", array());
  145. $aRefedBy = ReadParam("flt_refedby", array());
  146. $aLinkedWith = ReadParam("flt_linkedwith", array());
  147. $oFilter = new CMDBSearchFilter($sClass);
  148. if (!empty($sFilterFullText))
  149. {
  150. $oFilter->AddCondition_FullText($sFilterFullText);
  151. }
  152. foreach($aFilterOps as $sFltCode=>$sOpCode)
  153. {
  154. if ($sOpCode == "__none__") continue;
  155. $oFilter->AddCondition($sFltCode, $aFilterValues[$sFltCode], $sOpCode);
  156. }
  157. foreach($aPointTo as $sExtKeyAttCode=>$sFilterShortcut)
  158. {
  159. $oSubFilter = CMDBSearchFilter::unserialize($sFilterShortcut);
  160. $oFilter->AddCondition_PointingTo($oSubFilter, $sExtKeyAttCode);
  161. }
  162. foreach($aRefedBy as $sForeignClass=>$aExtKeys)
  163. {
  164. foreach($aExtKeys as $sForeignExtKey=>$sFilterShortcut)
  165. {
  166. //MyHelpers::var_dump_html("$sForeignClass / $sForeignExtKey / $sFilterShortcut");
  167. $oSubFilter = CMDBSearchFilter::unserialize($sFilterShortcut);
  168. //MyHelpers::var_dump_html($oSubFilter);
  169. $oFilter->AddCondition_ReferencedBy($oSubFilter, $sForeignExtKey);
  170. }
  171. }
  172. // $oFilter->AddCondition_LinkedTo(DBObjectSearch $oLinkFilter, $sExtKeyAttCodeToMe, $sExtKeyAttCodeTarget, DBObjectSearch $oFilterTarget);
  173. return $oFilter;
  174. }
  175. function Page3_ViewResults($oPage, $oFilter)
  176. {
  177. // Output results in various forms...
  178. //
  179. if ($oFilter->IsAny())
  180. {
  181. $oPage->p("You are considering the ENTIRE set of objects...");
  182. }
  183. else
  184. {
  185. $oPage->p($oFilter->__DescribeHTML());
  186. $oSet = new CMDBObjectSet($oFilter);
  187. $oPage->p("Found ".$oSet->Count()." items");
  188. $sFilterPhrase = $oFilter->serialize();
  189. $oPage->p("<a href=\"/pages/index.php?operation=direct&filter=$sFilterPhrase\">See detailed results</a>");
  190. }
  191. }
  192. ///////////////////////////////////////////////////////////////////////////////////////////////////
  193. //
  194. // M a i n P r o g r a m
  195. //
  196. ///////////////////////////////////////////////////////////////////////////////////////////////////
  197. $oPage->p("<h1>Advanced search</h1>");
  198. // Page 1 - Ask class
  199. //
  200. // Page 2 - Class is given, enum existing filters/possible links
  201. //
  202. // Page 3 - Interpret user choices, create a filter and render its string representation
  203. //
  204. //MyHelpers::arg_dump_html();
  205. //MyHelpers::var_dump_html($_SESSION);
  206. if (ReadParam('userconfig', false))
  207. {
  208. $sTodo = 'userconfig';
  209. }
  210. if (ReadParam('makeit', false))
  211. {
  212. $sTodo = 'makeit';
  213. }
  214. else
  215. {
  216. if (dialogstack::IsDialogStartup())
  217. {
  218. $sInit = dialogstack::StartDialog();
  219. $oFilter = CMDBSearchFilter::unserialize($sInit);
  220. $sTodo = 'userconfig';
  221. }
  222. else
  223. {
  224. $sClass = ReadParam('class', '');
  225. if (empty($sClass))
  226. {
  227. $sTodo = 'selectclass';
  228. }
  229. else
  230. {
  231. $oFilter = MakeFilterFromArgs();
  232. $sTodo = 'userconfig';
  233. }
  234. }
  235. }
  236. switch ($sTodo)
  237. {
  238. case "selectclass":
  239. Page1_AskClass($oPage);
  240. break;
  241. case "userconfig":
  242. dialogstack::DeclareCaller("Define filter for ".$oFilter->GetClass());
  243. $oPage->add(implode(" / ", dialogstack::GetCurrentStack()));
  244. Page2_ConfigFilters($oPage, $oFilter);
  245. break;
  246. case "makeit":
  247. $oFilter = MakeFilterFromArgs();
  248. Page3_ViewResults($oPage, $oFilter);
  249. $oPage->add(dialogstack::RenderEndDialogForm(DLGSTACK_OK, "Use filter", $oFilter->serialize()));
  250. $oPage->add(dialogstack::RenderEndDialogForm(DLGSTACK_CANCEL, "Annuler"));
  251. break;
  252. default:
  253. trigger_error("Wrong value for arg <em>todo</em> ($sTodo)", E_USER_ERROR);
  254. }
  255. $oPage->output();
  256. ?>