|
@@ -0,0 +1,221 @@
|
|
|
|
+<?php
|
|
|
|
+/**
|
|
|
|
+ * Query By Form
|
|
|
|
+ *
|
|
|
|
+ * This module allows node modules to add a query by form tab for their node
|
|
|
|
+ * types to the default search form
|
|
|
|
+ *
|
|
|
|
+ * @copyright 2008 Ouest Systemes Informatiques (OSInet)
|
|
|
|
+ * @author Frederic G. MARAND
|
|
|
|
+ * @version $Id: qbf.module,v 1.1 2008-08-22 16:58:01 marand Exp $
|
|
|
|
+ * @license CeCILL 2.0
|
|
|
|
+ * @package QBF
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+define('QBF_LEVEL_REMOVE', 0);
|
|
|
|
+define('QBF_LEVEL_OPTIONAL', 1);
|
|
|
|
+define('QBF_LEVEL_REQUIRED', 2);
|
|
|
|
+
|
|
|
|
+function _qbf_view($usNodeType = NULL)
|
|
|
|
+ {
|
|
|
|
+ $nodeType = filter_xss($usNodeType, array());
|
|
|
|
+
|
|
|
|
+ $arNodeTypes = node_get_types();
|
|
|
|
+ //dsm($arNodeTypes);
|
|
|
|
+ $arFuncs1 = get_defined_functions();
|
|
|
|
+ $arFuncs1 = $arFuncs1['user'];
|
|
|
|
+ $node = new stdClass();
|
|
|
|
+ $node->type = 'poll';
|
|
|
|
+ $arFuncs1 = node_forms();
|
|
|
|
+ //dsm($arFuncs1);
|
|
|
|
+ $form = node_form($node, array('qbe-key' => 'qbe-value'));
|
|
|
|
+ //dsm($form);
|
|
|
|
+ return 'foo';
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+function qbf_rewrite_form($form)
|
|
|
|
+ {
|
|
|
|
+ $hookName = 'qbf_rewrite_form';
|
|
|
|
+
|
|
|
|
+ foreach (module_implements($hookName) as $module)
|
|
|
|
+ {
|
|
|
|
+ $function = "${module}_$hookName";
|
|
|
|
+ $form = $function($form);
|
|
|
|
+ }
|
|
|
|
+ return drupal_get_form($form);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Transform a form array for QBF
|
|
|
|
+ *
|
|
|
|
+ * This function obtains the form array using Forms API, and transforms it by
|
|
|
|
+ * modifying widgets to other types where needed.
|
|
|
|
+ *
|
|
|
|
+ * The $arHooks array contains hooks to be invoked, indexed by hook name, with
|
|
|
|
+ * their arguments
|
|
|
|
+ *
|
|
|
|
+ * @param string $form_id
|
|
|
|
+ * @param array $arHooks
|
|
|
|
+ * @return array
|
|
|
|
+ */
|
|
|
|
+function _qbf_transform_form($form_id, $arHooks = array())
|
|
|
|
+ {
|
|
|
|
+ // Fetch the basic form and rename it
|
|
|
|
+ $form = drupal_retrieve_form($form_id, NULL);
|
|
|
|
+ $newFormId = "qbf_$form_id";
|
|
|
|
+
|
|
|
|
+ // Invoke the optional hooks extending it
|
|
|
|
+ foreach ($arHooks as $hookName => $arHookArguments)
|
|
|
|
+ {
|
|
|
|
+ dsm("Firing $hookName");
|
|
|
|
+
|
|
|
|
+ foreach (module_implements($hookName) as $module)
|
|
|
|
+ {
|
|
|
|
+ $function = $module .'_'. $hookName;
|
|
|
|
+ switch ($hookName)
|
|
|
|
+ {
|
|
|
|
+ case 'form':
|
|
|
|
+ // @todo FIXME needs node with type property set
|
|
|
|
+ // $formAdditions = node_invoke(new stdClass(), $hookName, $arHookArguments);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ $formAdditions = module_invoke_all($hookName, $arHookArguments);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ // dsm(array($function => $formAdditions));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (is_array($formAdditions))
|
|
|
|
+ {
|
|
|
|
+ $form = array_merge_recursive($form, $formAdditions);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Only keep the children of the form
|
|
|
|
+ $elements = array();
|
|
|
|
+ $newForm = array();
|
|
|
|
+ $form['mark'] = array('#type' => 'textarea', '#value' => 'goo');
|
|
|
|
+ foreach (element_children($form) as $key)
|
|
|
|
+ {
|
|
|
|
+ //dsm("Transforming $key, type " . $form[$key]['#type']);
|
|
|
|
+ $newElement = _qbf_transform_element($key, $form[$key]);
|
|
|
|
+ if (!is_null($newElement))
|
|
|
|
+ {
|
|
|
|
+ $newForm[$key] = $newElement;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $newForm['#id'] = $newFormId;
|
|
|
|
+//dsm($newForm);
|
|
|
|
+ return $newForm;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Transform a form element for QBF
|
|
|
|
+ *
|
|
|
|
+ * QBF-specific properties are:
|
|
|
|
+ * - #qbf_level : @see QBF_* constants
|
|
|
|
+ *
|
|
|
|
+ * @param array &$element
|
|
|
|
+ * @return void
|
|
|
|
+ */
|
|
|
|
+function _qbf_transform_element($key, array $element)
|
|
|
|
+ {
|
|
|
|
+ //dsm(array('key' => $key, 'element' => $element));
|
|
|
|
+ // Types without a default transformation are not transformed
|
|
|
|
+ static $arDefaultTypeTransformations = array
|
|
|
|
+ (
|
|
|
|
+ 'button' => NULL,
|
|
|
|
+ 'file' => NULL,
|
|
|
|
+ 'hidden' => NULL,
|
|
|
|
+ 'markup' => NULL,
|
|
|
|
+ 'password' => NULL,
|
|
|
|
+ 'radio' => NULL,
|
|
|
|
+ 'submit' => NULL,
|
|
|
|
+ 'textarea' => 'textfield',
|
|
|
|
+ 'value' => NULL,
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // Properties without a default transformation are not transformed
|
|
|
|
+ static $arDefaultPropertyTransformations = array
|
|
|
|
+ (
|
|
|
|
+ // Standard properties
|
|
|
|
+ '#action' => NULL,
|
|
|
|
+ '#after_build' => NULL,
|
|
|
|
+ '#base' => NULL,
|
|
|
|
+ '#button_type' => NULL,
|
|
|
|
+ '#built' => NULL,
|
|
|
|
+ '#description' => NULL,
|
|
|
|
+ '#method' => NULL,
|
|
|
|
+ '#parents' => NULL,
|
|
|
|
+ '#redirect' => NULL,
|
|
|
|
+ '#ref' => NULL,
|
|
|
|
+ '#required' => NULL,
|
|
|
|
+ '#rows' => NULL,
|
|
|
|
+ '#submit' => NULL,
|
|
|
|
+ '#tree' => NULL,
|
|
|
|
+ '#validate' => NULL,
|
|
|
|
+ '#value' => NULL,
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // Property values causing element removal
|
|
|
|
+ static $arKillerProperties = array
|
|
|
|
+ (
|
|
|
|
+ '#disabled' => TRUE,
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // Transform type
|
|
|
|
+ $sourceType = $element['#type'];
|
|
|
|
+ $destType = array_key_exists($sourceType, $arDefaultTypeTransformations)
|
|
|
|
+ ? $arDefaultTypeTransformations[$sourceType]
|
|
|
|
+ : $sourceType;
|
|
|
|
+
|
|
|
|
+ if (is_null($destType))
|
|
|
|
+ {
|
|
|
|
+ $ret = NULL;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ $ret = $element;
|
|
|
|
+ $ret['#type'] = $destType;
|
|
|
|
+
|
|
|
|
+ if (!array_key_exists('#qbf_level', $element) || $element['#qbf_level'] == QBF_LEVEL_REMOVE)
|
|
|
|
+ {
|
|
|
|
+ $ret = NULL;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ foreach (element_properties($element) as $propertyName)
|
|
|
|
+ {
|
|
|
|
+ // Apply killer properties first to avoid useless work
|
|
|
|
+ if (array_key_exists($propertyName, $arKillerProperties) && ($element[$propertyName] = $arKillerProperties[$propertyName]))
|
|
|
|
+ {
|
|
|
|
+ $ret = NULL;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Now transform or copy remaining properties
|
|
|
|
+ if (array_key_exists($propertyName, $arDefaultPropertyTransformations))
|
|
|
|
+ {
|
|
|
|
+ $ret[$propertyName] = $arDefaultPropertyTransformations[$propertyName];
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ $ret[$propertyName] = $element[$propertyName];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ foreach (element_children($element) as $childName)
|
|
|
|
+ {
|
|
|
|
+ $child = _qbf_transform_element($childName, $element[$childName]);
|
|
|
|
+ if (!is_null($child))
|
|
|
|
+ {
|
|
|
|
+ $ret[$childName] = $child;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //dsm(array('key' => $key, 'transformed element' => $ret));
|
|
|
|
+ return $ret;
|
|
|
|
+ }
|