TripalField.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  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. ' .
  14. 'Replace this text as appropriate for the child implementation.';
  15. // Provide a list of global settings. These can be accessed witihn the
  16. // globalSettingsForm. When the globalSettingsForm is submitted then
  17. // Drupal will automatically change these settings for all fields.
  18. // Once instances exist for a field type then these settings cannot be
  19. // changed.
  20. public static $default_settings = array(
  21. 'storage' => 'tripal_no_storage',
  22. // It is expected that all fields set a 'value' in the load() function.
  23. // In many cases, the value may be an associative array of key/value pairs.
  24. // In order for Tripal to provide context for all data, the keys should
  25. // be a controlled vocabulary term (e.g. rdfs:type). Keys in the load()
  26. // function that are supported by the query() function should be
  27. // listed here.
  28. 'searchable_keys' => array(),
  29. );
  30. // Provide a list of instance specific settings. These can be access within
  31. // the instanceSettingsForm. When the instanceSettingsForm is submitted
  32. // then Drupal with automatically change these settings for the instnace.
  33. // It is recommended to put settings at the instance level whenever possible.
  34. // If you override this variable in a child class be sure to replicate the
  35. // term_name, term_vocab, term_accession and term_fixed keys as these are
  36. // required for all TripalFields.
  37. public static $default_instance_settings = array(
  38. // The short name for the vocabulary (e.g. shcema, SO, GO, PATO, etc.).
  39. 'term_vocabulary' => 'schema',
  40. // The name of the term.
  41. 'term_name' => 'Thing',
  42. // The unique ID (i.e. accession) of the term.
  43. 'term_accession' => 'Thing',
  44. // Set to TRUE if the site admin is not allowed to change the term
  45. // type, otherwise the admin can change the term mapped to a field.
  46. 'term_fixed' => FALSE,
  47. // Inidates if this field should be automatically attached to display
  48. // or web services or if this field should be loaded separately. This
  49. // is convenient for speed. Fields that are slow should for loading
  50. // should ahve auto_attach set to FALSE so tha their values can be
  51. // attached asyncronously.
  52. 'auto_attach' => TRUE,
  53. );
  54. // The default widget for this field.
  55. public static $default_widget = '';
  56. // The default formatter for this field.
  57. public static $default_formatter = '';
  58. // The module that manages this field.
  59. public static $module = 'tripal';
  60. // A boolean specifying that users should not be allowed to create
  61. // fields and instances of this field type through the UI. Such
  62. // fields can only be created programmatically with field_create_field()
  63. // and field_create_instance().
  64. public static $no_ui = TRUE;
  65. // --------------------------------------------------------------------------
  66. // PROTECTED CLASS MEMBERS -- DO NOT OVERRIDE
  67. // --------------------------------------------------------------------------
  68. // An array containing details about the field. The format of this array
  69. // is the same as that returned by field_info_fields()
  70. protected $field;
  71. // An array containing details about an instance of the field. A field does
  72. // not have to have an instance. But if dealing with an instance (such as
  73. // when using the widgetForm, formatterSettingsForm, etc.) it should be set.
  74. protected $instance;
  75. // --------------------------------------------------------------------------
  76. // CONSTRUCTORS -- DO NOT OVERRIDE
  77. // --------------------------------------------------------------------------
  78. /**
  79. * Instantiates a new TripalField object.
  80. *
  81. * @param $field
  82. * An array containing the field data as returned by field_info_field().
  83. * @param $instance
  84. * An array containing the instance data as returned by field_instance_info().
  85. */
  86. public function __construct($field, $instance) {
  87. $this->field = $field;
  88. $this->instance = $instance;
  89. $class = get_called_class();
  90. // Make sure the term exist.
  91. if (!$instance) {
  92. tripal_set_message(t('Missing instance of field "%field"', array('%field' => $field['field_name'])), TRIPAL_ERROR);
  93. }
  94. else {
  95. // If the vocabulary and accession are set then make sure that the
  96. // term is a real term. It is possible that the vocabulary and accession
  97. // may not be set initially. This occurs when a field is created
  98. // dynamically be a priviledge site admin.
  99. if (array_key_exists('term_vocabulary', $instance['settings'])) {
  100. $vocabulary = $instance['settings']['term_vocabulary'];
  101. $accession = $instance['settings']['term_accession'];
  102. $term = tripal_get_term_details($vocabulary, $accession);
  103. if (!$term) {
  104. throw new Error(t('Cannot create TripalField of type "%term" as that
  105. term does not exist.', array('%term' => "$vocabulary:$accession")));
  106. }
  107. }
  108. }
  109. }
  110. // --------------------------------------------------------------------------
  111. // STATIC INFO FUNCTIONS -- DO NOT OVERRIDE
  112. // --------------------------------------------------------------------------
  113. /**
  114. * Provides default information about this field type
  115. *
  116. * This function corresponds to the hook_field_info() function of
  117. * the Drupal Field API.
  118. *
  119. * @return
  120. * An array whose keys are field type names and whose values are arrays
  121. * describing the field type. The keys are the same as for the
  122. * hook_field_info() function.
  123. */
  124. public static function info() {
  125. $class = get_called_class();
  126. $info = array(
  127. 'label' => $class::$default_label,
  128. 'description' => $class::$default_description,
  129. 'settings' => $class::$default_settings,
  130. 'instance_settings' => $class::$default_instance_settings,
  131. 'default_widget' => $class::$default_widget,
  132. 'default_formatter' => $class::$default_formatter,
  133. 'no_ui' => $class::$no_ui,
  134. );
  135. return $info;
  136. }
  137. // --------------------------------------------------------------------------
  138. // GETTERS AND SETTERS -- DO NOT OVERRIDE
  139. // --------------------------------------------------------------------------
  140. /**
  141. * Retrives the name of this field.
  142. *
  143. * @return
  144. * This field's name.
  145. */
  146. public function getFieldName() {
  147. return $this->field['field_name'];
  148. }
  149. public function getField() {
  150. return $this->field;
  151. }
  152. public function getInstance() {
  153. return $this->instance;
  154. }
  155. // --------------------------------------------------------------------------
  156. // OVERRIDEABLE FUNCTIONS
  157. // --------------------------------------------------------------------------
  158. /**
  159. * Perform validation of the field regardless how it is updated.
  160. *
  161. * Any errors encountered should be indicated by adding a value to the
  162. * $errors array according to the instructions below.
  163. *
  164. * @param $entity_type
  165. * The type of $entity.
  166. * @param $entity
  167. * The entity for the operation.
  168. * @param $field
  169. * The field structure for the operation.
  170. * @param $instance
  171. * The instance structure for $field on $entity's bundle.
  172. * @param $langcode
  173. * The language associated with $items.
  174. * @param $items
  175. * $entity->{$field['field_name']}[$langcode], or an empty array if unset.
  176. * @param $errors
  177. * The array of errors (keyed by field name, language code, and delta) that
  178. * have already been reported for the entity. The function should add its
  179. * errors to this array. Each error is an associative array with the
  180. * following keys and values:
  181. * - error: An error code (should be a string prefixed with the
  182. * module name).
  183. * - message: The human readable message to be displayed.
  184. *
  185. */
  186. public function validate($entity_type, $entity, $field, $items, &$errors) {
  187. }
  188. /**
  189. * Loads the field values from the underlying data store.
  190. *
  191. * @param $entity
  192. * @param $details
  193. *
  194. * @return
  195. * An array of the following format:
  196. * $entity->{$field_name}['und'][0]['value'] = $value;
  197. * where:
  198. * - $entity is the enity object to which this field is attached.
  199. * - $field_name is the name of this field
  200. * - 'und' is the language code (in this case 'und' == undefined)
  201. * - 0 is the cardinality. Increment by 1 when more than one item is
  202. * available.
  203. * - 'value' is the key indicating the value of this field. It should
  204. * always be set. The value of the 'value' key will be the contents
  205. * used for web services and for downloadable content. The value
  206. * should be of the follow format types: 1) A single value (text,
  207. * numeric, etc.) 2) An array of key value pair. 3) If multiple entries
  208. * then cardinality should incremented and format types 1 and 2 should
  209. * be used for each item.
  210. * The array may contain as many other keys at the same level as 'value'
  211. * but those keys are for internal field use and are not considered the
  212. * value of the field.
  213. *
  214. *
  215. */
  216. public function load($entity, $details = array()) {
  217. }
  218. /**
  219. * Provides a form for the 'Field Settings' of the field management page.
  220. *
  221. * This is an optional hook function and is similar to the
  222. * hook_field_settings_form function().
  223. *
  224. * @param $has_data
  225. * TRUE if the field already has data, FALSE if not.
  226. */
  227. public function settingsForm($has_data) {
  228. $settings = $this->field['settings'];
  229. $element = array();
  230. $element['#field'] = $this->field;
  231. $element['#instance'] = $this->instance;
  232. $element['#element_validate'][] = 'tripal_field_settings_form_validate';
  233. return $element;
  234. }
  235. /**
  236. *
  237. * @param unknown $form
  238. * @param unknown $form_state
  239. */
  240. public function settingsFormValidate($form, &$form_state) {
  241. }
  242. /**
  243. * Describes this field to Views.
  244. *
  245. * An array of views data, in the same format as the return value of
  246. * hook_views_data().
  247. *
  248. */
  249. public function viewsData() {
  250. $data = array();
  251. $bundle_name = $this->instance['bundle'];
  252. $field_name = $this->field['field_name'];
  253. $data[$bundle_name][$field_name] = array(
  254. 'title' => $this->instance['label'],
  255. 'help' => $this->instance['description'],
  256. 'field' => array(
  257. 'handler' => 'tripal_views_handler_field',
  258. 'click sortable' => TRUE,
  259. ),
  260. 'filter' => array(
  261. 'handler' => 'tripal_views_handler_filter_string',
  262. ),
  263. 'sort' => array(
  264. 'handler' => 'views_handler_sort',
  265. ),
  266. );
  267. return $data;
  268. }
  269. /**
  270. * Allows the view data for this field to be altered.
  271. *
  272. * This function is the equivalent of the hook_field_views_data_alter()
  273. * function of the Drupal Field API. It provides the necessary details to
  274. * allow views to integrate the field.
  275. *
  276. * @param $data
  277. * An array of views table data provided for a single field. This has the
  278. * same format as the return value of hook_views_data().
  279. */
  280. public function viewsDataAlter(&$data) {
  281. }
  282. /**
  283. * Provides a form for the 'Field Settings' of an instance of this field.
  284. *
  285. * This function corresponds to the hook_field_instance_settings_form()
  286. * function of the Drupal Field API.
  287. *
  288. * Validation of the instance settings form is not supported by Drupal, but
  289. * the TripalField class does provide a mechanism for supporting validation.
  290. * To allow for validation of your setting form you must call the parent
  291. * in your child class:
  292. *
  293. * @code
  294. * $element = parent::instanceSettingsForm();
  295. * @endcode
  296. *
  297. * Please note, the form generated with this function does not easily
  298. * support AJAX calls in the same way that other Drupal forms do. If you
  299. * need to use AJAX you must manually alter the $form in your ajax call.
  300. * The typical way to handle updating the form via an AJAX call is to make
  301. * the changes in the form function itself but that doesn't work here.
  302. */
  303. public function instanceSettingsForm() {
  304. $settings = $this->instance['settings'];
  305. $element = array();
  306. $element['#field'] = $this->field;
  307. $element['#instance'] = $this->instance;
  308. $element['#element_validate'][] = 'tripal_field_instance_settings_form_validate';
  309. return $element;
  310. }
  311. /**
  312. * Provides validation of the instance settings form.
  313. *
  314. * There is no equivalent function in the Drupal Field API. Validation
  315. * of instance settings forms in Drupal is not supported. However, the
  316. * TripalField provides this function to fill the gap. See the
  317. * documentation for the instanceSettingsForm() function for instructions
  318. * to support use of this function.
  319. *
  320. * @param $form
  321. * @param $form_state
  322. */
  323. public function instanceSettingsFormValidate($form, &$form_state) {
  324. }
  325. /**
  326. * Afte a field instance is created the following function is run.
  327. *
  328. * This function is equivalent to the hook_field_create_field() hook of
  329. * the Drupal Field API. This function is invoked after a new field
  330. * instance is created.
  331. */
  332. public function createInstance() {
  333. }
  334. /**
  335. * Used to filter records that match a given condition.
  336. *
  337. * Entities can be filtered using the fields. This function should be
  338. * implemented if the field supports filtering. To provide filtering,
  339. * the $query object should be updated to including any joins and
  340. * conditions necessary. The following rules should be followed when
  341. * implementing this function:
  342. * - Any keys from the value array that support filtering should be set
  343. * in the $default_settings['searchable_keys'] array of this class file.
  344. * - Implement support for every key in the
  345. * $default_settings['searchable_keys'] array.
  346. * - However, avoid making filteres for non-indexed database columns.
  347. * - This function should never set the fields that should be returned
  348. * nor ordering or group by.
  349. *
  350. * @param $query
  351. * A query object appropriate for the data storage backend. For example,
  352. * The Tripal Chado module will provide a SelectQuery object.
  353. * @param $condition
  354. * The field specific condition as set in the TripalFieldQuery object.
  355. */
  356. public function query($query, $condition) {
  357. }
  358. /**
  359. * Used to sort records that have been filtered.
  360. *
  361. * @param $query
  362. * A query object appropriate for the data storage backend. For example,
  363. * The Tripal Chado module will provide a SelectQuery object.
  364. * @param $order
  365. * The field ordering as set in the TripalFieldQuery object. This function
  366. * should handle the ordering request as specified by this object.
  367. */
  368. public function queryOrder($query, $order) {
  369. }
  370. }