TripalField.inc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. <?php
  2. class TripalField {
  3. // --------------------------------------------------------------------------
  4. // EDITABLE STATIC CONSTANTS
  5. //
  6. // The following constants SHOULD be set for each descendent class. They are
  7. // used by the static functions to provide information to Drupal about
  8. // the field and it's default widget and formatter.
  9. // --------------------------------------------------------------------------
  10. // The default lable for this field.
  11. public static $default_label = 'Tripal Field';
  12. // The default description for this field.
  13. public static $default_description = 'The generic base class for all Tripal fields. Replace this text as appropriate for the child implementation.';
  14. // Provide a list of global settings. These can be accessed witihn the
  15. // globalSettingsForm. When the globalSettingsForm is submitted then
  16. // Drupal will automatically change these settings for all fields.
  17. // Once instances exist for a field type then these settings cannot be
  18. // changed.
  19. public static $default_settings = array(
  20. 'storage' => 'tripal_no_storage',
  21. // It is expected that all fields set a 'value' in the load() function.
  22. // In many cases, the value may be an associative array of key/value pairs.
  23. // In order for Tripal to provide context for all data, the keys should
  24. // be a controlled vocabulary term (e.g. rdfs:type). Keys in the load()
  25. // function that are supported by the query() function should be
  26. // listed here.
  27. 'searchable_keys' => array(),
  28. );
  29. // Provide a list of instance specific settings. These can be access within
  30. // the instanceSettingsForm. When the instanceSettingsForm is submitted
  31. // then Drupal with automatically change these settings for the instnace.
  32. // It is recommended to put settings at the instance level whenever possible.
  33. // If you override this variable in a child class be sure to replicate the
  34. // term_name, term_vocab, term_accession and term_fixed keys as these are
  35. // required for all TripalFields.
  36. public static $default_instance_settings = array(
  37. // The short name for the vocabulary (e.g. shcema, SO, GO, PATO, etc.).
  38. 'term_vocabulary' => 'schema',
  39. // The name of the term.
  40. 'term_name' => 'Thing',
  41. // The unique ID (i.e. accession) of the term.
  42. 'term_accession' => 'Thing',
  43. // Set to TRUE if the site admin is not allowed to change the term
  44. // type, otherwise the admin can change the term mapped to a field.
  45. 'term_fixed' => FALSE,
  46. // Inidates if this field should be automatically attached to display
  47. // or web services or if this field should be loaded separately. This
  48. // is convenient for speed. Fields that are slow should for loading
  49. // should ahve auto_attach set to FALSE so tha their values can be
  50. // attached asyncronously.
  51. );
  52. // The default widget for this field.
  53. public static $default_widget = '';
  54. // The default formatter for this field.
  55. public static $default_formatter = '';
  56. // The module that manages this field.
  57. public static $module = 'tripal';
  58. // A boolean specifying that users should not be allowed to create
  59. // fields and instances of this field type through the UI. Such
  60. // fields can only be created programmatically with field_create_field()
  61. // and field_create_instance().
  62. public static $no_ui = TRUE;
  63. // A boolean specifying that the field will not contain any data. This
  64. // should exclude the field from web serivces or downloads. An example
  65. // could be a quick search field that appears on the page that redirects
  66. // the user but otherwise provides no data.
  67. public static $no_data = FALSE;
  68. // --------------------------------------------------------------------------
  69. // PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
  70. // --------------------------------------------------------------------------
  71. // An array containing details about the field. The format of this array
  72. // is the same as that returned by field_info_fields()
  73. protected $field;
  74. // An array containing details about an instance of the field. A field does
  75. // not have to have an instance. But if dealing with an instance (such as
  76. // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
  77. protected $instance;
  78. // The term array that provides all the details about the controlled
  79. // vocabulary term that this field maps to.
  80. protected $term;
  81. // --------------------------------------------------------------------------
  82. // CONSTRUCTOR
  83. // --------------------------------------------------------------------------
  84. /**
  85. * Instantiates a new TripalField object.
  86. *
  87. * @param $field
  88. * An array containing the field data as returned by field_info_field().
  89. * @param $instance
  90. * An array containing the instance data as returned by field_instance_info().
  91. */
  92. public function __construct($field, $instance) {
  93. $vocabulary = $term = NULL;
  94. $this->field = $field;
  95. $this->instance = $instance;
  96. $class = get_called_class();
  97. // Use the term info defined in the class by default (assuming it's not schema:Thing ;-).
  98. if ($class::$default_instance_settings['term_name'] != 'Thing') {
  99. $vocabulary = $class::$default_instance_settings['term_vocabulary'];
  100. $accession = $class::$default_instance_settings['term_accession'];
  101. }
  102. // Allow the constructor to override the term info.
  103. $vocabulary = isset($this->instance['settings']['term_vocabulary']) ? $this->instance['settings']['term_vocabulary'] : $vocabulary;
  104. $accession = isset($this->instance['settings']['term_accession']) ? $this->instance['settings']['term_accession'] : $accession;
  105. // Assuming we have term info, load the term.
  106. if (!empty($vocabulary) AND !empty($accession)) {
  107. $this->term = tripal_get_term_details($vocabulary, $accession);
  108. }
  109. else {
  110. tripal_report_error('tripal_field', TRIPAL_ERROR, 'Unable to instantiate Field :name due to missing vocabulary and/or accession.',
  111. array(':name' => $class::$default_label));
  112. }
  113. if (!$instance) {
  114. tripal_set_message(t('Missing instance of field "%field"', array('%field' => $field['field_name'])), TRIPAL_ERROR);
  115. }
  116. }
  117. // --------------------------------------------------------------------------
  118. // STATIC INFO FUNCTIONS -- DO NOT OVERRIDE
  119. // --------------------------------------------------------------------------
  120. /**
  121. * Provides default information about this field type
  122. *
  123. * This function corresponds to the hook_field_info() function of
  124. * the Drupal Field API.
  125. *
  126. * @return
  127. * An array whose keys are field type names and whose values are arrays
  128. * describing the field type. The keys are the same as for the
  129. * hook_field_info() function.
  130. */
  131. public static function info() {
  132. $class = get_called_class();
  133. $info = array(
  134. 'label' => $class::$default_label,
  135. 'description' => $class::$default_description,
  136. 'settings' => $class::$default_settings,
  137. 'instance_settings' => $class::$default_instance_settings,
  138. 'default_widget' => $class::$default_widget,
  139. 'default_formatter' => $class::$default_formatter,
  140. 'no_ui' => $class::$no_ui,
  141. );
  142. return $info;
  143. }
  144. // --------------------------------------------------------------------------
  145. // DO NOT OVERRIDE THESE FUNCTIONS
  146. // --------------------------------------------------------------------------
  147. /**
  148. * Retrives the name of this field.
  149. *
  150. * @return
  151. * This field's name.
  152. */
  153. public function getFieldName() {
  154. return $this->field['field_name'];
  155. }
  156. public function getField() {
  157. return $this->field;
  158. }
  159. public function getInstance() {
  160. return $this->instance;
  161. }
  162. /**
  163. * When constructing a pager for use by a field, all pagers must have
  164. * a unique ID
  165. */
  166. protected function getPagerElementID() {
  167. return $this->field['id'];
  168. }
  169. public function getFieldTerm(){
  170. return $this->term;
  171. }
  172. public function getFieldTermID() {
  173. $class = get_called_class();
  174. return $this->instance['settings']['term_vocabulary'] . ':' . $this->instance['settings']['term_accession'];
  175. }
  176. /**
  177. * Describes this field to Tripal web services.
  178. *
  179. * The child class need not implement this function. It has all of the details
  180. * provided for elements by the elementInfo() function are used to generate
  181. * the details needed for Views.
  182. *
  183. * @return
  184. * An associative array with the keys available for searching. The value
  185. * is the term array for the element.
  186. */
  187. public function webServicesData() {
  188. $elements = $this->elementInfo();
  189. $field_term = $this->getFieldTermID();
  190. $field_term_name = strtolower(preg_replace('/[^\w]/', '_', $this->term['name']));
  191. $field_details = $elements[$field_term];
  192. $searchable_keys = array();
  193. if (array_key_exists('searchable', $field_details) and $field_details['searchable']) {
  194. $searchable_keys[$field_term_name] = $field_term;
  195. }
  196. // Now add any entries for child elements.
  197. if (array_key_exists('elements', $field_details)) {
  198. $elements = $field_details['elements'];
  199. foreach ($elements as $element_name => $element_details) {
  200. $this->_addWebServiceElement($searchable_keys, $field_term_name, $field_term, $element_name, $element_details);
  201. }
  202. }
  203. return $searchable_keys;
  204. }
  205. /**
  206. *
  207. * @param $searchabe_keys
  208. * @param $field_name
  209. * @param $element_name
  210. * @param $element_details
  211. */
  212. protected function _addWebServiceElement(&$searchable_keys, $parent_term_name, $parent_term, $element_name, $element_details) {
  213. // Skip the 'entity' element, as we'll never make this searchable or
  214. // viewable. It's meant for linking.
  215. if ($element_name == 'entity') {
  216. return;
  217. }
  218. list($vocabulary, $accession) = explode(':', $element_name);
  219. $term = tripal_get_term_details($vocabulary, $accession);
  220. $field_term = $parent_term . ',' . $term['vocabulary']['short_name'] . ':' . $term['accession'];
  221. $field_term_name = $parent_term_name . '.' . strtolower(preg_replace('/[^\w]/', '_', $term['name']));
  222. // Is the field searchable?
  223. if (array_key_exists('searchable', $element_details) and $element_details['searchable']) {
  224. $searchable_keys[$field_term_name] = $field_term;
  225. }
  226. // Now add any entries for child elements.
  227. if (array_key_exists('elements', $element_details)) {
  228. $elements = $element_details['elements'];
  229. foreach ($elements as $element_name => $element_details) {
  230. $this->_addWebServiceElement($searchable_keys, $field_term_name, $field_term, $element_name, $element_details);
  231. }
  232. }
  233. }
  234. /**
  235. * Describes this field to Views.
  236. *
  237. * The child class need not implement this function has all of the details
  238. * provided for elements by the elementInfo() function are used to generate
  239. * the details needed for Views.
  240. *
  241. * @param $view_base_id
  242. * Views was originally designed to integrate with SQL tables. And
  243. * each field is associated with a table. Because these are TripalFields
  244. * and views is not directly querying the tables it doesn't make sense to
  245. * associate fields with a table, but we must associate the fields with
  246. * the bundle. Each bundle is uniquely identified with the $view_base_id
  247. * that is passed here.
  248. *
  249. * @return
  250. * An associative array describing the data structure. Primary key is the
  251. * name used internally by Views for the bundle that is provided by
  252. * the $view_base_id. The returned array should be compatible with the
  253. * instructions provided by the hook_views_data() function.
  254. */
  255. public function viewsData($view_base_id) {
  256. $data = array();
  257. $field_name = $this->field['field_name'];
  258. $field_term = $this->getFieldTermID();
  259. $elements = $this->elementInfo();
  260. $field_details = $elements[$field_term];
  261. // Get any titles or help text that is overriden.
  262. $title = ucfirst($this->instance['label']);
  263. if (array_key_exists('label', $field_details)) {
  264. $title = $field_details['label'];
  265. }
  266. $help = $this->instance['description'];
  267. if (array_key_exists('help', $field_details)) {
  268. $help = $field_details['help'];
  269. }
  270. // Build the entry for the field.
  271. $data[$view_base_id][$field_name] = array(
  272. 'title' => $title,
  273. 'help' => $help,
  274. 'field' => array(
  275. 'handler' => 'tripal_views_handler_field',
  276. 'click sortable' => TRUE,
  277. ),
  278. );
  279. // Is the field sortable?
  280. if (array_key_exists('sortable', $field_details) and $field_details['sortable']) {
  281. $data[$view_base_id][$field_name]['sort']['handler'] = 'tripal_views_handler_sort';
  282. }
  283. // Is the field searchable?
  284. if (array_key_exists('searchable', $field_details) and $field_details['searchable']) {
  285. $filter_handler = 'tripal_views_handler_filter_string';
  286. if (array_key_exists('type', $field_details) and $field_details['type'] == 'numeric') {
  287. $filter_handler = 'tripal_views_handler_filter';
  288. }
  289. $data[$view_base_id][$field_name]['filter'] = array(
  290. 'handler' => $filter_handler,
  291. );
  292. }
  293. // Now add any entries for child elements.
  294. if (array_key_exists('elements', $field_details)) {
  295. $elements = $field_details['elements'];
  296. foreach ($elements as $element_name => $element_details) {
  297. $this->_addViewsDataElement($data, $view_base_id, $field_name, $element_name, $element_details);
  298. }
  299. }
  300. return $data;
  301. }
  302. /**
  303. *
  304. * @param unknown $data
  305. * @param unknown $view_base_id
  306. * @param unknown $parent
  307. * @param unknown $element_name
  308. * @param unknown $element_details
  309. */
  310. protected function _addViewsDataElement(&$data, $view_base_id, $parent, $element_name, $element_details) {
  311. // Skip the 'entity' element, as we'll never make this searchable or
  312. // viewable. It's meant for linking.
  313. if ($element_name == 'entity') {
  314. return;
  315. }
  316. $field_name = $parent . '.' . $element_name;
  317. list($vocabulary, $accession) = explode(':', $element_name);
  318. $term = tripal_get_term_details($vocabulary, $accession);
  319. // Get any titles or help text that is overriden.
  320. $title = ucfirst($term['name']);
  321. if (array_key_exists('label', $element_details)) {
  322. $title = $element_details['label'];
  323. }
  324. $help = $term['definition'];
  325. if (array_key_exists('help', $element_details)) {
  326. $help = $element_details['help'];
  327. }
  328. // Build the entry for the field.
  329. $data[$view_base_id][$field_name] = array(
  330. 'title' => $title,
  331. 'help' => $help,
  332. 'field' => array(
  333. 'handler' => 'tripal_views_handler_field_element',
  334. ),
  335. );
  336. // Is the field sortable?
  337. if (array_key_exists('sortable', $element_details) and $element_details['sortable']) {
  338. $data[$view_base_id][$field_name]['sort']['handler'] = 'tripal_views_handler_sort';
  339. $data[$view_base_id][$field_name]['field']['click sortable'] = TRUE;
  340. }
  341. // Is the field searchable?
  342. if (array_key_exists('searchable', $element_details) and $element_details['searchable']) {
  343. $filter_handler = 'tripal_views_handler_filter_element_string';
  344. if (array_key_exists('type', $element_details) and $element_details['type'] == 'numeric') {
  345. $filter_handler = 'tripal_views_handler_filter';
  346. }
  347. $data[$view_base_id][$field_name]['filter'] = array(
  348. 'handler' => $filter_handler,
  349. );
  350. }
  351. // Recusrively add any entries for child elements.
  352. if (array_key_exists('elements', $element_details)) {
  353. $elements = $element_details['elements'];
  354. foreach ($elements as $element_name => $element_details) {
  355. $this->_addViewsDataElement($data, $view_base_id, $field_name, $element_name, $element_details);
  356. }
  357. }
  358. }
  359. // --------------------------------------------------------------------------
  360. // OVERRIDEABLE FUNCTIONS
  361. // --------------------------------------------------------------------------
  362. /**
  363. * Perform validation of the field regardless how it is updated.
  364. *
  365. * Any errors encountered should be indicated by adding a value to the
  366. * $errors array according to the instructions below.
  367. *
  368. * @param $entity_type
  369. * The type of $entity.
  370. * @param $entity
  371. * The entity for the operation.
  372. * @param $langcode
  373. * The language associated with $items.
  374. * @param $items
  375. * $entity->{$field['field_name']}[$langcode], or an empty array if unset.
  376. * @param $errors
  377. * The array of errors (keyed by field name, language code, and delta) that
  378. * have already been reported for the entity. The function should add its
  379. * errors to this array. Each error is an associative array with the
  380. * following keys and values:
  381. * - error: An error code (should be a string prefixed with the
  382. * module name).
  383. * - message: The human readable message to be displayed.
  384. *
  385. */
  386. public function validate($entity_type, $entity, $langcode, $items, &$errors) {
  387. }
  388. /**
  389. * Loads the field values from the underlying data store.
  390. *
  391. * @param $entity
  392. *
  393. * @return
  394. * An array of the following format:
  395. * $entity->{$field_name}['und'][0]['value'] = $value;
  396. * where:
  397. * - $entity is the enity object to which this field is attached.
  398. * - $field_name is the name of this field
  399. * - 'und' is the language code (in this case 'und' == undefined)
  400. * - 0 is the cardinality. Increment by 1 when more than one item is
  401. * available.
  402. * - 'value' is the key indicating the value of this field. It should
  403. * always be set. The value of the 'value' key will be the contents
  404. * used for web services and for downloadable content. The value
  405. * should be of the follow format types: 1) A single value (text,
  406. * numeric, etc.) 2) An array of key value pair. 3) If multiple entries
  407. * then cardinality should incremented and format types 1 and 2 should
  408. * be used for each item.
  409. * The array may contain as many other keys at the same level as 'value'
  410. * but those keys are for internal field use and are not considered the
  411. * value of the field.
  412. *
  413. *
  414. */
  415. public function load($entity) {
  416. }
  417. /**
  418. * Provides the list of elements returned by the 'value' of the field. \
  419. *
  420. * The elements provided by this function are used to integrate with
  421. * Drupal Views and Web services. The return value is an associative array
  422. * that contains all of the elements that will be returned by the
  423. * 'value' of this field. If the value field returns an element which
  424. * is not defined here a warning will be generated.
  425. *
  426. * The array structure should contain at the top-level a key of the form
  427. * {db}:{accession}. This represents the term that this field belongs to.
  428. * The value of this top-level key is an array with the following keys:
  429. * -name: this key is not actually used but is availble to improve
  430. * readability of the array. Because the key is a vocabulary term
  431. * conaining only the accession it's not always clear what it means.
  432. * Providing a 'name' key helps other's know what the term is.
  433. * -searchable: TRUE if the element can be used for filtering the content
  434. * type to which tis field is attached. FALSE if not.
  435. * -operations: an array of filtering operations that can be used for this
  436. * field. These include: 'eq', 'ne', 'contains', 'starts', 'gt', 'lt',
  437. * 'gte', 'lte'. These opertaions are applicable to strings: 'eq', 'ne',
  438. * 'contains', and 'starts'. These operations are applicable for numeric
  439. * values: 'gt', 'lt', 'gte', 'lte'.
  440. * -label: The label (if applicable) to appear for the elmeent. The default
  441. * is to use the term's name.
  442. * -help: Help text (if applicable) to appear for the element. The default
  443. * is to use the term's definition.
  444. * -type: The data type: e.g. 'string' or 'numeric'. Default is 'string'.
  445. * -sortable: TRUE if the element can be sorted. FALSE if not.
  446. * -elements: If this field value is a simple scalar (i.e. string or
  447. * number) then this key is not needed. But, if the 'value' of the
  448. * field is an array with sub keys then those subkeys must be defined
  449. * using this key. The members of the element array follows the same
  450. * format as the top-level key and the above subkeys can be used as well.
  451. *
  452. * The following code provides an example for describing the value elements
  453. * of this field. The Tripal Chado module provides an obi__organism field
  454. * that attaches organism details to content types such as genes, mRNA,
  455. * stocks, etc. It provides a label containing the full scientific name of
  456. * the organism as well as the genus, species, infraspecific name,
  457. * and infraspecific type. If the organism to which the field belong is
  458. * published then an entity ID is provided. The following array describes
  459. * all of these.
  460. * @code
  461. $field_term = $this->getFieldTermID();
  462. return array(
  463. $field_term => array(
  464. 'operations' => array('eq', 'contains', 'starts'),
  465. 'sortable' => TRUE,
  466. 'searchable' => TRUE,
  467. 'elements' => array(
  468. 'rdfs:label' => array(
  469. 'searchable' => TRUE,
  470. 'name' => 'scientfic_name',
  471. 'operations' => array('eq', 'ne', 'contains', 'starts'),
  472. 'sortable' => TRUE,
  473. ),
  474. 'TAXRANK:0000005' => array(
  475. 'searchable' => TRUE,
  476. 'name' => 'genus',
  477. 'operations' => array('eq', 'ne', 'contains', 'starts'),
  478. 'sortable' => TRUE,
  479. ),
  480. 'TAXRANK:0000006' => array(
  481. 'searchable' => TRUE,
  482. 'name' => 'species',
  483. 'operations' => array('eq', 'ne', 'contains', 'starts'),
  484. 'sortable' => TRUE,
  485. ),
  486. 'TAXRANK:0000045' => array(
  487. 'searchable' => TRUE,
  488. 'name' => 'infraspecies',
  489. 'operations' => array('eq', 'ne', 'contains', 'starts'),
  490. 'sortable' => TRUE,
  491. ),
  492. 'local:infraspecific_type' => array(
  493. 'searchable' => TRUE,
  494. 'name' => 'infraspecific_type',
  495. 'operations' => array('eq', 'ne', 'contains', 'starts'),
  496. 'sortable' => TRUE,
  497. ),
  498. 'entity' => array(
  499. 'searchable' => FALSE,
  500. ),
  501. ),
  502. )
  503. );
  504. * @endcode
  505. *
  506. * If a field does not have a complex nested set of values, but simply returns
  507. * a scalar then the default elementInfo provides default string-based
  508. * searchabilty.
  509. *
  510. * @return
  511. * An associative array of the value elements provided by this field.
  512. */
  513. public function elementInfo() {
  514. $field_term = $this->getFieldTermID();
  515. return array(
  516. $field_term => array(
  517. 'operations' => array('eq', 'ne', 'contains', 'starts'),
  518. 'sortable' => TRUE,
  519. 'searchable' => TRUE,
  520. ),
  521. );
  522. }
  523. /**
  524. * Provides a form for the 'Field Settings' of the field management page.
  525. *
  526. * This is an optional hook function and is similar to the
  527. * hook_field_settings_form function().
  528. *
  529. * @param $has_data
  530. * TRUE if the field already has data, FALSE if not.
  531. */
  532. public function settingsForm($has_data) {
  533. $settings = $this->field['settings'];
  534. $element = array();
  535. $element['#field'] = $this->field;
  536. $element['#instance'] = $this->instance;
  537. $element['#element_validate'][] = 'tripal_field_settings_form_validate';
  538. return $element;
  539. }
  540. /**
  541. *
  542. * @param $form
  543. * @param $form_state
  544. */
  545. public function settingsFormValidate($form, &$form_state) {
  546. }
  547. /**
  548. * Provides a form for the 'Field Settings' of an instance of this field.
  549. *
  550. * This function corresponds to the hook_field_instance_settings_form()
  551. * function of the Drupal Field API.
  552. *
  553. * Validation of the instance settings form is not supported by Drupal, but
  554. * the TripalField class does provide a mechanism for supporting validation.
  555. * To allow for validation of your setting form you must call the parent
  556. * in your child class:
  557. *
  558. * @code
  559. * $element = parent::instanceSettingsForm();
  560. * @endcode
  561. *
  562. * Please note, the form generated with this function does not easily
  563. * support AJAX calls in the same way that other Drupal forms do. If you
  564. * need to use AJAX you must manually alter the $form in your ajax call.
  565. * The typical way to handle updating the form via an AJAX call is to make
  566. * the changes in the form function itself but that doesn't work here.
  567. */
  568. public function instanceSettingsForm() {
  569. $settings = $this->instance['settings'];
  570. $element = array();
  571. $element['#field'] = $this->field;
  572. $element['#instance'] = $this->instance;
  573. $element['#element_validate'][] = 'tripal_field_instance_settings_form_validate';
  574. return $element;
  575. }
  576. /**
  577. * Provides validation of the instance settings form.
  578. *
  579. * There is no equivalent function in the Drupal Field API. Validation
  580. * of instance settings forms in Drupal is not supported. However, the
  581. * TripalField provides this function to fill the gap. See the
  582. * documentation for the instanceSettingsForm() function for instructions
  583. * to support use of this function.
  584. *
  585. * @param $form
  586. * @param $form_state
  587. */
  588. public function instanceSettingsFormValidate($form, &$form_state) {
  589. }
  590. /**
  591. * Afte a field instance is created the following function is run.
  592. *
  593. * This function is equivalent to the hook_field_create_field() hook of
  594. * the Drupal Field API. This function is invoked after a new field
  595. * instance is created.
  596. */
  597. public function createInstance() {
  598. }
  599. /**
  600. * Used to filter records that match a given condition.
  601. *
  602. * Records that belong to a content type can be filtered using the fields.
  603. * This function should be implemented if the field supports filtering as
  604. * specified in the elementInfo() function. With this function, the query
  605. * object appropriate for the storage back-end is passed into the function.
  606. *
  607. * The condition array passesd in will have three values:
  608. * - column: the key indicating how the filter should occur.
  609. * - op: the operation to perform (e.g. equals, contains, starts with etc.
  610. * - value: the value for filtering.
  611. *
  612. * The column used for filtering will be a comma-speperated list of
  613. * controlled vocabulary IDs. This comma-separate list corresponds directly
  614. * to the heirarchy of elements provided by the elementInfo() function.
  615. * For example, if a field provides organism information then it may use
  616. * the OBI:0100026 term for the field, and the term TAXRANK:0000005 for the
  617. * term to indicate the 'Genus'. If these fields are properly organized in
  618. * the elementInfo() function then the "column" of the condition when
  619. * a user wants to search by genus will be: OBI:0100026,TAXRANK:0000005.
  620. *
  621. * @param $query
  622. * A query object appropriate for the data storage backend. For example,
  623. * The Tripal Chado module will provide a SelectQuery object.
  624. * @param $condition
  625. * The field specific condition as set in the TripalFieldQuery object.
  626. */
  627. public function query($query, $condition) {
  628. }
  629. /**
  630. * Used to sort records that have been filtered.
  631. *
  632. * @param $query
  633. * A query object appropriate for the data storage backend. For example,
  634. * The Tripal Chado module will provide a SelectQuery object.
  635. * @param $order
  636. * The field ordering as set in the TripalFieldQuery object. This function
  637. * should handle the ordering request as specified by this object.
  638. */
  639. public function queryOrder($query, $order) {
  640. }
  641. }