TripalField.inc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. <?php
  2. /**
  3. * A base class for all fields supported by Tripal.
  4. *
  5. * The Field API of Drupal defines three "levels" for fields: field types,
  6. * fields, and instances of fields. All fields must be of a specific type, and
  7. * the field types are typically defined using the hook_field_info() hook.
  8. * Normally, using Drupal's Field API, fields can be created by using the
  9. * field_create_field() function which defines the parameters and settings
  10. * for the field. The field_create_instance() function is then used to attach
  11. * a field to a bundle and to set local parameters and settings for the field
  12. * when attached to the bundle. There are also a variety of hooks for creating
  13. * widgets, formatters, customizaing settings forms, loading values, validating
  14. * widget forms, etc. Rather than use all of these hooks, the TripalField class
  15. * is used to consolidate and simplify creation and management of Fields.
  16. *
  17. * A module can extend this class to create new fields, and attach them to
  18. * bundles. The class is structure to allow fields to attach themselves to
  19. * bundles. This is a bit different from how fields would normally be
  20. * attached. But allows a field to be self-aware and all of the functionality
  21. * for a field is self-contained in the Class implementation. To change
  22. * functionality a developer need only edit the class file for a field rathaer
  23. * than look for all of the Field API hook that would typically be spread
  24. * around the module.
  25. *
  26. * This field also supports use of controlled vocabulaaries for providing
  27. * "types" to these fields. This is important for use with the semantic web
  28. * support for Tripal v3.
  29. *
  30. * AJAX callbacks, and theme functions unfortunately cannot be part of the
  31. * implementation of this class. To keep all functionality for a field
  32. * in the same file, it is recommended that those functions, if needed, should
  33. * be added to the bottom of the file where the child class is housed, and each
  34. * TripalField child class should each be written in a separate file.
  35. *
  36. */
  37. class TripalField {
  38. // The type of Entity (e.g. TripalEntity).
  39. protected $entity_type = '';
  40. // The bundle to which this field may be attached.
  41. protected $bundle = NULL;
  42. // The name of this field.
  43. protected $field_name = '';
  44. // The type of field.
  45. protected $field_type = '';
  46. // Set to TRUE if this field is attached to the bundle. TripalFields are
  47. // allowed to decide if they want to be attached to bundles or not.
  48. protected $can_attach = FALSE;
  49. // An array of paramters that can be used by the field. This is typically
  50. // passed by the module that provides the field.
  51. protected $details = array();
  52. /**
  53. * The TripalField constructor.
  54. */
  55. public function __construct($entity_type, $bundle, $details = array()) {
  56. $this->entity_type = $entity_type;
  57. $this->bundle = $bundle;
  58. $this->details = $details;
  59. // Set the field type. This will always be the name of the file. The
  60. // field type, class name and file name must all be identical or things
  61. // will break.
  62. $this->field_type = get_class($this);
  63. // Determine if this field can attach to the bundle.
  64. $this->setCanAttach($bundle, $details);
  65. // Set the field's name.
  66. $this->setFieldName($bundle, $details);
  67. }
  68. /**
  69. * Allows the child class to set the field name.
  70. */
  71. protected function setFieldName() {
  72. // Set the field name to default to be the same as the field type. Any
  73. // classes that extend this one can adjust the field name as needed.
  74. $this->field_name = $this->field_type;
  75. }
  76. /**
  77. * Retrives the name of this field.
  78. *
  79. * @return
  80. * This field's name.
  81. */
  82. public function getFieldName() {
  83. return $this->field_name;
  84. }
  85. /**
  86. * A helper function to determine if this field wants to attach to a bundle.
  87. *
  88. * Any class that extends the TripalField class can override this function but
  89. * it should set the $this->can_attach member to TRUE or FALSE.
  90. *
  91. * @param $entity_type
  92. * The entity type Class to which the bundle belongs.
  93. * @param $bundle.
  94. * An instance of a TripalBundle object. This is the bundle to which
  95. * the field can be added.
  96. * @param $details
  97. * An associative array containing additional details provided by the
  98. * calling module that can be used by the function to determine if the
  99. * bundle should be attached to.
  100. */
  101. protected function setCanAttach() {
  102. $this->can_attach = FALSE;
  103. }
  104. /**
  105. * Retrieves the type of field for this field.
  106. *
  107. * @return
  108. * The field's type.
  109. */
  110. public function getType() {
  111. return $this->field_type;
  112. }
  113. /**
  114. * Retrieves the bundle that this field was provided.
  115. *
  116. * @return
  117. * A bundle object.
  118. */
  119. public function getBundle() {
  120. return $this->bundle;
  121. }
  122. /**
  123. * Indicates if the field should be attached to the bundle.
  124. *
  125. * @return
  126. * TRUE if the field wants to be attached to the bundle that was provdied
  127. * in the constructor. FALSE otherwise.
  128. */
  129. public function canAttach() {
  130. return $this->can_attach;
  131. }
  132. /**
  133. * Provides default settings for the field.
  134. *
  135. * This is a static function and defines defaults for all fields of this
  136. * type.
  137. *
  138. * @return
  139. * An array whose keys are field type names and whose values are arrays
  140. * describing the field type. The keys are the same as for the
  141. * hook_field_info() function, which are:
  142. * - label: The human-readable name of the field type.
  143. * - description: A short description for the field type.
  144. * - settings: An array whose keys are the names of the settings available
  145. * for the field type, and whose values are the default values for those
  146. * settings.
  147. * - instance_settings: An array whose keys are the names of the settings
  148. * available for instances of the field type, and whose values are the
  149. * default values for those settings. Instance-level settings can have
  150. * different values on each field instance, and thus allow greater
  151. * flexibility than field-level settings. It is recommended to put
  152. * settings at the instance level whenever possible. Notable
  153. * exceptions: settings acting on the schema definition, or settings
  154. * that Views needs to use across field instances (for example, the
  155. * list of allowed values).
  156. * - default_widget: The machine name of the default widget to be used by
  157. * instances of this field type, when no widget is specified in the
  158. * instance definition. This widget must be available whenever the field
  159. * type is available (i.e. provided by the field type module, or by a
  160. * module the field type module depends on). Valid names are those
  161. * provided by the widget_info() function of this class.
  162. * - default_formatter: The machine name of the default formatter to be
  163. * used by instances of this field type, when no formatter is specified
  164. * in the instance definition. This formatter must be available whenever
  165. * the field type is available (i.e. provided by the field type module,
  166. * or by a module the field type module depends on). Valid names are
  167. * those provided by the formater_info() function of this class.
  168. * - no_ui: (optional) A boolean specifying that users should not be allowed
  169. * to create fields and instances of this field type through the UI.
  170. * Such fields can only be created programmatically with
  171. * field_create_field() and field_create_instance(). Defaults to
  172. * FALSE.
  173. */
  174. public static function fieldInfo() {
  175. return array(
  176. );
  177. }
  178. /**
  179. * Provides the information required for creating a field.
  180. *
  181. * These settings are global for every instance of the field.
  182. *
  183. * he TripalField class allows a field to decide which bundles it would
  184. * like to attach itself to. Therefore, the entity type, and bundle are
  185. * passed as arguments to allow the field to decide if it wants to be
  186. * attached.
  187. *
  188. * @return
  189. * A field definition array. The return value is identical to that
  190. * provided to the field_create_info() function. The field_name and
  191. * type properties are required. The semantic_web value is also required
  192. * under the settings. Other properties, if omitted, will be
  193. * given the following default values:
  194. * - cardinality: 1
  195. * - locked: FALSE. Set to TRUE if you do not want your field to be
  196. * re-used or deleted.
  197. * - settings: each omitted setting is given the default value
  198. * defined in field_info().
  199. * - semantic_web: a controlled vocabulary term written in the form
  200. * [CV short name]:[accession] (e.g. SO:000745).
  201. * - storage:
  202. * - type: the storage backend specified in the 'field_storage_default'
  203. * system variable.
  204. * - settings: each omitted setting is given the default value specified
  205. * in hook_field_storage_info().
  206. *
  207. * Nothing is returned when this field will not be attached to the bundle.
  208. */
  209. public function createInfo() {
  210. if (!$this->can_attach) {
  211. return;
  212. }
  213. }
  214. /**
  215. * Provides the information required for creating an instance of a field.
  216. *
  217. * A field instance is a field that has been created using the values provided
  218. * by the create_info() function of this class, and which is attached to
  219. * a bundle.
  220. *
  221. * The TripalField class allows a field to decide which bundles it would
  222. * like to attach itself to. Therefore, the entity type, and bundle are
  223. * passed as arguments to allow the field to decide if it wants to be
  224. * attached and if so then this function will provide the details to create
  225. * the field. The field instance can later be attached to the bundle
  226. * using information provided by the create_instance_info() function.
  227. *
  228. * @param $entity_type
  229. * The entity type Class to which the bundle belongs.
  230. * @param $bundle.
  231. * An instance of a TripalBundle object. This is the bundle to which
  232. * the field can be added.
  233. * @param $details
  234. * An associative array containing additional details provided by the
  235. * calling module that can be used by the function to determine if the
  236. * bundle should be attached to.
  237. *
  238. * @return
  239. * A field instance definition array. The values of thie array are identical
  240. * to those passed to the field_create_instance() function. The field_name,
  241. * entity_type and bundle (name of the bundle) properties are required.
  242. * Other properties, if omitted, will be given the following default values:
  243. * - label: the field name
  244. * - description: empty string
  245. * - required: FALSE
  246. * - default_value_function: empty string
  247. * - settings: each omitted setting is given the default value specified
  248. * in hook_field_info().
  249. * - widget:
  250. * - type: the default widget specified in field_info().
  251. * - settings: each omitted setting is given the default value specified
  252. * in widget_info().
  253. * - display: An instance can support multiple view modes. Eeach mode must
  254. * be listed as a separate key (e.g. 'default') with a the following
  255. * values (and their default specified below. If display is not
  256. * included then the settings for the 'default' view mode will be added
  257. * automatically, and each view mode in the definition will be completed
  258. * with the following default values:
  259. * - label: 'above'
  260. * - type: the default formatter specified in field_info().
  261. * - settings: each omitted setting is given the default value specified
  262. * in formatter_info(). A setting specific to TripalFields is the
  263. * 'auto_attach'. If this settings is set to TRUE then the field
  264. * will be automatically attached to the entity. IF FALSE then it
  265. * will not be and can be attached with a separate field_attach_load()
  266. * call. If not specified the default is FALSE.
  267. * View modes not present in the definition are left empty, and the
  268. * field will not be displayed in this mode.
  269. *
  270. * Nothing is returned when this field will not be attached to the bundle.
  271. */
  272. public function createInstanceInfo() {
  273. if (!$this->can_attach) {
  274. return;
  275. }
  276. }
  277. /**
  278. * Provides information about the widgets provided by this field.
  279. *
  280. * This function returns an array describing the widget types implemented by
  281. * the field. The widgets created by this field are expecte to be used only
  282. * by this field.
  283. *
  284. * This is a static function as it provides default values for all of the
  285. * widgets for this field type, and thus we don't need an instantiated
  286. * object to provide this information.
  287. *
  288. * @param $entity_type
  289. * The entity type Class to which the bundle belongs.
  290. * @param $bundle.
  291. * An instance of a TripalBundle object. This is the bundle to which
  292. * the field can be added.
  293. * @param $details
  294. * An associative array containing additional details provided by the
  295. * calling module that can be used by the function to determine if the
  296. * bundle should be attached to.
  297. *
  298. * @return
  299. * An associative array where the keys are widget type names. To avoid
  300. * name clashes, widget type names should be prefixed with the name of
  301. * the module that exposes them. The values are arrays describing the
  302. * widget type, with the following key/value pairs:
  303. *
  304. * - label: The human-readable name of the widget type.
  305. * - description: A short description for the widget type.
  306. * - field types: An array of field types the widget supports.
  307. * - settings: An array whose keys are the names of the settings
  308. * available for the widget type, and whose values are the default
  309. * values for those settings.
  310. * - behaviors: (optional) An array describing behaviors of the widget,
  311. * with the following elements:
  312. * - multiple values: One of the following constants:
  313. * - FIELD_BEHAVIOR_DEFAULT: (default) If the widget allows the
  314. * input of one single field value (most common case). The widget
  315. * will be repeated for each value input.
  316. * - FIELD_BEHAVIOR_CUSTOM: If one single copy of the widget can
  317. * receive several field values. Examples: checkboxes, multiple
  318. * select, comma-separated textfield.
  319. * - default value: One of the following constants:
  320. * - FIELD_BEHAVIOR_DEFAULT: (default) If the widget accepts
  321. * default values.
  322. * - FIELD_BEHAVIOR_NONE: if the widget does not support
  323. * default values.
  324. * - weight: (optional) An integer to determine the weight of this
  325. * widget relative to other widgets in the Field UI when selecting a
  326. * widget for a given field instance.
  327. */
  328. public static function widgetInfo() {
  329. return array(
  330. );
  331. }
  332. /**
  333. * Provides information about the formatter for this field.
  334. *
  335. * This is a static function as it provides default values for all of the
  336. * formatters for this field type, and thus we don't need an instantiated
  337. * object to provide this information.
  338. *
  339. * @return
  340. * An associative array with key/value paris compatible with those from the
  341. * hook_field_formatter_info() function of the Drupal Field API.
  342. *
  343. */
  344. public static function formatterInfo() {
  345. return array(
  346. );
  347. }
  348. /**
  349. * Provides a summary of the formatter settings.
  350. *
  351. * On the 'Manage Display' page of the content type administration page,
  352. * fields are allowed to provide a settings form. This settings form can
  353. * be used to allow the site admin to define how the field should be
  354. * formatted. The settings are then available for the formatter()
  355. * function of this class. This function provides a text-based description
  356. * of the settings for the site developer to see. It appears on the manage
  357. * display page inline with the field. A field must always return a
  358. * value in this function if the settings form gear button is to appear.
  359. *
  360. * See the hook_field_formatter_settings_summary() function for more
  361. * information.
  362. *
  363. * @param $field
  364. * @param $instance
  365. * @param $view_mode
  366. *
  367. * @return string
  368. * A string that provides a very brief summary of the field settings
  369. * to the user.
  370. *
  371. */
  372. public static function formatterSettingsSummary($field, $instance, $view_mode) {
  373. }
  374. /**
  375. * Provides the field's setting form.
  376. *
  377. * The settings form appears on the 'Manage Display' page of the content
  378. * type administration page. This function provides the form that will
  379. * appear on that page.
  380. *
  381. * To add a validate function, please create a static function in the
  382. * implementing class, and indicate that this function should be used
  383. * in the form array that is returned by this function.
  384. *
  385. * This form will not be displayed if the formatter_settings_summary()
  386. * function does not return anything.
  387. *
  388. * @param $field
  389. * @param $instance
  390. * @param $view_mode
  391. * @param $form
  392. * @param $form_state
  393. *
  394. * @return
  395. * A Drupal Form array containing the settings form for this field.
  396. */
  397. public static function formatterSettingsForm($field, $instance,
  398. $view_mode, $form, &$form_state) {
  399. }
  400. /**
  401. * Provides the display for a field
  402. *
  403. * This function provides the display for a field when it is viewed on
  404. * the web page. The content returned by the formatter should only include
  405. * what is present in the $items[$delta]['values] array. This way, the
  406. * contents that are displayed on the page, via webservices and downloaded
  407. * into a CSV file will always be identical. The view need not show all
  408. * of the data in the 'values' array.
  409. *
  410. * @param $element
  411. * @param $entity_type
  412. * @param $entity
  413. * @param $field
  414. * @param $instance
  415. * @param $langcode
  416. * @param $items
  417. * @param $display
  418. *
  419. * @return
  420. * An element array compatible with that returned by the
  421. * hook_field_formatter_view() function.
  422. */
  423. public static function formatterView(&$element, $entity_type, $entity,
  424. $field, $instance, $langcode, $items, $display) {
  425. foreach($items as $delta => $item) {
  426. $element[$delta] = array(
  427. '#type' => 'markup',
  428. '#markup' => $item['value'],
  429. );
  430. }
  431. }
  432. /**
  433. * Provides the form for editing of this field.
  434. *
  435. * This form is diplayed when the user creates a new entity or edits an
  436. * existing entity. If the field is attached to the entity then the form
  437. * provided by this function will be displayed.
  438. *
  439. * At a minimum, the form must have a 'value' element. For Tripal, the
  440. * 'value' element of a field always corresponds to the value that is
  441. * presented to the end-user either directly on the page (with formatting)
  442. * or via web services, or some other mechanism. However, the 'value' is
  443. * sometimes not enough for a field. For example, the Tripal Chado module
  444. * maps fields to table columns and sometimes those columns are foreign keys
  445. * therefore, the Tripal Chado modules does not use the 'value' but adds
  446. * additional elements to help link records via FKs. But even in this case
  447. * the 'value' element must always be present in the returne form and in such
  448. * cases it's value should be set equal to that added in the 'load' function.
  449. *
  450. * @param $widget
  451. * @param $form
  452. * @param $form_state
  453. * @param $field
  454. * @param $instance
  455. * @param $langcode
  456. * @param $items
  457. * @param $delta
  458. * @param $element
  459. *
  460. * @return
  461. * A Drupal form. See the hook_field_widget_form() function for more information.
  462. */
  463. public static function widgetForm(&$widget, &$form, &$form_state, $field, $instance,
  464. $langcode, $items, $delta, $element) {
  465. $widget['value'] = array(
  466. '#type' => 'value',
  467. '#value' => array_key_exists($delta, $items) ? $items[$delta]['value'] : '',
  468. );
  469. }
  470. /**
  471. * Perform validation of the widget_form when adding or editing the entity.
  472. *
  473. * Any errors encountered should be indicatd by adding a value to the $errors
  474. * array according to the instructions below.
  475. *
  476. * @param $entity_type
  477. * The type of $entity.
  478. * @param $entity
  479. * The entity for the operation.
  480. * @param $field
  481. * The field structure for the operation.
  482. * @param $instance
  483. * The instance structure for $field on $entity's bundle.
  484. * @param $langcode
  485. * The language associated with $items.
  486. * @param $items
  487. * $entity->{$field['field_name']}[$langcode], or an empty array if unset.
  488. * @param $errors
  489. * The array of errors (keyed by field name, language code, and delta) that
  490. * have already been reported for the entity. The function should add its
  491. * errors to this array. Each error is an associative array with the
  492. * following keys and values:
  493. * - error: An error code (should be a string prefixed with the
  494. * module name).
  495. * - message: The human readable message to be displayed.
  496. *
  497. */
  498. public static function widgetFormValidate($entity_type, $entity, $field, $instance, $langcode,
  499. $items, &$errors) {
  500. }
  501. /**
  502. * Performs extra commands when the entity form is submitted.
  503. *
  504. * Drupal typically does not provide a submit hook for fields. The
  505. * TripalField provides one to allow for behind-the-scenes actions to
  506. * occur. This function should never be used for updates, deletes or
  507. * inserts into the storage backend. Rather, the appropriate Field Storage
  508. * implementation will take care of that. An example where this function
  509. * may be useful would be to set values in the $items array using values
  510. * of the other.
  511. *
  512. * @param $entity_type
  513. * The type of $entity.
  514. * @param $entity
  515. * The entity for the operation.
  516. * @param $field
  517. * The field structure for the operation.
  518. * @param $instance
  519. * The instance structure for $field on $entity's bundle.
  520. * @param $langcode
  521. * The language associated with $items.
  522. * @param $items
  523. * $entity->{$field['field_name']}[$langcode], or an empty array if unset.
  524. * @param $form
  525. * The submitted form array.
  526. * @param $form_state.
  527. * The form state array.
  528. */
  529. public static function widgetFormSubmit($entity_type, $entity, $field, $instance, $langcode,
  530. &$items, $form, &$form_state) {
  531. }
  532. /**
  533. * Loads the field values from the underlying data store.
  534. *
  535. * @param $field
  536. * @param $entity
  537. * @param $details
  538. *
  539. * @return
  540. * An array of the following format:
  541. * $entity->{$field_name}['und'][0]['value'] = $value;
  542. * where:
  543. * - $entity is the enity object to which this field is attached.
  544. * - $field_name is the name of this field
  545. * - 'und' is the language code (in this case 'und' == undefined)
  546. * - 0 is the cardinality. Increment by 1 when more than one item is
  547. * available.
  548. * - 'value' is the key indicating the value of this field. It should
  549. * always be set. The value of the 'value' key will be the contents
  550. * used for web services and for downloadable content. The value
  551. * should be of the follow format types: 1) A single value (text,
  552. * numeric, etc.) 2) An array of key value pair. 3) If multiple entries
  553. * then cardinality should incremented and format types 1 and 2 should
  554. * be used for each item.
  555. * The array may contain as many other keys at the same level as 'value'
  556. * but those keys are for internal field use and are not considered the
  557. * value of the field.
  558. *
  559. *
  560. */
  561. public static function load($field, $entity, $details = array()) {
  562. }
  563. /**
  564. * Provides a form for the 'Field Settings' of the field management page.
  565. *
  566. * This is an optional hook function and is similar to the
  567. * hook_field_settings_form function().
  568. *
  569. * @param $field
  570. * The field structure being configured.
  571. * @param $instance
  572. * The instance structure being configured.
  573. * @param $has_data
  574. * TRUE if the field already has data, FALSE if not.
  575. */
  576. public function settingsForm($field, $instance, $has_data) {
  577. $settings = $field['settings'];
  578. $element = array();
  579. // $element['semantic_web'] = array(
  580. // '#type' => 'textfield',
  581. // '#title' => 'Semantic Web',
  582. // '#description' => t('Each field must be associated with a term
  583. // from a controlled vocabulary. This allows computer programs to understand
  584. // the data provided on this site. Please be cautions changing these
  585. // values. Defaults are set by Tripal and sites that use the same
  586. // terms can exchange information.'),
  587. // '#collapsed' => TRUE,
  588. // '#collapsible' => TRUE,
  589. // '#tree' => TRUE,
  590. // );
  591. return $element;
  592. }
  593. /**
  594. * Describes this fields "data tables" to Views.
  595. *
  596. * This function is the equivalent of the hook_views_data() function of
  597. * the Drupal Views API. It provides the necessary details to allow
  598. * Views to integrate the field.
  599. *
  600. * @return
  601. * An associative array describing the data structure of the field.
  602. */
  603. public static function viewsDataAlter(&$data, $field, $entity_info) {
  604. }
  605. }