editableviews_plugin_style_row_edit_table.inc

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

Classes

Namesort descending Description
editableviews_plugin_style_row_edit_table Plugin class for the Editable Table style.
editableviews_style_helper Helper class for the style plugin.

File

sites/all/modules/ulmus/editableviews/editableviews_plugin_style_row_edit_table.inc
View source
  1. <?php
  2. /**
  3. * Plugin class for the Editable Table style.
  4. */
  5. class editableviews_plugin_style_row_edit_table extends views_plugin_style_table {
  6. /**
  7. * Initialize a style plugin.
  8. */
  9. function init(&$view, &$display, $options = NULL) {
  10. parent::init($view, $display, $options);
  11. // Get the helper object. This abstracts out a number of things we do here,
  12. // in order that other style plugins can use them too.
  13. $this->helper = new editableviews_style_helper($this);
  14. }
  15. function option_definition() {
  16. $options = parent::option_definition();
  17. // Todo: this should technically be on the helper, but it's faffy as it
  18. // is apparently not always there, if Views code with the same
  19. // pattern is anything to go by!
  20. $options['relationship_creation_bundle'] = array('default' => array());
  21. $options['save_messages'] = array('default' => 'individual');
  22. return $options;
  23. }
  24. /**
  25. * The options form for the given style.
  26. */
  27. function options_form(&$form, &$form_state) {
  28. parent::options_form($form, $form_state);
  29. // Everything we add to the options form is common and thus in the helper.
  30. $this->helper->options_form($form, $form_state);
  31. }
  32. function validate() {
  33. $errors = parent::validate();
  34. $relationship_handlers = $this->display->handler->get_handlers('relationship');
  35. $field_handlers_grouped = $this->helper->get_editable_field_handlers_grouped();
  36. //dsm($field_handlers_grouped);
  37. foreach ($relationship_handlers as $relationship_id => $relationship_handler) {
  38. // We don't care about required relationships.
  39. if ($relationship_handler->options['required']) {
  40. continue;
  41. }
  42. //dsm($relationship_handler);
  43. // We don't care if there are no editable fields on the relationship.
  44. if (empty($field_handlers_grouped[$relationship_id])) {
  45. continue;
  46. }
  47. if (!isset($relationship_handler->definition['editableviews_direction'])) {
  48. $errors[] = t("The relationship '@relationship' is not compatible with editable fields that may cause creation of entities for empty data. The relationship should be set to be 'required'.", array(
  49. '@relationship' => $relationship_handler->options['label']
  50. ));
  51. }
  52. if (!isset($this->options['relationship_creation_bundle'][$relationship_id])) {
  53. $errors[] = t("Display @display is set to use a editable fields and the '@relationship' relationship is not set to be required: the bundle of entities to create on this relationship must be set in the Editable Table options.", array(
  54. '@display' => $this->display->display_title,
  55. '@relationship' => $relationship_handler->options['label']
  56. ));
  57. }
  58. }
  59. return $errors;
  60. }
  61. /**
  62. * Add anything to the query that we might need to.
  63. */
  64. function query() {
  65. parent::query();
  66. // Everything we do to the query is common and thus in the helper.
  67. $this->helper->query();
  68. }
  69. /**
  70. * Helper to get the handlers for editable fields.
  71. *
  72. * @return
  73. * An array of field handlers, in the same format as get_handlers() returns,
  74. * but containing only those handlers which are for editable fields.
  75. */
  76. function get_edit_field_handlers() {
  77. $handlers = $this->display->handler->get_handlers('field');
  78. $edit_field_handlers = array();
  79. foreach ($handlers as $key => $handler) {
  80. if (!empty($handler->editable)) {
  81. $edit_field_handlers[$key] = $handler;
  82. }
  83. }
  84. return $edit_field_handlers;
  85. }
  86. /**
  87. * Render all of the fields for a given style and store them on the object.
  88. *
  89. * @param $result
  90. * The result array from $view->result
  91. */
  92. function render_fields($result) {
  93. if (!$this->uses_fields()) {
  94. return;
  95. }
  96. if (!isset($this->rendered_fields)) {
  97. parent::render_fields($result);
  98. $this->insert_form_elements($result);
  99. }
  100. return $this->rendered_fields;
  101. }
  102. /**
  103. * Insert the field form elements into the rendered View fields.
  104. *
  105. * @param $result
  106. * The result array from $view->result
  107. */
  108. function insert_form_elements($result) {
  109. //dsm($result, '$result');
  110. // Get our edit field handlers.
  111. $edit_field_handlers = $this->get_edit_field_handlers();
  112. if (empty($edit_field_handlers)) {
  113. // There's nothing to do!
  114. return;
  115. }
  116. //dsm($edit_field_handlers, '$edit_field_handlers');
  117. $relationship_handlers = $this->display->handler->get_handlers('relationship');
  118. //dsm($this->view->relationship);
  119. // Build an array of the field names to make editable.
  120. // The keys are the id keys of the Views handlers.
  121. // For non-field-API fields, the definition must include this property.
  122. $edit_fields = array();
  123. // Create the keys in this so they exist even for relationships with no
  124. // editable fields.
  125. $edit_field_handlers_grouped = array_fill_keys(array_keys($relationship_handlers), array());
  126. $edit_field_handlers_grouped[$this->view->base_table] = array();
  127. foreach ($edit_field_handlers as $handler_id => $handler) {
  128. //dsm($handler, "field handler $handler_id");
  129. $edit_fields[$handler_id] = $handler->field_name();
  130. // Build an array of handlers grouped by relationship ID.
  131. // This is for the form builder to only work on the handlers that are
  132. // relevant to the entity's relationship.
  133. $field_handler_relationship_id = $handler->options['relationship'];
  134. if ($field_handler_relationship_id == 'none') {
  135. $field_handler_relationship_id = $this->view->base_table;
  136. }
  137. $edit_field_handlers_grouped[$field_handler_relationship_id][$handler_id] = $handler;
  138. }
  139. // Build an array of entities that we should be working with. We load the
  140. // that are implicit in the view result, creating new ones if there are any
  141. // gaps.
  142. // The entity ID fields have been added to the view result by query().
  143. $result_entities = array();
  144. foreach ($result as $index => $result_row) {
  145. foreach ($this->helper->relationship_entity_fields as $relationship_id => $relationship_entity_data) {
  146. $entity_type = $relationship_entity_data['entity_type'];
  147. // Get the entity ID out of the result.
  148. $entity_id = $result_row->{$relationship_entity_data['id_field_alias']};
  149. // Get the entities we work with, and build an array of them.
  150. if (isset($entity_id)) {
  151. $entity = entity_load_single($entity_type, $entity_id);
  152. $result_entities[$entity_type][$entity_id] = $entity;
  153. }
  154. else {
  155. if (count($edit_field_handlers_grouped[$relationship_id])) {
  156. // If there is no entity, and the relationship has editable fields,
  157. // we create one (i.e., make the object without saving it). We give
  158. // this a fake entity id, composed of the relationship handler id
  159. // and the index so it's unique.
  160. $entity_id = $relationship_id . ':' . $index;
  161. $entity = $this->helper->entity_create($relationship_id);
  162. $result_entities[$entity_type][$entity_id] = $entity;
  163. }
  164. }
  165. // Build a lookup from entity type and entity to the result row index
  166. // and relationship. It helps to conceptualize this as giving us
  167. // coordinates for where the entity has fields in the view table:
  168. // the index gives the row, and the relationship gives the column(s).
  169. // This is for the form builder to be able to get to the right result
  170. // row and to know which handlers to get form elements from.
  171. $result_indexes[$entity_type][$entity_id] = array($relationship_id, $index);
  172. // Build a lookup array of the same coordinates, but towards the entity:
  173. // keys are relationship ID then index, values are entity type and entity.
  174. $result_indexes_reverse[$relationship_id][$index] = array($entity_type, $entity_id);
  175. }
  176. }
  177. //dsm($result_entities, '$result_entities');
  178. //dsm($result_indexes_reverse, '$result_indexes_reverse');
  179. // Make a combined array of coordinate lookups, both forward and reverse.
  180. // TODO: eventually replace everything to work with this arrays instead of
  181. // the two separate ones.
  182. $results_coordinates = array(
  183. 'entities_to_results' => $result_indexes,
  184. 'results_to_entities' => $result_indexes_reverse,
  185. );
  186. // Build up some lookups pertaining to field handlers, and set the editable
  187. // fields on new entities.
  188. $result_entity_ids = array();
  189. foreach ($result as $index => $result_row) {
  190. foreach ($edit_field_handlers as $handler_id => $handler) {
  191. // Get the entity type and entity for this field handler from the
  192. // relationship lookup.
  193. $field_handler_relationship_id = $handler->options['relationship'];
  194. if ($field_handler_relationship_id == 'none') {
  195. $field_handler_relationship_id = $this->view->base_table;
  196. }
  197. // Add the field_name for this field handler to the list on the entity
  198. // which keeps track of them.
  199. list($entity_type, $entity_id) = $result_indexes_reverse[$field_handler_relationship_id][$index];
  200. if (!is_numeric($entity_id)) {
  201. $entity = $result_entities[$entity_type][$entity_id];
  202. $entity->editableviews_exposed_fields[] = $handler->field_name();
  203. }
  204. // Build a lookup array from index and field handler to the entity type
  205. // and entity. This is to get to the right form element to include when
  206. // we finally render our fields.
  207. // Just get the entity coordinates from the relationship lookup.
  208. $result_entity_ids[$index][$handler_id] = $result_indexes_reverse[$field_handler_relationship_id][$index];
  209. }
  210. }
  211. //dsm($result_entity_ids, '$result_entity_ids');
  212. // Now we have built up all our entities, go over them again and add
  213. // the connecting properties to any new ones.
  214. // In other words:
  215. // - On a forward relationship, the existing entity on the relationship's
  216. // base needs to point to the new entity that is (potentially) about to
  217. // be saved.
  218. // - On a reverse relationship, the new entity that is about to be created
  219. // needs to point back to the existing entity on the relationship's base.
  220. // Here we figure out the id we need to point to, and the property to point
  221. // to it in.
  222. $this->helper->connect_new_entities($result_entities, $results_coordinates, $edit_field_handlers_grouped);
  223. //dsm($result_entities, '$result_entities post connect');
  224. // Load up the form render array.
  225. $this->get_form($result_entities, $results_coordinates, $edit_field_handlers_grouped);
  226. // Doctor the view's rendered fields to add in the form elements for
  227. // the appropriate entity and field.
  228. foreach ($this->rendered_fields as $index => $rendered_fields) {
  229. foreach ($edit_fields as $handler_id => $field_name) {
  230. // Get the already rendered field.
  231. $rendered_field = $this->rendered_fields[$index][$handler_id];
  232. // Get the entity type and entity that this field handler shows from our
  233. // lookup array, so that we can pick out the form element to render
  234. // for it.
  235. list($entity_type, $entity_id) = $result_entity_ids[$index][$handler_id];
  236. // TODO! theme this!!
  237. $this->rendered_fields[$index][$handler_id] = '<div class="views-row-edit-static">' . $rendered_field . '</div>';
  238. $this->rendered_fields[$index][$handler_id] .= '<div class="views-row-edit-edit">' . drupal_render($this->form[$entity_type][$entity_id][$field_name]) . '</div>';
  239. }
  240. }
  241. }
  242. /**
  243. * Helper method. Retrieves the form render array.
  244. *
  245. * @param $entities
  246. * An array of entities to get the form for, keyed first by entity type and
  247. * then by entity id.
  248. * @param $results_coordinates
  249. * An array containing coordinates lookups for getting entity type and entity
  250. * from row id and relationship, and the same the other way round. Contains:
  251. * - 'entities_to_results': A nested array keyed by entity type then entity
  252. * id. The final values are flat arrays of the relationship id and result
  253. * index.
  254. * - 'results_to_entities': A nested array keyed by relationship id then
  255. * result index. The final values are flat arrays of the entity type and
  256. * entity id.
  257. * @param $edit_field_handlers
  258. * An array of field handlers to provide form elements for, grouped by
  259. * their relationship.
  260. * See editableviews_entity_form() for details.
  261. */
  262. function get_form($entities, $results_coordinates, $edit_field_handlers) {
  263. // Create a dynamic form ID using the base name (for quick recognition
  264. // in hook_forms()) and the view name. This allows hook_form_alter() to
  265. // target forms for specific views. We don't add the display name as there's
  266. // no clean way to mark the separation between that and the view name.
  267. // @see editableviews_forms()
  268. $form_id = 'editableviews_entity_form' . '_' . $this->view->name;
  269. // We store this rather than return it, as it's used in different places.
  270. $this->form = drupal_get_form($form_id, $entities, $results_coordinates, $edit_field_handlers, $this->view);
  271. }
  272. /**
  273. * Render the display in this style.
  274. */
  275. function render() {
  276. // Get the rendered view output.
  277. $view_render = parent::render();
  278. // Stick it INSIDE the form as plain markup, so that the HTML FORM element
  279. // goes around everything.
  280. $this->form['view'] = array(
  281. '#markup' => $view_render,
  282. );
  283. return $this->form;
  284. }
  285. }
  286. /**
  287. * Helper class for the style plugin.
  288. *
  289. * This abstracts out a number of things the style plugin needs to do, in order
  290. * that other style plugins can use them too.
  291. */
  292. class editableviews_style_helper {
  293. /**
  294. * A lookup from relationships to the data needed to load their entities.
  295. *
  296. * This is an array of the relationships on the view which correspond to
  297. * entity base tables, including the base table (as a pseudo-relationship).
  298. * The key is the relationship id (in the case of the base table, this is just
  299. * the table name itself). Each value is an array containing:
  300. * - 'entity_type': The entity type this relationship brings to the view.
  301. * - 'id_field_alias': The field alias of the field on the view in which to
  302. * find the entity's ID. This field is ensured by our query().
  303. */
  304. public $relationship_entity_fields = array();
  305. function __construct(&$plugin) {
  306. $this->plugin = &$plugin;
  307. }
  308. /**
  309. * Provide common options for editable style plugins.
  310. */
  311. function options_form(&$form, &$form_state) {
  312. // Add a fieldset to allow setting of a creation bundle for all the
  313. // relationships that are non-required. This is because a non-required
  314. // relationship may cause empty data in the result, and if this has editable
  315. // fields, then entering data into those field's form elements causes the
  316. // creation of a new entity. Which we need a bundle for.
  317. $relationship_handlers = $this->plugin->display->handler->get_handlers('relationship');
  318. // Get our edit field handlers.
  319. $edit_field_handlers = $this->plugin->get_edit_field_handlers();
  320. // Collect the relationships these are on.
  321. $edit_relationship_handlers = array();
  322. foreach ($edit_field_handlers as $field_handler_id => $field_handler) {
  323. // Because we're not in the process of querying, the relationship is only
  324. // set in the options.
  325. $relationship_id = $field_handler->options['relationship'];
  326. // Skip edit field handlers that are on the base.
  327. if ($relationship_id == 'none') {
  328. continue;
  329. }
  330. // Argh, do we need to contend with the alias of the relationship here??
  331. // Skip a relationship that is required: these will never provide an empty
  332. // row, and so never require entity creation.
  333. if ($relationship_handlers[$relationship_id]->options['required']) {
  334. continue;
  335. }
  336. // If we're still here, this is a relationship we need to consider.
  337. $edit_relationship_handlers[$relationship_id] = $relationship_handlers[$relationship_id];
  338. }
  339. // Only show this fieldset if there are relationships to consider.
  340. if (count($edit_relationship_handlers)) {
  341. $form['relationship_creation_bundle'] = array(
  342. '#type' => 'fieldset',
  343. '#title' => t('Relationship entity creation bundles'),
  344. '#description' => t('A relationship which is set to not required may produce empty form elements, which thus require the creation of a new entity if populated with data. The bundle for these new entities must be specified here.'),
  345. '#weight' => -1,
  346. );
  347. foreach ($edit_relationship_handlers as $relationship_id => $relationship_handler) {
  348. // The 'base' of a relationship is the table it brings.
  349. $table = $relationship_handler->definition['base'];
  350. // Get the entity type from the table.
  351. $table_data = views_fetch_data($table);
  352. $entity_type = $table_data['table']['entity type'];
  353. $entity_info = entity_get_info($entity_type);
  354. $options = array();
  355. foreach ($entity_info['bundles'] as $bundle => $bundle_info) {
  356. $options[$bundle] = $bundle_info['label'];
  357. }
  358. $form['relationship_creation_bundle'][$relationship_id] = array(
  359. '#type' => 'select',
  360. '#title' => t('Bundle for new entities created on %label', array(
  361. '%label' => $relationship_handler->options['label'],
  362. )),
  363. '#description' => t('Select the %entity entity bundle for entities created on this relationship.', array(
  364. '%entity' => $entity_info['label'],
  365. )),
  366. '#options' => $options,
  367. '#required' => TRUE,
  368. );
  369. // We have to check the default value, as the key in the array is variable
  370. // because it's the relationship handler ID. That means that Views won't
  371. // have it set in option_definition().
  372. if (isset($this->plugin->options['relationship_creation_bundle'][$relationship_id])) {
  373. $form['relationship_creation_bundle'][$relationship_id]['#default_value'] = $this->plugin->options['relationship_creation_bundle'][$relationship_id];
  374. }
  375. }
  376. }
  377. $form['save_messages'] = array(
  378. '#type' => 'select',
  379. '#title' => t("Save messages"),
  380. '#description' => t('The messages to show the user when the view form is saved.'),
  381. '#options' => array(
  382. 'none' => t('Show no messages'),
  383. 'summary' => t('Show a single message summarizing the changes'),
  384. 'individual' => t('Show a message for each saved entity'),
  385. ),
  386. '#default_value' => $this->plugin->options['save_messages'],
  387. );
  388. }
  389. /**
  390. * Add anything to the query that we might need to.
  391. *
  392. * For the base and each relationship that brings an entity table, add the
  393. * entity ID field for that entity. This ensures that we can load the entities
  394. * when we need to get form elements for them.
  395. *
  396. * We do this for all relationships, not just those which have editable fields
  397. * on them, because we may need access to entities that editable field
  398. * entities need to point to when creating entities.
  399. */
  400. function query() {
  401. // For each relationship that provides an entity table (including the base
  402. // pseudo-relationship), add the field for that entity's ID.
  403. $base_table = $this->plugin->view->base_table;
  404. // Do the View base first.
  405. $table_data = views_fetch_data($this->plugin->view->base_table);
  406. if (isset($table_data['table']['entity type'])) {
  407. // We don't need to ensure this field is on the query: the id field on
  408. // the base table always is.
  409. $this->relationship_entity_fields[$base_table] = array(
  410. 'entity_type' => $table_data['table']['entity type'],
  411. // We don't need to find an alias for a field on the base.
  412. 'id_field_alias' => $table_data['table']['base']['field'],
  413. );
  414. }
  415. // Now the relationships.
  416. $relationship_handlers = $this->plugin->display->handler->get_handlers('relationship');
  417. foreach ($relationship_handlers as $relationship_id => $relationship_handler) {
  418. //dsm($relationship_handler, $relationship_id);
  419. // The 'base' of a relationship is the table it brings.
  420. $table = $relationship_handler->definition['base'];
  421. // Get the entity type from the table.
  422. $table_data = views_fetch_data($table);
  423. if (!isset($table_data['table']['entity type'])) {
  424. // Not an entity base table relationship: skip it.
  425. continue;
  426. }
  427. // Get the entity type and the views field that corresponds to the entity
  428. // id from the table definition.
  429. //dsm($table_data['table'], 'table data');
  430. $entity_type = $table_data['table']['entity type'];
  431. $entity_id_field = $table_data['table']['base']['field'];
  432. // Force the 're
  433. if ($relationship_handler->options['relationship'] == 'none') {
  434. $relationship_relationship = $base_table;
  435. }
  436. else {
  437. $relationship_relationship = $relationship_handler->options['relationship'];
  438. }
  439. //dsm($relationship_relationship, '$relationship_relationship');
  440. // We want the alias for the table the relationship brings, not the table
  441. // it sits on.
  442. $table_alias = $relationship_handler->alias;
  443. //dsm("$relationship_id brings $entity_type, $entity_id_field.\ntable alias is $table_alias");
  444. $entity_id_field_alias = $this->plugin->view->query->add_field($table_alias, $entity_id_field);
  445. $this->relationship_entity_fields[$relationship_id] = array(
  446. 'entity_type' => $entity_type,
  447. 'id_field_alias' => $entity_id_field_alias,
  448. );
  449. }
  450. //dsm($this->relationship_entity_fields);
  451. }
  452. /**
  453. * Returns a new (unsaved) entity for the given relationship ID.
  454. *
  455. * This is needed when editable field handlers are on a non-required
  456. * relationship, and a particular result row has no data there. We create a
  457. * new entity for FieldAPI to work on, and potentially save it on submission
  458. * if the user enters data.
  459. *
  460. * @param $relationship_id
  461. * The id of the relationship that requires a new entity.
  462. *
  463. * @return
  464. * A new, unsaved entity. The entity type is implied by the handler, and
  465. * should be known by the caller. The bundle will be set on this, given by
  466. * the style plugin's options.
  467. */
  468. function entity_create($relationship_id) {
  469. $entity_type = $this->relationship_entity_fields[$relationship_id]['entity_type'];
  470. // This is complex. We know the entity type, but we need to be told
  471. // the bundle: that's one for the plugin settings.
  472. // Then when it's created, we need to know how to set the relationship
  473. // field.
  474. $entity_info = entity_get_info($entity_type);
  475. // Assume this exists, as it must do if the entity is fieldable, and
  476. // if your entity is not fieldable, what are you doing here? ;)
  477. $bundle_key = $entity_info['entity keys']['bundle'];
  478. $values = array(
  479. // The bundle of the new entity is set in the options for this
  480. // style plugin. This has to be set by the user, because there is
  481. // absolutely no other way to sniff this out!
  482. // TODO: cloud cuckoo land, but a form element field to specify
  483. // the bundle for each row would be nice!
  484. $bundle_key => $this->plugin->options['relationship_creation_bundle'][$relationship_id],
  485. );
  486. // Just a little bit of sugar to save this having to be done in a custom
  487. // form submit handler: for nodes and comments, set the uid property
  488. // to the current user. We would do this with anything that has a uid
  489. // property, but entity_get_property_info() calls it 'author' and it's just
  490. // starting to get faffy now.
  491. if ($entity_type == 'node' || $entity_type == 'comment') {
  492. $values['uid'] = $GLOBALS['user']->uid;
  493. }
  494. $entity = entity_create($entity_type, $values);
  495. // Add our own property to the entity, where we keep track of the properties
  496. // that are exposed as form elements in the view. This is how we will
  497. // determine whether or not to save it when the form is submitted.
  498. $entity->editableviews_exposed_fields = array();
  499. // Add our own property to specify whether this needs to be saved or not.
  500. // @see editableviews_entity_form_submit_build_values()
  501. $entity->editableviews_needs_save = FALSE;
  502. return $entity;
  503. }
  504. /**
  505. * Sets the properties so that new entities connect to existing ones.
  506. *
  507. * For a forward relationship, the existing entity must know it has to point
  508. * to the new entity once it has been saved.
  509. * For a reverse relationship, the new entity must have the right property set
  510. * (e.g. an entityreference field) so that it point back to the existing
  511. * entity.
  512. *
  513. * @param $result_entities
  514. * The array of result entities from the style plugin. Passed by reference
  515. * so the entities can be altered. (TODO: is this actually needed??)
  516. * @param $results_coordinates
  517. * The combined coordinates array, containing both the forward and reverse
  518. * lookups for entities and results.
  519. * @see editableviews_plugin_style_row_edit_table::get_form() for details.
  520. * @param $edit_field_handlers_grouped
  521. * The edit field handlers, grouped by relationship handler ID.
  522. */
  523. function connect_new_entities(&$result_entities, $results_coordinates, $edit_field_handlers_grouped) {
  524. $relationship_handlers = $this->plugin->display->handler->get_handlers('relationship');
  525. //dsm($edit_field_handlers_grouped);
  526. //dsm($result_entities);
  527. foreach (array_keys($result_entities) as $entity_type) {
  528. foreach ($result_entities[$entity_type] as $entity_id => $entity) {
  529. // New entities have a non-numeric fake id we just gave them.
  530. if (!is_numeric($entity_id)) {
  531. // Get the views coordinates for this entity.
  532. list($relationship_id, $index) = $results_coordinates['entities_to_results'][$entity_type][$entity_id];
  533. $relationship_handler = $relationship_handlers[$relationship_id];
  534. //dsm($relationship_handler);
  535. // Get the relationship that the relationship is on, so we can then
  536. // get the entity for that relationship.
  537. if (isset($relationship_handler->relationship)) {
  538. $relationship_relationship = $relationship_handler->relationship;
  539. }
  540. else {
  541. $relationship_relationship = $this->plugin->view->base_table;
  542. }
  543. // Only act if the new entity's relationship has editable fields:
  544. // otherwise it's just an empty bunch of table cells, and there's
  545. // nothing to connect to or from.
  546. if (count($edit_field_handlers_grouped[$relationship_relationship]) == 0) {
  547. continue;
  548. }
  549. if ($relationship_handler->definition['editableviews_direction'] == 'forward') {
  550. // Get the entity on our relationship's relationship -- same
  551. // as for reverse.
  552. // Get the entity out of the imaginary Views grid that is on the same
  553. // row as us, and in the $relationship_relationship relationship...
  554. list($referring_entity_type, $referring_entity_id) = $results_coordinates['results_to_entities'][$relationship_relationship][$index];
  555. $referring_entity = $result_entities[$referring_entity_type][$referring_entity_id];
  556. // Store this entity's details on the current, new entity, so that
  557. // when (and if!) we save it, we can go and make the referring
  558. // entity point to it.
  559. $entity->editableviews_future_reference = array(
  560. 'entity_type' => $referring_entity_type,
  561. 'entity_id' => $referring_entity_id,
  562. 'field_name' => $relationship_handler->definition['field_name'],
  563. );
  564. }
  565. else {
  566. // Would be nice to factor this out to a helper method, say
  567. // '$this->new_entity_set_reverse_connection()' but we'd need to
  568. // pass so many variables it's probably just as faffy.
  569. // Get the entity out of the imaginary Views grid that is on the same
  570. // row as us, and in the $relationship_relationship relationship...
  571. list($referred_entity_type, $referred_entity_id) = $results_coordinates['results_to_entities'][$relationship_relationship][$index];
  572. $referred_entity = $result_entities[$referred_entity_type][$referred_entity_id];
  573. // From here on, this is just reverse relationships!
  574. $wrapper = entity_metadata_wrapper($entity_type, $entity);
  575. // This is what we need to set on the new entity in a reverse relationship.
  576. $relationship_field_name = $relationship_handler->definition['field_name'];
  577. // Make the new entity point to the entity on its relationship's
  578. // relationship.
  579. $wrapper->{$relationship_field_name}->set($referred_entity_id);
  580. }
  581. }
  582. }
  583. }
  584. }
  585. /**
  586. * Get editable field handlers grouped by relationship id.
  587. */
  588. function get_editable_field_handlers_grouped() {
  589. $editable_field_handlers = $this->plugin->get_edit_field_handlers();
  590. $editable_field_handlers_grouped = array();
  591. foreach ($editable_field_handlers as $field_handler_id => $field_handler) {
  592. //dsm($field_handler, '$field_handler');
  593. $relationship_id = $field_handler->options['relationship'];
  594. if ($relationship_id == 'none') {
  595. // TODO: tidy up this WTF!
  596. $relationship_id = 'base';
  597. }
  598. $editable_field_handlers_grouped[$relationship_id][$field_handler_id] = $field_handler;
  599. }
  600. return $editable_field_handlers_grouped;
  601. }
  602. }
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.