entity_field_value.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  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. if (!is_array($form_items)) { // Single value item.
  131. foreach ($columns as $column) {
  132. $items[0][$column] = $form_items;
  133. }
  134. return $items;
  135. }
  136. foreach ($form_items as $delta => $value) {
  137. $item = array();
  138. if (is_numeric($delta)) { // Array of field values.
  139. if (!is_array($value)) { // Single value in array.
  140. foreach ($columns as $column) {
  141. $item[$column] = $value;
  142. }
  143. }
  144. else { // Value has colums.
  145. foreach ($columns as $column) {
  146. $item[$column] = isset($value[$column]) ? $value[$column] : '';
  147. }
  148. }
  149. }
  150. $items[] = $item;
  151. }
  152. // Check if $form_items is an array of columns.
  153. $item = array();
  154. $has_columns = FALSE;
  155. foreach ($columns as $column) {
  156. if (isset($form_items[$column])) {
  157. $has_columns = TRUE;
  158. $item[$column] = $form_items[$column];
  159. }
  160. else {
  161. $item[$column] = '';
  162. }
  163. }
  164. if ($has_columns) {
  165. $items[] = $item;
  166. }
  167. // Remove empty values.
  168. $items = _field_filter_items($field, $items);
  169. return $items;
  170. }
  171. function _ctools_entity_field_value_filter_items_by_column($items, $column) {
  172. $column_items = array();
  173. foreach ($items as $delta => $values) {
  174. $column_items[$delta] = isset($values[$column]) ? $values[$column] : '';
  175. }
  176. return $column_items;
  177. }
  178. /**
  179. * Check for access.
  180. */
  181. function ctools_entity_field_value_ctools_access_check($conf, $context, $plugin) {
  182. if ((!is_object($context)) || (empty($context->data))) {
  183. // If the context doesn't exist -- for example, a newly added entity
  184. // reference is used as a pane visibility criteria -- we deny access.
  185. return FALSE;
  186. }
  187. list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
  188. if ($field_items = field_get_items($entity_type, $context->data, $field_name)) {
  189. $langcode = field_language($entity_type, $context->data, $field_name);
  190. // Get field storage columns.
  191. $instance = field_info_instance($entity_type, $field_name, $bundle_type);
  192. $field = field_info_field_by_id($instance['field_id']);
  193. $columns = array();
  194. foreach ($field['columns'] as $column => $attributes) {
  195. $columns[$column] = _field_sql_storage_columnname($field_name, $column);
  196. }
  197. if (isset($conf[$field_name])) {
  198. // We have settings for this field.
  199. $conf_value_array = _ctools_entity_field_value_ctools_access_get_conf_field_values($conf[$field_name], $langcode);
  200. if (empty($conf_value_array)) {
  201. return FALSE;
  202. }
  203. // Check field value.
  204. foreach ($field_items as $field_value) {
  205. // Iterate through config values.
  206. foreach ($conf_value_array as $conf_value) {
  207. $match = FALSE;
  208. foreach ($field_value as $field_column => $value) {
  209. // Check access only for stored in config column values.
  210. if (isset($conf_value[$field_column])) {
  211. if ($value == $conf_value[$field_column]) {
  212. $match = TRUE;
  213. }
  214. else {
  215. $match = FALSE;
  216. break;
  217. }
  218. }
  219. }
  220. if ($match) {
  221. return TRUE;
  222. }
  223. }
  224. }
  225. return FALSE;
  226. }
  227. }
  228. return FALSE;
  229. }
  230. function _ctools_entity_field_value_ctools_access_get_conf_field_values($values, $langcode = LANGUAGE_NONE) {
  231. if (!is_array($values) || !isset($values[$langcode])) {
  232. return NULL;
  233. }
  234. $conf_values = array();
  235. foreach ($values[$langcode] as $delta => $value) {
  236. $conf_values[$delta] = $value;
  237. }
  238. return $conf_values;
  239. }
  240. /**
  241. * Provide a summary description based upon the checked entity_bundle.
  242. */
  243. function ctools_entity_field_value_ctools_access_summary($conf, $context, $plugin) {
  244. list($parent, $entity_type, $bundle_type, $field_name) = explode(':', $plugin['name']);
  245. $instances = field_info_instances($entity_type, $bundle_type);
  246. $instance = $instances[$field_name];
  247. $field = field_info_field_by_id($instance['field_id']);
  248. $entity_info = entity_get_info($entity_type);
  249. $entity = (object)array(
  250. $entity_info['entity keys']['bundle'] => $bundle_type,
  251. );
  252. $keys = array();
  253. $value_keys = array();
  254. $keyed_elements = array();
  255. foreach ($field['columns'] as $column => $attributes) {
  256. $conf_key = _field_sql_storage_columnname($field_name, $column);
  257. $keyed_elements["@{$column}_value"] = array();
  258. if (isset($conf[$conf_key])) {
  259. if (is_array($conf[$conf_key])) {
  260. $i = 0;
  261. foreach ($conf[$conf_key] as $conf_value) {
  262. if (!is_array($conf_value)) {
  263. $entity->{$field_name}[LANGUAGE_NONE][$i][$column] = $conf_value;
  264. $keyed_elements["@{$column}_value"][$i] = array('#markup' => $conf_value);
  265. }
  266. elseif (isset($conf_value[$column])) {
  267. $entity->{$field_name}[LANGUAGE_NONE][$i][$column] = $conf_value[$column];
  268. $keyed_elements["@{$column}_value"][$i] = array('#markup' => $conf_value[$column]);
  269. }
  270. $i++;
  271. }
  272. }
  273. else {
  274. $entity->{$field_name}[LANGUAGE_NONE][0][$column] = $conf[$conf_key];
  275. $keyed_elements["@{$column}_value"][0] = array('#markup' => $conf[$conf_key]);
  276. }
  277. }
  278. $keys['@' . $column] = $column;
  279. $value_keys[] = "@{$column}_value";
  280. }
  281. $elements = array();
  282. $items = isset($entity->{$field_name}[LANGUAGE_NONE]) ? $entity->{$field_name}[LANGUAGE_NONE] : array();
  283. $view_mode = 'full';
  284. ctools_include('fields');
  285. $display = field_get_display($instance, $view_mode, $entity);
  286. if (!isset($display['module'])) {
  287. $display['module'] = $field['module'];
  288. }
  289. if (isset($display['module'])) {
  290. // Choose simple formatter for well known cases.
  291. switch ($display['module']) {
  292. case 'text':
  293. $display['type'] = 'text_default';
  294. break;
  295. case 'list':
  296. $display['type'] = 'list_default';
  297. if ($field['type'] == 'list_boolean') {
  298. $allowed_values = list_allowed_values($field, $instance, $entity_type, $entity);
  299. foreach ($items as $item) {
  300. if (isset($allowed_values[$item['value']])) {
  301. if ($allowed_values[$item['value']] == '') {
  302. $display['type'] = 'list_key';
  303. break;
  304. }
  305. }
  306. else {
  307. $display['type'] = 'list_key';
  308. }
  309. }
  310. }
  311. break;
  312. case 'taxonomy':
  313. $display['type'] = 'taxonomy_term_reference_plain';
  314. break;
  315. case 'entityreference':
  316. $display['type'] = 'entityreference_label';
  317. break;
  318. default :
  319. // Use field instance formatter setting.
  320. break;
  321. }
  322. $function = $display['module'] . '_field_formatter_view';
  323. if (function_exists($function)) {
  324. $entity_group = array(0 => $entity);
  325. $item_group = array(0 => $items);
  326. $instance_group = array(0 => $instance);
  327. field_default_prepare_view($entity_type, $entity_group, $field, $instance_group, LANGUAGE_NONE, $item_group, $display);
  328. $elements = $function($entity_type, $entity, $field, $instance, LANGUAGE_NONE, $item_group[0], $display);
  329. }
  330. }
  331. if (count($elements) > 0) {
  332. foreach ($field['columns'] as $column => $attributes) {
  333. if (count($field['columns']) == 1) {
  334. $keyed_elements["@{$column}_value"] = $elements;
  335. }
  336. }
  337. }
  338. $values = array();
  339. foreach ($value_keys as $key) {
  340. $output = array();
  341. $elements = $keyed_elements[$key];
  342. if (is_array($elements)) {
  343. foreach ($elements as $element_key => $element) {
  344. if (is_numeric($element_key)) {
  345. $value_str= strip_tags(drupal_render($element));
  346. if (strlen($value_str) > 0) {
  347. $output[] = $value_str;
  348. }
  349. }
  350. }
  351. }
  352. else {
  353. $value_str = strip_tags(drupal_render($elements));
  354. if (strlen($value_str) > 0) {
  355. $output[] = $value_str;
  356. }
  357. }
  358. $value = implode(', ', $output);
  359. if ($value !== '') {
  360. $values[$key] = implode(', ', $output);
  361. }
  362. }
  363. $string = '';
  364. $value_count = count($values);
  365. foreach ($keys as $key_name => $column) {
  366. if (isset($values[$key_name . '_value'])) {
  367. $string .= ($value_count > 1) ? " @{$column} = @{$column}_value" : "@{$column}_value";
  368. }
  369. }
  370. return t('@field is set to "!value"', array('@field' => $instance['label'], '!value' => format_string($string, array_merge($keys, $values))));
  371. }