editableviews_handler_field_entity_metadata_property.inc

  1. cis7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  2. cle7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  3. ecd7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  4. elmsmedia7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  5. harmony7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  6. icor7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  7. meedjum_blog7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
  8. mooc7 sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc

Classes

Namesort descending Description
editableviews_handler_field_entity_metadata_property Field handler for editing an entity metadata property.

File

sites/all/modules/ulmus/editableviews/handlers/editableviews_handler_field_entity_metadata_property.inc
View source
  1. <?php
  2. /**
  3. * Field handler for editing an entity metadata property.
  4. *
  5. * This allows editing of Entity API metadata properties, as defined in
  6. * hook_entity_property_info(). To qualify, a property have a 'setter callback'
  7. * defined.
  8. */
  9. class editableviews_handler_field_entity_metadata_property extends views_handler_field {
  10. /**
  11. * Boolean to indicate to the style plugin that this field is editable.
  12. */
  13. public $editable = TRUE;
  14. function option_definition() {
  15. $options = parent::option_definition();
  16. $options['property'] = array('default' => NULL);
  17. $options['form_use_label'] = array('default' => FALSE);
  18. $options['reverse_boolean'] = array('default' => FALSE);
  19. return $options;
  20. }
  21. function options_form(&$form, &$form_state) {
  22. parent::options_form($form, $form_state);
  23. $table_data = views_fetch_data($this->table);
  24. $entity_info = entity_get_info($table_data['table']['entity type']);
  25. $entity_property_info = entity_get_property_info($table_data['table']['entity type']);
  26. // Create an array of grouped options.
  27. $options = array();
  28. // Common properties.
  29. $label_common = t('Common');
  30. $options[$label_common] = array();
  31. if (isset($entity_info['entity keys']['bundle'])) {
  32. // Entity API makes the bundle entity key settable, presumably for
  33. // creating new entities. That's really not going to fly here.
  34. // (No need to check it exists before we attempt to unset it.)
  35. unset($entity_property_info['properties'][$entity_info['entity keys']['bundle']]);
  36. }
  37. foreach ($entity_property_info['properties'] as $property_name => $property_info) {
  38. if (empty($property_info['setter callback'])) {
  39. // We can't do anything with a property that has no information about
  40. // how to set it.
  41. continue;
  42. }
  43. if (!empty($property_info['field'])) {
  44. // FieldAPI fields have their own handler that does a far better job
  45. // (with widgets, etc) than this can do.
  46. continue;
  47. }
  48. $options[$label_common][$property_name] = $property_info['label'];
  49. }
  50. // Bundle-specific properties.
  51. foreach ($entity_property_info['bundles'] as $bundle_name => $bundle_info) {
  52. $bundle_label = $entity_info['bundles'][$bundle_name]['label'];
  53. $options[$bundle_label] = array();
  54. foreach ($bundle_info['properties'] as $property_name => $property_info) {
  55. if (empty($property_info['setter callback'])) {
  56. // We can't do anything with a property that has no information about
  57. // how to set it.
  58. continue;
  59. }
  60. if (!empty($property_info['field'])) {
  61. // FieldAPI fields have their own handler that does a far better job
  62. // (with widgets, etc) than this can do.
  63. continue;
  64. }
  65. $options[$bundle_label][$property_name] = $property_info['label'];
  66. }
  67. }
  68. $form['property'] = array(
  69. '#type' => 'select',
  70. '#title' => t('Metadata property'),
  71. '#options' => $options,
  72. '#description' => t('Select the property to edit with this field. (Only properties that define how they may be set on an entity are available. Be sure to ensure the property applies to all entities the View will show.)'),
  73. '#default_value' => $this->options['property'],
  74. // Views AJAX magic which I don't pretend to understand, which allows a
  75. // dependent form element for 'reverse_boolean'.
  76. '#ajax' => array(
  77. 'path' => views_ui_build_form_url($form_state),
  78. ),
  79. '#submit' => array('views_ui_config_item_form_submit_temporary'),
  80. '#executes_submit_callback' => TRUE,
  81. );
  82. $form['form_use_label'] = array(
  83. '#type' => 'checkbox',
  84. '#title' => t('Use handler label for form element'),
  85. '#description' => t('Use the label for this handler on the form element, rather than the label set in metadata properties which is not always suited to non-developer consumption.'),
  86. '#default_value' => $this->options['form_use_label'],
  87. );
  88. if ($this->options['property']) {
  89. $entity_all_property_info = entity_get_all_property_info($table_data['table']['entity type']);
  90. $selected_property_info = $entity_all_property_info[$this->options['property']];
  91. if ($selected_property_info['type'] == 'boolean') {
  92. $form['reverse_boolean'] = array(
  93. '#type' => 'checkbox',
  94. '#title' => t('Reverse checkbox value'),
  95. '#description' => t('Reverse the value of the boolean property in the checkbox. Use this for properties which make more sense to the user when inverted.'),
  96. '#default_value' => $this->options['reverse_boolean'],
  97. );
  98. }
  99. }
  100. }
  101. /**
  102. * Return the name of the entity property this handler controls.
  103. */
  104. function field_name() {
  105. return $this->options['property'];
  106. }
  107. /**
  108. * Render the field.
  109. *
  110. * Override this as otherwise we'd just output the entity ID all the time.
  111. *
  112. * @param $values
  113. * The values retrieved from the database.
  114. */
  115. function render($values) {
  116. // Don't return anything. We don't know the entity we're on at this point.
  117. // TODO: split up insert_form_elements() to do all the joining up of data
  118. // before parent::render_fields() is called, and set the entity on the
  119. // handlers. This would allow us to output the value of the property here.
  120. return '';
  121. }
  122. /**
  123. * Add the edit form for the field.
  124. */
  125. function edit_form($entity_type, $entity, &$element, &$form_state) {
  126. // Something weird in Views admin UI causes us to come here (because the
  127. // style plugin gets rendered) without the options set on this handler. This
  128. // then causes an AJAX error because further down we access a metadata
  129. // wrapper with no property. I have no time to go chasing this right now, so
  130. // for now, just bail here if we're not properly set up. Doing this appears
  131. // to have no adverse or visible side effects.
  132. if (empty($this->options['property'])) {
  133. return;
  134. }
  135. $wrapper = entity_metadata_wrapper($entity_type, $entity);
  136. // Get the info for the property we are working with. We only need to get
  137. // this once.
  138. if (!isset($this->property_info)) {
  139. $this->property_info = $wrapper->getPropertyInfo($this->options['property']);
  140. }
  141. if (isset($this->property_info['options list'])) {
  142. // Special case: if the property has an 'options list' defined, we can
  143. // show a select form element of options.
  144. $this->edit_form_element_select($element, $form_state, $wrapper);
  145. }
  146. else {
  147. // The type of form element we add depends on the type of the property.
  148. // This is just a best guess.
  149. // TODO: add an option to override this?
  150. switch ($this->property_info['type']) {
  151. case 'boolean':
  152. $this->edit_form_element_checkbox($element, $form_state, $wrapper);
  153. break;
  154. default:
  155. $this->edit_form_element_textfield($element, $form_state, $wrapper);
  156. break;
  157. }
  158. }
  159. // Set the title property.
  160. if ($this->options['form_use_label']) {
  161. $element[$this->options['property']]['#title'] = $this->options['label'];
  162. }
  163. else {
  164. $element[$this->options['property']]['#title'] = check_plain($this->property_info['label']);
  165. }
  166. }
  167. /**
  168. * Create a textfield element.
  169. *
  170. * @param &$element
  171. * The element to alter.
  172. * @param &$form_state
  173. * The form state.
  174. * @param $wrapper
  175. * The wrapper for the entity whose property is to be shown in the element.
  176. */
  177. function edit_form_element_textfield(&$element, &$form_state, $wrapper) {
  178. // Just do the same thing as node_content_form().
  179. $element[$this->options['property']] = array(
  180. '#type' => 'textfield',
  181. '#required' => !empty($this->property_info['required']),
  182. // The value might not be set in the case where we're on a non-required
  183. // relationship with empty data. TODO???
  184. '#default_value' => $wrapper->{$this->options['property']}->raw(),
  185. //'#size' => $this->options['textfield_size'],
  186. '#maxlength' => 255,
  187. );
  188. }
  189. /**
  190. * Create a select element.
  191. *
  192. * @param &$element
  193. * The element to alter.
  194. * @param &$form_state
  195. * The form state.
  196. * @param $wrapper
  197. * The wrapper for the entity whose property is to be shown in the element.
  198. */
  199. function edit_form_element_select(&$element, &$form_state, $wrapper) {
  200. // Just do the same thing as node_content_form().
  201. $element[$this->options['property']] = array(
  202. '#type' => 'select',
  203. '#required' => !empty($this->property_info['required']),
  204. '#options' => $wrapper->{$this->options['property']}->optionsList(),
  205. // The value might not be set in the case where we're on a non-required
  206. // relationship with empty data. TODO???
  207. '#default_value' => $wrapper->{$this->options['property']}->raw(),
  208. );
  209. }
  210. /**
  211. * Create a checkbox element.
  212. *
  213. * @param &$element
  214. * The element to alter.
  215. * @param &$form_state
  216. * The form state.
  217. * @param $wrapper
  218. * The wrapper for the entity whose property is to be shown in the element.
  219. */
  220. function edit_form_element_checkbox(&$element, &$form_state, $wrapper) {
  221. $default_value = $wrapper->{$this->options['property']}->raw();
  222. if ($this->options['reverse_boolean']) {
  223. $default_value = !$default_value;
  224. }
  225. $element[$this->options['property']] = array(
  226. '#type' => 'checkbox',
  227. '#required' => !empty($this->property_info['required']),
  228. // The value might not be set in the case where we're on a non-required
  229. // relationship with empty data. TODO???
  230. '#default_value' => $default_value,
  231. );
  232. }
  233. /**
  234. * Helper to get the value out of the form element.
  235. */
  236. function get_element_value($element, $form_state) {
  237. // The element's '#parents' property gets us nearly all the way there.
  238. $parents = $element['#parents'];
  239. $parents[] = $this->options['property'];
  240. $value = drupal_array_get_nested_value($form_state['values'], $parents);
  241. return $value;
  242. }
  243. /**
  244. * Handle the form validation for this field's form element.
  245. */
  246. function edit_form_validate($entity_type, $entity, &$element, &$form_state) {
  247. // Wrappers don't have a way of testing the waters to validate, but we can
  248. // attempt to set the property and catch an exception.
  249. try {
  250. // Get the value out of the form state.
  251. $value = $this->get_element_value($element, $form_state);
  252. if ($this->options['reverse_boolean']) {
  253. $value = !$value;
  254. }
  255. // Set it on the wrapper, and stand back!
  256. $wrapper = entity_metadata_wrapper($entity_type, $entity);
  257. $wrapper->{$this->options['property']}->set($value);
  258. }
  259. catch (EntityMetadataWrapperException $e) {
  260. // TODO: the exception message from Entity API is not that end-user-friendly.
  261. form_error($element[$this->options['property']], $e->getMessage());
  262. }
  263. }
  264. /**
  265. * Handle the form submission for this field's form element.
  266. */
  267. function edit_form_submit($entity_type, $entity, &$element, &$form_state) {
  268. // Get the value out of the form state.
  269. $value = $this->get_element_value($element, $form_state);
  270. if ($this->options['reverse_boolean']) {
  271. $value = !$value;
  272. }
  273. // We can set this on the wrapper with inpunity, as the validate step
  274. // already caught any exception this might throw.
  275. $wrapper = entity_metadata_wrapper($entity_type, $entity);
  276. $wrapper->{$this->options['property']}->set($value);
  277. }
  278. }
Error | ELMSLN API

Error

×

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/elmsln_community/api.elmsln.org/includes/common.inc:2791) in drupal_send_headers() (line 1499 of /var/www/html/elmsln_community/api.elmsln.org/includes/bootstrap.inc).
  • Error: Call to undefined function apc_delete() in DrupalAPCCache->clear() (line 289 of /var/www/html/elmsln_community/api.elmsln.org/sites/all/modules/apc/drupal_apc_cache.inc).
The website encountered an unexpected error. Please try again later.