Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0 / 0 |
|
100.00% |
0 / 0 |
CRAP | |
8.91% |
9 / 101 |
|
| ctools_content_menu | |
100.00% |
1 / 1 |
0 | |
100.00% |
9 / 9 |
|||
| ctools_content_autocomplete_entity | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 27 |
|||
| _ctools_buildQuery | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 26 |
|||
| _ctools_getReferencableEntities | |
0.00% |
0 / 1 |
0 | |
0.00% |
0 / 39 |
|||
| <?php | |
| /** | |
| * @file | |
| * Contains menu item registration for the content tool. | |
| * | |
| * The menu items registered are AJAX callbacks for the things like | |
| * autocomplete and other tools needed by the content types. | |
| */ | |
| function ctools_content_menu(&$items) { | |
| $base = array( | |
| 'access arguments' => array('access content'), | |
| 'type' => MENU_CALLBACK, | |
| 'file' => 'includes/content.menu.inc', | |
| ); | |
| $items['ctools/autocomplete/%'] = array( | |
| 'page callback' => 'ctools_content_autocomplete_entity', | |
| 'page arguments' => array(2), | |
| ) + $base; | |
| } | |
| /** | |
| * Helper function for autocompletion of entity titles. | |
| */ | |
| function ctools_content_autocomplete_entity($entity_type, $string = '') { | |
| if ($string != '') { | |
| $entity_info = entity_get_info($entity_type); | |
| if (!module_exists('entity')) { | |
| module_load_include('inc', 'ctools', 'includes/entity-access'); | |
| _ctools_entity_access($entity_info, $entity_type); | |
| } | |
| // We must query all ids, because if every one of the 10 don't have access | |
| // the user may never be able to autocomplete a node title. | |
| $preg_matches = array(); | |
| $matches = array(); | |
| $match = preg_match('/\[id: (\d+)\]/', $string, $preg_matches); | |
| if (!$match) { | |
| $match = preg_match('/^id: (\d+)/', $string, $preg_matches); | |
| } | |
| // If an ID match was found, use that ID rather than the whole string. | |
| if ($match) { | |
| $entity_id = $preg_matches[1]; | |
| $results = _ctools_getReferencableEntities($entity_type, $entity_info, $entity_id, '=', 1); | |
| } | |
| else { | |
| // We cannot find results if the entity doesn't have a label to search. | |
| if (!isset($entity_info['entity keys']['label'])) { | |
| drupal_json_output(array("[id: NULL]" => '<span class="autocomplete_title">' . t('Entity Type !entity_type does not support autocomplete search.', array('!entity_type' => $entity_type)) . '</span>')); | |
| return; | |
| } | |
| $results = _ctools_getReferencableEntities($entity_type, $entity_info, $string, 'LIKE', 10); | |
| } | |
| foreach ($results as $entity_id => $result) { | |
| $matches[$result['label'] . " [id: $entity_id]"] = '<span class="autocomplete_title">' . check_plain($result['label']) . '</span>'; | |
| $matches[$result['label'] . " [id: $entity_id]"] .= isset($result['bundle']) ? ' <span class="autocomplete_bundle">(' . check_plain($result['bundle']) . ')</span>' : ''; | |
| } | |
| drupal_json_output($matches); | |
| } | |
| } | |
| /* | |
| * Use well known/tested entity reference code to build our search query | |
| * From EntityReference_SelectionHandler_Generic class | |
| */ | |
| function _ctools_buildQuery($entity_type, $entity_info, $match = NULL, $match_operator = 'CONTAINS') { | |
| $base_table = $entity_info['base table']; | |
| $label_key = $entity_info['entity keys']['label']; | |
| $query = db_select($base_table) | |
| ->fields($base_table, array($entity_info['entity keys']['id'])); | |
| if (isset($match)) { | |
| if (isset($label_key)) { | |
| $query->condition($base_table . '.' . $label_key, '%' . $match . '%', $match_operator); | |
| } | |
| // This should never happen, but double check just in case. | |
| else { | |
| return array(); | |
| } | |
| } | |
| // Add a generic entity access tag to the query. | |
| $query->addTag('ctools'); | |
| // We have to perform two checks. First check is a query alter (with tags) | |
| // in an attempt to only return results that have access. However, this is | |
| // not full-proof since entities many not implement hook_access query tag. | |
| // This is why we have a second check after entity load, before we display | |
| // the label of an entity. | |
| if ($entity_type == 'comment') { | |
| // Adding the 'comment_access' tag is sadly insufficient for comments: core | |
| // requires us to also know about the concept of 'published' and | |
| // 'unpublished'. | |
| if (!user_access('administer comments')) { | |
| $query->condition('comment.status', COMMENT_PUBLISHED); | |
| } | |
| // Join to a node if the user does not have node access bypass permissions | |
| // to obey node published permissions | |
| if (!user_access('bypass node access')) { | |
| $node_alias = $query->innerJoin('node', 'n', '%alias.nid = comment.nid'); | |
| $query->condition($node_alias . '.status', NODE_PUBLISHED); | |
| } | |
| $query->addTag('node_access'); | |
| } | |
| else { | |
| $query->addTag($entity_type . '_access'); | |
| } | |
| // Add the sort option. | |
| if (isset($label_key)) { | |
| $query->orderBy($base_table . '.' . $label_key, 'ASC'); | |
| } | |
| return $query; | |
| } | |
| /** | |
| * Private function to get referencable entities. Based on code from the | |
| * Entity Reference module. | |
| */ | |
| function _ctools_getReferencableEntities($entity_type, $entity_info, $match = NULL, $match_operator = 'LIKE', $limit = 0) { | |
| global $user; | |
| $account = $user; | |
| $options = array(); | |
| // We're an entity ID, return the id | |
| if (is_numeric($match) && $match_operator == '=') { | |
| if ($entity = array_shift(entity_load($entity_type, array($match)))) { | |
| if (isset($entity_info['access callback']) && function_exists($entity_info['access callback'])) { | |
| if ($entity_info['access callback']('view', $entity, $account, $entity_type)) { | |
| $label = entity_label($entity_type, $entity); | |
| return array( | |
| $match => array( | |
| 'label' => !empty($label) ? $label : $entity->{$entity_info['entity keys']['id']}, | |
| 'bundle' => !empty($entity_info['entity keys']['bundle']) ? check_plain($entity->{$entity_info['entity keys']['bundle']}) : NULL, | |
| ), | |
| ); | |
| } | |
| } | |
| } | |
| // If you don't have access, or an access callback or a valid entity, just | |
| // Return back the Entity ID. | |
| return array( | |
| $match => array( | |
| 'label' => $match, | |
| 'bundle' => NULL, | |
| ), | |
| ); | |
| } | |
| // We have matches, build a query to fetch the result. | |
| if ($query = _ctools_buildQuery($entity_type, $entity_info, $match, $match_operator)) { | |
| if ($limit > 0) { | |
| $query->range(0, $limit); | |
| } | |
| $results = $query->execute(); | |
| if (!empty($results)) { | |
| foreach ($results as $record) { | |
| $entities = entity_load($entity_type, array($record->{$entity_info['entity keys']['id']})); | |
| $entity = array_shift($entities); | |
| if (isset($entity_info['access callback']) && function_exists($entity_info['access callback'])) { | |
| if ($entity_info['access callback']('view', $entity, $account, $entity_type)) { | |
| $label = entity_label($entity_type, $entity); | |
| $options[$record->{$entity_info['entity keys']['id']}] = array( | |
| 'label' => !empty($label) ? $label : $entity->{$entity_info['entity keys']['id']}, | |
| 'bundle' => !empty($entity_info['entity keys']['bundle']) ? check_plain($entity->{$entity_info['entity keys']['bundle']}) : NULL, | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| return $options; | |
| } | |
| return array(); | |
| } |