entity_field_value.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. <?php
  2. /**
  3. * @file
  4. * Plugin to provide access control based upon entity bundle.
  5. */
  6. $plugin = array(
  7. 'title' => t("(Custom) Entity: Field Value"),
  8. 'description' => t('Control access by entity field value.'),
  9. 'callback' => 'ctools_entity_field_value_ctools_access_check',
  10. 'default' => array('type' => array()),
  11. 'settings form' => 'ctools_entity_field_value_ctools_access_settings',
  12. 'settings form submit' => 'ctools_entity_field_value_ctools_access_settings_submit',
  13. 'summary' => 'ctools_entity_field_value_ctools_access_summary',
  14. 'get child' => 'ctools_entity_field_value_ctools_access_get_child',
  15. 'get children' => 'ctools_entity_field_value_ctools_access_get_children',
  16. );
  17. function ctools_entity_field_value_ctools_access_get_child($plugin, $parent, $child) {
  18. $plugins = &drupal_static(__FUNCTION__, array());
  19. if (empty($plugins[$parent . ':' . $child])) {
  20. list($entity_type, $bundle_type, $field_name) = explode(':', $child);
  21. $plugins[$parent . ':' . $child] = _ctools_entity_field_value_ctools_access_get_child($plugin, $parent, $entity_type, $bundle_type, $field_name);
  22. }
  23. return $plugins[$parent . ':' . $child];
  24. }
  25. function ctools_entity_field_value_ctools_access_get_children($plugin, $parent) {
  26. $plugins = &drupal_static(__FUNCTION__, array());
  27. if (!empty($plugins)) {
  28. return $plugins;
  29. }
  30. $entities = entity_get_info();
  31. foreach ($entities as $entity_type => $entity) {
  32. foreach ($entity['bundles'] as $bundle_type => $bundle) {
  33. foreach (field_info_instances($entity_type, $bundle_type) as $field_name => $field) {
  34. if (!isset($plugins[$parent . ':' . $entity_type . ':' . $bundle_type . ':' . $field_name])) {
  35. $plugin = _ctools_entity_field_value_ctools_access_get_child($plugin, $parent, $entity_type, $bundle_type, $field_name, $entity, $bundle, $field);
  36. $plugins[$parent . ':' . $entity_type . ':' . $bundle_type . ':' . $field_name] = $plugin;
  37. }
  38. }
  39. }
  40. }
  41. return $plugins;
  42. }
  43. function _ctools_entity_field_value_ctools_access_get_child($plugin, $parent, $entity_type, $bundle_type, $field_name, $entity = NULL, $bundle = NULL, $field = NULL) {
  44. // Check that the entity, bundle and field arrays have a value.
  45. // If not, load theme using machine names.
  46. if (empty($entity)) {
  47. $entity = entity_get_info($entity_type);
  48. }
  49. if (empty($bundle)) {
  50. $bundle = $entity['bundles'][$bundle_type];
  51. }
  52. if (empty($field)) {
  53. $field_instances = field_info_instances($entity_type, $bundle_type);
  54. $field = $field_instances[$field_name];
  55. }
  56. $plugin['title'] = t('@entity @type: @field Field', array('@entity' => $entity['label'], '@type' => $bundle_type, '@field' => $field['label']));
  57. $plugin['keyword'] = $entity_type;
  58. $plugin['description'] = t('Control access by @entity entity bundle.', array('@entity' => $entity_type));
  59. $plugin['name'] = $parent . ':' . $entity_type . ':' . $bundle_type . ':' . $field_name;
  60. $plugin['required context'] = new ctools_context_required(t(ucfirst($entity_type)), $entity_type, array(
  61. 'type' => $bundle_type,
  62. ));
  63. return $plugin;
  64. }
  65. /**
  66. * Settings form for the 'by entity_bundle' access plugin.
  67. */
  68. function ctools_entity_field_value_ctools_access_settings($form, &$form_state, $conf) {
  69. $plugin = $form_state['plugin'];
  70. list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
  71. $entity_info = entity_get_info($entity_type);
  72. $instances = field_info_instances($entity_type, $bundle_type);
  73. $instance = $instances[$field_name];
  74. $field = field_info_field_by_id($instance['field_id']);
  75. foreach ($field['columns'] as $column => $attributes) {
  76. $columns[$column] = _field_sql_storage_columnname($field_name, $column);
  77. }
  78. ctools_include('fields');
  79. $entity = (object) array(
  80. $entity_info['entity keys']['bundle'] => $bundle_type,
  81. );
  82. foreach ($columns as $column => $sql_column) {
  83. if (isset($conf[$sql_column])) {
  84. if (is_array($conf[$sql_column])) {
  85. foreach ($conf[$sql_column] as $delta => $conf_value) {
  86. if (is_numeric($delta)) {
  87. if (is_array($conf_value)) {
  88. $entity->{$field_name}[LANGUAGE_NONE][$delta][$column] = $conf_value[$column];
  89. }
  90. else {
  91. $entity->{$field_name}[LANGUAGE_NONE][$delta][$column] = $conf_value;
  92. }
  93. }
  94. }
  95. }
  96. else {
  97. $entity->{$field_name}[LANGUAGE_NONE][0][$column] = $conf[$sql_column];
  98. }
  99. }
  100. }
  101. $form['#parents'] = array('settings');
  102. $langcode = field_valid_language(NULL);
  103. $form['settings'] += (array) ctools_field_invoke_field($instance, 'form', $entity_type, $entity, $form, $form_state, array('default' => TRUE, 'language' => $langcode));
  104. // Weight is really not important once this is populated and will only interfere with the form layout.
  105. foreach (element_children($form['settings']) as $element) {
  106. unset($form['settings'][$element]['#weight']);
  107. }
  108. return $form;
  109. }
  110. function ctools_entity_field_value_ctools_access_settings_submit($form, &$form_state) {
  111. $plugin = $form_state['plugin'];
  112. list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
  113. $langcode = field_valid_language(NULL);
  114. $langcode = isset($form_state['input']['settings'][$field_name][$langcode]) ? $langcode : LANGUAGE_NONE;
  115. $instances = field_info_instances($entity_type, $bundle_type);
  116. $instance = $instances[$field_name];
  117. $field = field_info_field_by_id($instance['field_id']);
  118. foreach ($field['columns'] as $column => $attributes) {
  119. $columns[$column] = _field_sql_storage_columnname($field_name, $column);
  120. }
  121. $items = _ctools_entity_field_value_get_proper_form_items($field, $form_state['values']['settings'][$field_name][$langcode], array_keys($columns));
  122. foreach ($columns as $column => $sql_column) {
  123. $column_items = _ctools_entity_field_value_filter_items_by_column($items, $column);
  124. $form_state['values']['settings'][$sql_column] = $column_items;
  125. }
  126. $form_state['values']['settings'][$field_name][$langcode] = $items;
  127. }
  128. function _ctools_entity_field_value_get_proper_form_items($field, $form_items, $columns) {
  129. $items = array();
  130. // Single value item.
  131. if (!is_array($form_items)) {
  132. foreach ($columns as $column) {
  133. $items[0][$column] = $form_items;
  134. }
  135. return $items;
  136. }
  137. foreach ($form_items as $delta => $value) {
  138. $item = array();
  139. if (is_numeric($delta)) { // Array of field values.
  140. if (!is_array($value)) { // Single value in array.
  141. foreach ($columns as $column) {
  142. $item[$column] = $value;
  143. }
  144. }
  145. else { // Value has colums.
  146. foreach ($columns as $column) {
  147. $item[$column] = isset($value[$column]) ? $value[$column] : '';
  148. }
  149. }
  150. }
  151. $items[] = $item;
  152. }
  153. // Check if $form_items is an array of columns.
  154. $item = array();
  155. $has_columns = FALSE;
  156. foreach ($columns as $column) {
  157. if (isset($form_items[$column])) {
  158. $has_columns = TRUE;
  159. $item[$column] = $form_items[$column];
  160. }
  161. else {
  162. $item[$column] = '';
  163. }
  164. }
  165. if ($has_columns) {
  166. $items[] = $item;
  167. }
  168. // Remove empty values.
  169. $items = _field_filter_items($field, $items);
  170. return $items;
  171. }
  172. function _ctools_entity_field_value_filter_items_by_column($items, $column) {
  173. $column_items = array();
  174. foreach ($items as $delta => $values) {
  175. $column_items[$delta] = isset($values[$column]) ? $values[$column] : '';
  176. }
  177. return $column_items;
  178. }
  179. /**
  180. * Check for access.
  181. */
  182. function ctools_entity_field_value_ctools_access_check($conf, $context, $plugin) {
  183. if ((!is_object($context)) || (empty($context->data))) {
  184. // If the context doesn't exist -- for example, a newly added entity
  185. // reference is used as a pane visibility criteria -- we deny access.
  186. return FALSE;
  187. }
  188. list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
  189. if ($field_items = field_get_items($entity_type, $context->data, $field_name)) {
  190. $langcode = field_language($entity_type, $context->data, $field_name);
  191. // Get field storage columns.
  192. $instance = field_info_instance($entity_type, $field_name, $bundle_type);
  193. $field = field_info_field_by_id($instance['field_id']);
  194. $columns = array();
  195. foreach ($field['columns'] as $column => $attributes) {
  196. $columns[$column] = _field_sql_storage_columnname($field_name, $column);
  197. }
  198. if (isset($conf[$field_name])) {
  199. // We have settings for this field.
  200. $conf_value_array = _ctools_entity_field_value_ctools_access_get_conf_field_values($conf[$field_name], $langcode);
  201. if (empty($conf_value_array)) {
  202. return FALSE;
  203. }
  204. // Check field value.
  205. foreach ($field_items as $field_value) {
  206. // Iterate through config values.
  207. foreach ($conf_value_array as $conf_value) {
  208. $match = FALSE;
  209. foreach ($field_value as $field_column => $value) {
  210. // Check access only for stored in config column values.
  211. if (isset($conf_value[$field_column])) {
  212. if ($value == $conf_value[$field_column]) {
  213. $match = TRUE;
  214. }
  215. else {
  216. $match = FALSE;
  217. break;
  218. }
  219. }
  220. }
  221. if ($match) {
  222. return TRUE;
  223. }
  224. }
  225. }
  226. return FALSE;
  227. }
  228. }
  229. return FALSE;
  230. }
  231. function _ctools_entity_field_value_ctools_access_get_conf_field_values($values, $langcode = LANGUAGE_NONE) {
  232. if (!is_array($values) || !isset($values[$langcode])) {
  233. return NULL;
  234. }
  235. $conf_values = array();
  236. foreach ($values[$langcode] as $delta => $value) {
  237. $conf_values[$delta] = $value;
  238. }
  239. return $conf_values;
  240. }
  241. /**
  242. * Provide a summary description based upon the checked entity_bundle.
  243. */
  244. function ctools_entity_field_value_ctools_access_summary($conf, $context, $plugin) {
  245. list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
  246. $instances = field_info_instances($entity_type, $bundle_type);
  247. $instance = $instances[$field_name];
  248. $field = field_info_field_by_id($instance['field_id']);
  249. $entity_info = entity_get_info($entity_type);
  250. $entity = (object)array(
  251. $entity_info['entity keys']['bundle'] => $bundle_type,
  252. );
  253. $keys = array();
  254. $value_keys = array();
  255. $keyed_elements = array();
  256. foreach ($field['columns'] as $column => $attributes) {
  257. $conf_key = _field_sql_storage_columnname($field_name, $column);
  258. $keyed_elements["@{$column}_value"] = array();
  259. if (isset($conf[$conf_key])) {
  260. if (is_array($conf[$conf_key])) {
  261. $i = 0;
  262. foreach ($conf[$conf_key] as $conf_value) {
  263. if (!is_array($conf_value)) {
  264. $entity->{$field_name}[LANGUAGE_NONE][$i][$column] = $conf_value;
  265. $keyed_elements["@{$column}_value"][$i] = array('#markup' => $conf_value);
  266. }
  267. elseif (isset($conf_value[$column])) {
  268. $entity->{$field_name}[LANGUAGE_NONE][$i][$column] = $conf_value[$column];
  269. $keyed_elements["@{$column}_value"][$i] = array('#markup' => $conf_value[$column]);
  270. }
  271. $i++;
  272. }
  273. }
  274. else {
  275. $entity->{$field_name}[LANGUAGE_NONE][0][$column] = $conf[$conf_key];
  276. $keyed_elements["@{$column}_value"][0] = array('#markup' => $conf[$conf_key]);
  277. }
  278. }
  279. $keys['@' . $column] = $column;
  280. $value_keys[] = "@{$column}_value";
  281. }
  282. $elements = array();
  283. $items = isset($entity->{$field_name}[LANGUAGE_NONE]) ? $entity->{$field_name}[LANGUAGE_NONE] : array();
  284. $view_mode = 'full';
  285. ctools_include('fields');
  286. $display = field_get_display($instance, $view_mode, $entity);
  287. if (!isset($display['module'])) {
  288. $display['module'] = $field['module'];
  289. }
  290. if (isset($display['module'])) {
  291. // Choose simple formatter for well known cases.
  292. switch ($display['module']) {
  293. case 'text':
  294. $display['type'] = 'text_default';
  295. break;
  296. case 'list':
  297. $display['type'] = 'list_default';
  298. if ($field['type'] == 'list_boolean') {
  299. $allowed_values = list_allowed_values($field, $instance, $entity_type, $entity);
  300. foreach ($items as $item) {
  301. if (isset($allowed_values[$item['value']])) {
  302. if ($allowed_values[$item['value']] == '') {
  303. $display['type'] = 'list_key';
  304. break;
  305. }
  306. }
  307. else {
  308. $display['type'] = 'list_key';
  309. }
  310. }
  311. }
  312. break;
  313. case 'taxonomy':
  314. $display['type'] = 'taxonomy_term_reference_plain';
  315. break;
  316. case 'entityreference':
  317. $display['type'] = 'entityreference_label';
  318. break;
  319. default:
  320. // Use field instance formatter setting.
  321. break;
  322. }
  323. $function = $display['module'] . '_field_formatter_view';
  324. if (function_exists($function)) {
  325. $entity_group = array(0 => $entity);
  326. $item_group = array(0 => $items);
  327. $instance_group = array(0 => $instance);
  328. field_default_prepare_view($entity_type, $entity_group, $field, $instance_group, LANGUAGE_NONE, $item_group, $display);
  329. $elements = $function($entity_type, $entity, $field, $instance, LANGUAGE_NONE, $item_group[0], $display);
  330. }
  331. }
  332. if (count($elements) > 0) {
  333. foreach ($field['columns'] as $column => $attributes) {
  334. if (count($field['columns']) == 1) {
  335. $keyed_elements["@{$column}_value"] = $elements;
  336. }
  337. }
  338. }
  339. $values = array();
  340. foreach ($value_keys as $key) {
  341. $output = array();
  342. $elements = $keyed_elements[$key];
  343. if (is_array($elements)) {
  344. foreach ($elements as $element_key => $element) {
  345. if (is_numeric($element_key)) {
  346. $value_str = strip_tags(drupal_render($element));
  347. if (strlen($value_str) > 0) {
  348. $output[] = $value_str;
  349. }
  350. }
  351. }
  352. }
  353. else {
  354. $value_str = strip_tags(drupal_render($elements));
  355. if (strlen($value_str) > 0) {
  356. $output[] = $value_str;
  357. }
  358. }
  359. $value = implode(', ', $output);
  360. if ($value !== '') {
  361. $values[$key] = implode(', ', $output);
  362. }
  363. }
  364. $string = '';
  365. $value_count = count($values);
  366. foreach ($keys as $key_name => $column) {
  367. if (isset($values[$key_name . '_value'])) {
  368. $string .= ($value_count > 1) ? " @{$column} = @{$column}_value" : "@{$column}_value";
  369. }
  370. }
  371. return t('@field is set to "!value"', array('@field' => $instance['label'], '!value' => format_string($string, array_merge($keys, $values))));
  372. }