-
Notifications
You must be signed in to change notification settings - Fork 19
/
viewfield.module
136 lines (120 loc) · 3.71 KB
/
viewfield.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
use \Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* @file
* Defines a field type to display a view.
*/
/**
* Implements hook_theme().
*/
function viewfield_theme() {
return array(
'viewfield_formatter_default' => array(
'render element' => 'element',
),
);
}
/**
* Implements hook_preprocess_HOOK().
*/
function viewfield_preprocess_viewfield_formatter_default(&$variables) {
$element = $variables['element'];
$view_el = $element['#view']->preview($element['#view_display'], array($element['#view_arguments']));
$output = render ($view_el);
$variables['output'] = $output;
}
/**
* Implements hook_element_info().
*/
function viewfield_element_info() {
$types['viewfield'] = array(
'#pre_render' => array('viewfield_pre_render'),
'#theme' => 'viewfield_formatter_default',
'#post_render' => array('viewfield_post_render'),
);
return $types;
}
/**
* #pre_render callback for a viewfield field.
*
* @see viewfield_post_render()
*/
function viewfield_pre_render($element) {
$stack = &drupal_static('viewfield_stack', array());
// Abort rendering in case the view could not be loaded.
if (empty($element['#view'])) {
// @todo Output an error message?
$element['#printed'] = TRUE;
}
// Abort rendering in case of recursion.
elseif (isset($stack[$element['#entity_type']][$element['#entity_id']])) {
$element['#printed'] = TRUE;
}
// Otherwise, add the rendered entity to the stack to prevent recursion.
else {
$stack[$element['#entity_type']][$element['#entity_id']] = TRUE;
// Override the view's path to the current path. Otherwise, exposed
// views filters would submit to the front page.
$url = Url::fromRoute('<current>');
$current_path = $url->toString();
$element['#view']->override_path = $current_path;
// @todo Store views arguments serialized.
$element['#view_arguments'] = _viewfield_get_view_args($element['#view_arguments'], $element['#entity_type'], $element['#entity']);
}
return $element;
}
/**
* #post_render callback for a viewfield field.
*
* @see viewfield_pre_render()
*/
function viewfield_post_render($content, $element) {
$stack = &drupal_static('viewfield_stack', array());
unset($stack[$element['#entity_type']][$element['#entity_id']]);
return $content;
}
/**
* Perform argument replacement
*/
function _viewfield_get_view_args($vargs, $entity_type, $entity) {
$args = array();
if (!empty($vargs)) {
$pos = 0;
while ($pos < strlen($vargs)) {
$found = FALSE;
// If string starts with a quote, start after quote and get everything
// before next quote.
if (strpos($vargs, '"', $pos) === $pos) {
if (($quote = strpos($vargs, '"', ++$pos)) !== FALSE) {
// Skip pairs of quotes.
while (!(($ql = strspn($vargs, '"', $quote)) & 1)) {
$quote = strpos($vargs, '"', $quote + $ql);
}
$args[] = str_replace('""', '"', substr($vargs, $pos, $quote + $ql - $pos - 1));
$pos = $quote + $ql + 1;
$found = TRUE;
}
}
elseif (($comma = strpos($vargs, ',', $pos)) !== FALSE) {
// Otherwise, get everything before next comma.
$args[] = substr($vargs, $pos, $comma - $pos);
// Skip to after comma and repeat
$pos = $comma + 1;
$found = TRUE;
}
if (!$found) {
$args[] = substr($vargs, $pos);
$pos = strlen($vargs);
}
}
list($entity_id) = $entity->id();
$entity = entity_load($entity_type, $entity_id);
$token_data = array($entity_type => $entity);
$token = Drupal::token();
foreach ($args as $key => $value) {
$args[$key] = $token->replace($value, $token_data);
}
}
return $args;
}