qbf.module 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. /**
  3. * Query By Form
  4. *
  5. * This module allows node modules to add a query by form tab for their node
  6. * types to the default search form
  7. *
  8. * @copyright 2008 Ouest Systemes Informatiques (OSInet)
  9. * @author Frederic G. MARAND
  10. * @version $Id: qbf.module,v 1.4 2008-08-26 16:24:07 marand Exp $
  11. * @license CeCILL 2.0
  12. * @package QBF
  13. */
  14. define('QBF_LEVEL_REMOVE', 0);
  15. define('QBF_LEVEL_DISPLAY', 1); // Display only, don't use
  16. define('QBF_LEVEL_OPTIONAL', 2);
  17. define('QBF_LEVEL_REQUIRED', 3);
  18. define('QBF_PATH_QUERY', 'qbf/query');
  19. function _qbf_view($usNodeType = NULL)
  20. {
  21. $nodeType = filter_xss($usNodeType, array());
  22. $arNodeTypes = node_get_types();
  23. //dsm($arNodeTypes);
  24. $arFuncs1 = get_defined_functions();
  25. $arFuncs1 = $arFuncs1['user'];
  26. $node = new stdClass();
  27. $node->type = 'poll';
  28. $arFuncs1 = node_forms();
  29. //dsm($arFuncs1);
  30. $form = node_form($node, array('qbe-key' => 'qbe-value'));
  31. //dsm($form);
  32. return 'foo';
  33. }
  34. function qbf_rewrite_form($form)
  35. {
  36. $hookName = 'qbf_rewrite_form';
  37. foreach (module_implements($hookName) as $module)
  38. {
  39. $function = "${module}_$hookName";
  40. $form = $function($form);
  41. }
  42. return drupal_get_form($form);
  43. }
  44. /**
  45. * Transform a form array for QBF
  46. *
  47. * This function obtains the form array using Forms API, and transforms it by
  48. * modifying widgets to other types where needed.
  49. *
  50. * Any additional parameter passed to the function is transmitted to the form
  51. * generating function.
  52. *
  53. * @param string $form_id
  54. * @return array
  55. */
  56. function qbf_transform_form($form_id)
  57. {
  58. $arArgs = func_get_args();
  59. //dsm(array('qtf' => $arArgs));
  60. // Fetch the basic form and rename it, passing it the caller's arguments
  61. $form = call_user_func_array('drupal_retrieve_form', $arArgs);
  62. $newFormId = "qbf_$form_id";
  63. // Only keep the children of the form and QBF properties on the form itself
  64. $elements = array();
  65. $newForm = array();
  66. $newForm['#qbf_source_form_id'] = $form_id;
  67. if (in_array('#qbf', element_properties($form)))
  68. {
  69. $newForm += $form['#qbf'];
  70. }
  71. foreach (element_children($form) as $key)
  72. {
  73. // dsm("Transforming $key, type " . $form[$key]['#type']);
  74. $newElement = _qbf_transform_element($key, $form[$key]);
  75. if (!is_null($newElement))
  76. {
  77. $newForm[$key] = $newElement;
  78. }
  79. }
  80. $newForm['#id'] = $newFormId;
  81. $newForm['#multistep'] = TRUE;
  82. $newForm['#redirect'] = FALSE;
  83. $newForm['#after_build'][] = 'qbf_after_build';
  84. // dsm($newForm);
  85. return $newForm;
  86. }
  87. /**
  88. * Transform a form element for QBF
  89. *
  90. * QBF-specific properties are:
  91. * - #qbf : array of properties
  92. * - #level: only within #qbf @see QBF_* constants
  93. *
  94. * @param array &$element
  95. * @return void
  96. */
  97. function _qbf_transform_element($key, array $element)
  98. {
  99. // dsm(array('key' => $key, 'element' => $element));
  100. // Types without a default transformation are not transformed
  101. static $arDefaultTypeTransformations = array
  102. (
  103. 'button' => NULL,
  104. 'file' => NULL,
  105. // 'hidden' => NULL,
  106. 'markup' => NULL,
  107. 'password' => NULL,
  108. 'radio' => NULL,
  109. 'submit' => NULL,
  110. 'textarea' => 'textfield',
  111. // 'value' => 'value',
  112. );
  113. // Properties without a default transformation are not transformed
  114. static $arDefaultPropertyTransformations = array
  115. (
  116. // Standard properties
  117. '#action' => NULL,
  118. '#after_build' => NULL,
  119. '#base' => NULL,
  120. '#button_type' => NULL,
  121. '#built' => NULL,
  122. '#description' => NULL,
  123. '#method' => NULL,
  124. '#parents' => NULL,
  125. '#redirect' => NULL,
  126. '#ref' => NULL,
  127. '#required' => NULL,
  128. '#rows' => NULL,
  129. '#submit' => NULL,
  130. '#tree' => NULL,
  131. '#validate' => NULL,
  132. );
  133. // Property values causing element removal
  134. static $arKillerProperties = array
  135. (
  136. '#disabled' => TRUE,
  137. );
  138. // Transform type
  139. $sourceType = $element['#type'];
  140. // .. Default transformation
  141. $destType = array_key_exists($sourceType, $arDefaultTypeTransformations)
  142. ? $arDefaultTypeTransformations[$sourceType]
  143. : $sourceType;
  144. // .. Apply type override
  145. if (isset($element['#qbf']['#type']))
  146. {
  147. $destType = $element['#qbf']['#type'];
  148. }
  149. if (is_null($destType))
  150. {
  151. $ret = NULL;
  152. }
  153. else
  154. {
  155. $ret = $element;
  156. $ret['#type'] = $destType;
  157. if (!array_key_exists('#qbf', $element) || $element['#qbf']['#level'] == QBF_LEVEL_REMOVE)
  158. {
  159. $ret = NULL;
  160. }
  161. else
  162. {
  163. foreach (element_properties($element) as $propertyName)
  164. {
  165. // Apply killer properties first to avoid useless work
  166. if (array_key_exists($propertyName, $arKillerProperties) && ($element[$propertyName] = $arKillerProperties[$propertyName]))
  167. {
  168. $ret = NULL;
  169. break;
  170. }
  171. // Now transform or copy remaining properties
  172. if (array_key_exists($propertyName, $arDefaultPropertyTransformations))
  173. {
  174. $ret[$propertyName] = $arDefaultPropertyTransformations[$propertyName];
  175. }
  176. else
  177. {
  178. $ret[$propertyName] = $element[$propertyName];
  179. }
  180. // And apply form-defined overrides
  181. if ($propertyName == '#qbf')
  182. {
  183. foreach ($element[$propertyName] as $overrideName => $overrideValue)
  184. {
  185. $ret[$overrideName] = $overrideValue;
  186. }
  187. }
  188. }
  189. foreach (element_children($element) as $childName)
  190. {
  191. $child = _qbf_transform_element($childName, $element[$childName]);
  192. if (is_null($child))
  193. {
  194. unset($ret[$childName]);
  195. }
  196. else
  197. {
  198. $ret[$childName] = $child;
  199. }
  200. }
  201. }
  202. }
  203. //dsm(array('key' => $key, 'transformed element' => $ret));
  204. return $ret;
  205. }
  206. function qbf_perm()
  207. {
  208. $ret = array('use qbf search functions');
  209. return $ret;
  210. }
  211. /**
  212. * Implement hook_forms
  213. *
  214. * @todo dynamically build the list of forms
  215. *
  216. * @return array
  217. */
  218. function qbf_forms()
  219. {
  220. $forms['qbf_job_form'] = array
  221. (
  222. 'callback' => 'qbf_transform_form',
  223. 'callback arguments' => array('job_form'),
  224. );
  225. return $forms;
  226. }
  227. function qbf_after_build($form, $form_values)
  228. {
  229. $arQuery = array();
  230. dsm($form_values);
  231. foreach (element_children($form) as $childName)
  232. {
  233. if ($form[$childName]['#qbf']['#level'] > QBF_LEVEL_REMOVE)
  234. {
  235. $arQuery[] = $childName . '=' . $form[$childName]['#value'];
  236. }
  237. }
  238. $query = implode(', ', $arQuery);
  239. $form['food'] = array
  240. (
  241. '#type' => 'markup',
  242. '#value' => "<p>Requête sur $query</p>",
  243. );
  244. return $form;
  245. }