123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- <?php
- /**
- * @file
- * Source plugin for the Translation Management system that handles entities.
- */
- /**
- * Implements hook_tmgmt_source_plugin_info().
- */
- function tmgmt_entity_tmgmt_source_plugin_info() {
- $info['entity'] = array(
- 'label' => t('Entity'),
- 'description' => t('Source handler for entities.'),
- 'plugin controller class' => 'TMGMTEntitySourcePluginController',
- 'item types' => array(),
- );
- $entity_types = array_filter(variable_get('entity_translation_entity_types', array()));
- foreach ($entity_types as $entity_key) {
- $entity_info = entity_get_info($entity_key);
- $info['entity']['item types'][$entity_key] = $entity_info['label'];
- }
- return $info;
- }
- /**
- * Implements hook_form_ID_alter().
- *
- * Alters comment node type select box to filter out comment types that belongs
- * to non entity translatable node types.
- */
- function tmgmt_entity_form_tmgmt_ui_entity_source_comment_overview_form_alter(&$form, &$form_state) {
- if (!isset($form['search_wrapper']['search']['node_type'])) {
- return;
- }
- // Change the select name to "type" as in the query submitted value will be
- // passed into node.type condition.
- $form['search_wrapper']['search']['type'] = $form['search_wrapper']['search']['node_type'];
- unset($form['search_wrapper']['search']['node_type']);
- // Set new default value.
- $form['search_wrapper']['search']['type']['#default_value'] = isset($_GET['type']) ? $_GET['type'] : NULL;
- }
- /**
- * Helper function to get entity translatable bundles.
- *
- * Note that for comment entity type it will return the same as for node as
- * comment bundles have no use (i.e. in queries).
- *
- * @param string $entity_type
- * Drupal entity type.
- *
- * @return array
- * Array of key => values, where key is type and value its label.
- */
- function tmgmt_entity_get_translatable_bundles($entity_type) {
- // If given entity type does not have entity translations enabled, no reason
- // to continue.
- if (!in_array($entity_type, variable_get('entity_translation_entity_types', array()))) {
- return array();
- }
- $entity_info = entity_get_info($entity_type);
- $translatable_bundle_types = array();
- foreach ($entity_info['bundles'] as $bundle_type => $bundle_definition) {
- if ($entity_type == 'comment') {
- $bundle_type = str_replace('comment_node_', '', $bundle_type);
- if (variable_get('language_content_type_' . $bundle_type) == ENTITY_TRANSLATION_ENABLED) {
- $translatable_bundle_types[$bundle_type] = $bundle_definition['label'];
- }
- }
- elseif ($entity_type == 'node') {
- if (variable_get('language_content_type_' . $bundle_type) == ENTITY_TRANSLATION_ENABLED) {
- $translatable_bundle_types[$bundle_type] = $bundle_definition['label'];
- }
- }
- else {
- $translatable_bundle_types[$bundle_type] = $bundle_definition['label'];
- }
- }
- return $translatable_bundle_types;
- }
- /**
- * Gets translatable entities of a given type.
- *
- * Additionally you can specify entity property conditions, pager and limit.
- *
- * @param string $entity_type
- * Drupal entity type.
- * @param array $property_conditions
- * Entity properties. There is no value processing so caller must make sure
- * the provided entity property exists for given entity type and its value
- * is processed.
- * @param bool $pager
- * Flag to determine if pager will be used.
- *
- * @return array
- * Array of translatable entities.
- */
- function tmgmt_entity_get_translatable_entities($entity_type, $property_conditions = array(), $pager = FALSE) {
- if (!in_array($entity_type, variable_get('entity_translation_entity_types', array()))) {
- return array();
- }
- $languages = drupal_map_assoc(array_keys(language_list()));
- $entity_info = entity_get_info($entity_type);
- $label_key = isset($entity_info['entity keys']['label']) ? $entity_info['entity keys']['label'] : NULL;
- $id_key = $entity_info['entity keys']['id'];
- $query = db_select($entity_info['base table'], 'e');
- $query->addTag('tmgmt_entity_get_translatable_entities');
- $query->addField('e', $id_key);
- // Language neutral entities are not translatable. Filter them out. To do
- // that: join {entity_translation} table, but only records with source column
- // empty. The {entity_translation}.language will represent the original entity
- // language in that case.
- $source_table_alias = $query->leftJoin('entity_translation', NULL, "%alias.entity_type = :entity_type AND %alias.entity_id = e.$id_key AND %alias.source = ''", array(':entity_type' => $entity_type));
- $query->condition("$source_table_alias.language", LANGUAGE_NONE, '<>');
- // Searching for sources with missing translation.
- if (!empty($property_conditions['target_status']) && !empty($property_conditions['target_language']) && in_array($property_conditions['target_language'], $languages)) {
- $translation_table_alias = db_escape_field('et_' . $property_conditions['target_language']);
- $query->leftJoin('entity_translation', $translation_table_alias, "%alias.entity_type = :entity_type AND %alias.entity_id = e.$id_key AND %alias.language = :language",
- array(':entity_type' => $entity_type, ':language' => $property_conditions['target_language']));
- // Exclude entities with having source language same as the target language
- // we search for.
- $query->condition('e.language', $property_conditions['target_language'], '<>');
- if ($property_conditions['target_status'] == 'untranslated_or_outdated') {
- $or = db_or();
- $or->isNull("$translation_table_alias.language");
- $or->condition("$translation_table_alias.translate", 1);
- $query->condition($or);
- }
- elseif ($property_conditions['target_status'] == 'outdated') {
- $query->condition("$translation_table_alias.translate", 1);
- }
- elseif ($property_conditions['target_status'] == 'untranslated') {
- $query->isNull("$translation_table_alias.language");
- }
- }
- // Remove the condition so we do not try to add it again below.
- unset($property_conditions['target_language']);
- unset($property_conditions['target_status']);
- // Searching for the source label.
- if (!empty($label_key) && isset($property_conditions[$label_key])) {
- $search_tokens = explode(' ', $property_conditions[$label_key]);
- $or = db_or();
- foreach ($search_tokens as $search_token) {
- $search_token = trim($search_token);
- if (strlen($search_token) > 2) {
- $or->condition($label_key, "%$search_token%", 'LIKE');
- }
- }
- if ($or->count() > 0) {
- $query->condition($or);
- }
- unset($property_conditions[$label_key]);
- }
- // Searching by taxonomy bundles - we need to switch to vid as the bundle key.
- if ($entity_type == 'taxonomy_term' && !empty($property_conditions['vocabulary_machine_name'])) {
- $property_name = 'vid';
- $vocabulary = taxonomy_vocabulary_machine_name_load($property_conditions['vocabulary_machine_name']);
- $property_value = $vocabulary->vid;
- $query->condition('e.' . $property_name, $property_value);
- // Remove the condition so we do not try to add it again below.
- unset($property_conditions['vocabulary_machine_name']);
- }
- // Searching by the node bundles - that applies for node entities as well as
- // comment.
- elseif (in_array($entity_type, array('comment', 'node'))) {
- $node_table_alias = 'e';
- // For comments join node table so that we can filter based on type.
- if ($entity_type == 'comment') {
- $query->join('node', 'n', 'e.nid = n.nid');
- $node_table_alias = 'n';
- }
- // Get translatable node types and check if it is worth to continue.
- $translatable_node_types = array_keys(tmgmt_entity_get_translatable_bundles('node'));
- if (empty($translatable_node_types)) {
- return array();
- }
- // If we have type property add condition.
- if (isset($property_conditions['type'])) {
- $query->condition($node_table_alias . '.type', $property_conditions['type']);
- // Remove the condition so we do not try to add it again below.
- unset($property_conditions['type']);
- }
- // If not, query db only for translatable node types.
- else {
- $query->condition($node_table_alias . '.type', $translatable_node_types);
- }
- }
- // Add remaining query conditions which are expected to be handled in a
- // generic way.
- foreach ($property_conditions as $property_name => $property_value) {
- $query->condition('e.' . $property_name, $property_value);
- }
- if ($pager) {
- $query = $query->extend('PagerDefault')->limit(variable_get('tmgmt_source_list_limit', 20));
- }
- else {
- $query->range(0, variable_get('tmgmt_source_list_limit', 20));
- }
- $query->orderBy($entity_info['entity keys']['id'], 'DESC');
- $entity_ids = $query->execute()->fetchCol();
- $entities = array();
- if (!empty($entity_ids)) {
- $entities = entity_load($entity_type, $entity_ids);
- }
- return $entities;
- }
- /**
- * Implements hook_tmgmt_source_suggestions()
- */
- function tmgmt_entity_tmgmt_source_suggestions(array $items, TMGMTJob $job) {
- $suggestions = array();
- // Get all translatable entity types.
- $entity_types = array_filter(variable_get('entity_translation_entity_types', array()));
- foreach ($items as $item) {
- if (($item instanceof TMGMTJobItem) && ($item->plugin == 'entity') || ($item->plugin == 'node')) {
- // Load the entity and extract the bundle name to get all fields from the
- // current entity.
- $entity = entity_load_single($item->item_type, $item->item_id);
- list(, , $bundle) = entity_extract_ids($item->item_type, $entity);
- $field_instances = field_info_instances($item->item_type, $bundle);
- // Loop over all fields, check if they are NOT translatable. Only if a
- // field is not translatable we may suggest a referenced entity. If so,
- // check for a supported field type (image and file currently here).
- foreach ($field_instances as $instance) {
- $field = field_info_field($instance['field_name']);
- $field_type = $field['type'];
- $field_name = $field['field_name'];
- switch ($field_type) {
- case 'file':
- case 'image':
- // 'File' (and images) must be translatable entity types.
- // Other files we not suggest here. Get all field items from the
- // current field and suggest them as translatable.
- if (isset($entity_types['file']) && ($field_items = field_get_items($item->item_type, $entity, $field_name))) {
- // Add all files as a suggestion.
- foreach ($field_items as $field_item) {
- $file_entity = entity_load_single('file', $field_item['fid']);
- // Check if there is already a translation available for this
- // file. If so, just continue with the next file.
- $handler = entity_translation_get_handler('file', $file_entity);
- if ($handler instanceof EntityTranslationHandlerInterface) {
- $translations = $handler->getTranslations();
- if (isset($translations->data[$job->target_language])) {
- continue;
- }
- }
- // Add the translation as a suggestion.
- $suggestions[] = array(
- 'job_item' => tmgmt_job_item_create('entity', 'file', $file_entity->fid),
- 'reason' => t('Field @label', array('@label' => $instance['label'])),
- 'from_item' => $item->tjiid,
- );
- }
- }
- break;
- case 'entityreference':
- $target_type = $field['settings']['target_type'];
- // Make sure only tranlatable entity types are suggested.
- if (isset($entity_types[$target_type]) && ($field_items = field_get_items($item->item_type, $entity, $field_name))) {
- // Add all referenced entities as suggestion.
- foreach ($field_items as $field_item) {
- $ref_entity = entity_load_single($target_type, $field_item['target_id']);
- // Check if there is already a translation available for this
- // entity. If so, just continue with the next one.
- $handler = entity_translation_get_handler($target_type, $ref_entity);
- if ($handler instanceof EntityTranslationHandlerInterface) {
- $translations = $handler->getTranslations();
- if (isset($translations->data[$job->target_language])) {
- continue;
- }
- }
- // Add suggestion.
- $suggestions[] = array(
- 'job_item' => tmgmt_job_item_create('entity', $target_type, $field_item['target_id']),
- 'reason' => t('Field @label', array('@label' => $instance['label'])),
- 'from_item' => $item->tjiid,
- );
- }
- }
- break;
- }
- }
- }
- }
- return $suggestions;
- }
|