From ec8ae7bde7549b73d584ad900a78a83558e24ce0 Mon Sep 17 00:00:00 2001
From: Dmytro Danylevskyi <dmytro@danylevskyi.com>
Date: Thu, 10 Jan 2013 20:30:11 +0200
Subject: [PATCH] Issue #1309332 by aaronbauman, danylevskyi: Field collection
 operational links in views.

---
 field_collection.info                         |    1 +
 field_collection.module                       |    6 ++
 views/field_collection.views.inc              |   12 ++++
 views/field_collection_handler_field_link.inc |   84 +++++++++++++++++++++++++
 4 files changed, 103 insertions(+)
 create mode 100644 views/field_collection_handler_field_link.inc

diff --git a/field_collection.info b/field_collection.info
index 494eb27..52a3f90 100644
--- a/field_collection.info
+++ b/field_collection.info
@@ -5,5 +5,6 @@ dependencies[] = entity
 files[] = field_collection.test
 files[] = field_collection.info.inc
 files[] = views/field_collection_handler_relationship.inc
+files[] = views/field_collection_handler_field_link.inc
 configure = admin/structure/field-collections
 package = Fields
diff --git a/field_collection.module b/field_collection.module
index bf6a005..eec6f57 100644
--- a/field_collection.module
+++ b/field_collection.module
@@ -54,6 +54,8 @@ function field_collection_entity_info() {
   // use field_read_fields() as field_info_fields() requires built entity info
   // to work.
   foreach (field_read_fields(array('type' => 'field_collection')) as $field_name => $field) {
+    $path = field_collection_field_get_path($field);
+    $count = count(explode('/', $path));
     $return['field_collection_item']['bundles'][$field_name] = array(
       'label' => t('Field collection @field', array('@field' => $field_name)),
       'admin' => array(
@@ -62,6 +64,10 @@ function field_collection_entity_info() {
         'bundle argument' => 3,
         'access arguments' => array('administer field collections'),
       ),
+      'crud' => array(
+        'edit' => array('path' => $path . '/%/edit', 'entity_id' => $count),
+        'delete' => array('path' => $path . '/%/delete', 'entity_id' => $count)
+      ),
     );
   }
 
diff --git a/views/field_collection.views.inc b/views/field_collection.views.inc
index a4e8a0d..c1df92d 100644
--- a/views/field_collection.views.inc
+++ b/views/field_collection.views.inc
@@ -49,5 +49,17 @@ function field_collection_field_views_data($field) {
     );
   }
 
+  foreach (array('edit', 'delete') as $op) {
+    $data['field_collection_item']['link_' . $op] = array(
+      'group' => t('Field collection item'),
+      'title' => t('!op link', array('!op' => drupal_ucfirst($op))),
+      'help' => t('Field collection item !op link.', array('!op' => $op)),
+      'field' => array(
+        'handler' => 'field_collection_handler_field_link',
+        'operation' => $op,
+      ),
+    );
+  }
+
   return $data;
 }
diff --git a/views/field_collection_handler_field_link.inc b/views/field_collection_handler_field_link.inc
new file mode 100644
index 0000000..40fc0fc
--- /dev/null
+++ b/views/field_collection_handler_field_link.inc
@@ -0,0 +1,84 @@
+<?php
+
+/**
+ * @file
+ * Definition of field_collection_handler_field_link.
+ */
+
+/**
+ * Field handler to present a edit/delete links.
+ *
+ * @ingroup views_field_handlers
+ */
+class field_collection_handler_field_link extends views_handler_field_entity {
+
+  /**
+   * Specifies the options this handler uses.
+   */
+  public function option_definition() {
+    $options = parent::option_definition();
+    $options['text'] = array('default' => '', 'translatable' => TRUE);
+    return $options;
+  }
+
+  /**
+   * Provide an options form for this handler.
+   */
+  public function options_form(&$form, &$form_state) {
+    $form['text'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Text to display'),
+      '#default_value' => $this->options['text'],
+    );
+    parent::options_form($form, $form_state);
+
+    // The path is set by render_link function so don't allow to set it.
+    $form['alter']['path'] = array('#access' => FALSE);
+    $form['alter']['external'] = array('#access' => FALSE);
+  }
+
+  /**
+   * Render the field.
+   *
+   * @param $values
+   *   The values retrieved from the database.
+   */
+  function render($values) {
+    static $fc_entity_info, $bundles;
+
+    if (empty($fc_entity_info)) {
+      $fc_entity_info = field_collection_entity_info();
+      $bundles = $fc_entity_info['field_collection_item']['bundles'];
+    }
+
+    $item_id = $values->item_id;
+    $fc_item = field_collection_item_load($item_id);
+    $field_info = $bundles[$fc_item->field_name];
+    $op = $this->definition['operation'];
+
+    if (empty($field_info['crud'][$op]['path'])) {
+      return;
+    }
+
+    $path = $field_info['crud'][$op]['path'];
+    if (!empty($field_info['crud'][$op]['entity_id'])) {
+      $position = $field_info['crud'][$op]['entity_id'];
+      $parts = explode('/', $path);
+      $parts[$position] = $item_id;
+      $path = implode('/', $parts);
+    }
+
+    // Ensure user has proper access rights
+    if (!field_collection_item_access($op, $fc_item)) {
+      return;
+    }
+
+    $this->options['alter']['make_link'] = TRUE;
+    $this->options['alter']['path'] = $path;
+    $this->options['alter']['query'] = drupal_get_destination();
+
+    $text = !empty($this->options['text']) ? $this->options['text'] : t('!op', array('!op' => $op));
+    return $text;
+  }
+
+}
-- 
1.7.9.5

