first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
README.txt
==========
Drupal module: Translation set API
==================================
This is a generic API to handle translation sets. It is being used for now
for path translation and taxonomy term translation inside i18n package.
Translation sets can hold a collection of entities or other objects. A translation set is itself
an Entity thus leveraging all the power of the Entity API.
It also provides some basic storage for translation sets and a generator of new translation set id.
However, each module is responsible for storing which objects belong to which translation set for which
it needs to verride some methods of the base i18n_translation_set class.
- load_translations()
- save_translations()
- clean_translations()
- delete_translations()
Once these are implemented, to get the objects belonging to a translation set, indexed by language code,
you can invoke this method on a translation set object:
- get_translations()
To define a new type of translation set, a module must implement hook_i18n_translation_set_info()
as in this example:
/**
* Implements hook_i18n_translation_set_info().
*/
function i18n_path_i18n_translation_set_info() {
return array(
'path' => array(
'title' => t('Paths'),
'class' => 'i18n_path_translation_set',
)
);
}
See examples of overriding and extending this API:
- i18n_path/i18n_path.inc
- i18n_taxonomy/i18n_taxonomy.inc
====================================================================
Jose A. Reyero, http://reyero.net

View File

@@ -0,0 +1,98 @@
<?php
/**
* @file
* Internationalization (i18n) module. Translation sets admin
*/
/**
* Overview page for translation sets
*
* @param $type
* Translation set type to get a listing for this type only
* @param $query
* Base query to build upon
*/
function i18n_translation_admin_overview($type = NULL, $query = NULL) {
// Build the sortable table header.
$header['title'] = array('data' => t('Title'), 'field' => 't.title');
if (!$type) {
$header['type'] = array('data' => t('Type'), 'field' => 't.type');
}
$header['items'] = t('Items');
$header['created'] = array('data' => t('Created'), 'field' => 't.created');
$header['changed'] = array('data' => t('Updated'), 'field' => 't.changed', 'sort' => 'desc');
$header['operations'] = array('data' => t('Operations'));
// Get the translation sets for this form
$query = $query ? $query : db_select('i18n_translation_set', 't');
$query = $query->extend('PagerDefault')->extend('TableSort');
if ($type) {
$query->condition('t.type', $type);
}
$tsids = $query
->fields('t', array('tsid'))
->limit(20)
->orderByHeader($header)
->execute()
->fetchCol();
$translations = $tsids ? entity_load('i18n_translation', $tsids) : array();
$form = drupal_get_form('i18n_translation_admin_form', $translations, $header);
$form['pager'] = array('#markup' => theme('pager'));
return $form;
}
/**
* Admin form
*/
function i18n_translation_admin_form($form, &$form_state, $translations, $header) {
$destination = drupal_get_destination();
$rows = array();
foreach ($translations as $set) {
$info = i18n_object_info($set->type);
$rows[$set->tsid]['title'] = check_plain($set->get_title());
if (isset($header['type'])) {
$rows[$set->tsid]['type'] = isset($info['title']) ? $info['title'] : t('Unknown');
}
$rows[$set->tsid]['items'] = ($items = $set->get_links()) ? theme('links', array('links' => $items)) : '';
$rows[$set->tsid] += array(
'created' => format_date($set->created, 'short'),
'changed' => format_date($set->changed, 'short'),
'operations' => '',
);
// Build a list of all the accessible operations for the current set.
$operations = $set->get_operations();
if (count($operations) > 1) {
// Render an unordered list of operations links.
$rows[$set->tsid]['operations'] = array(
'data' => array(
'#theme' => 'links__node_operations',
'#links' => $operations,
'#attributes' => array('class' => array('links', 'inline')),
),
);
}
elseif (!empty($operations)) {
// Render the first and only operation as a link.
$link = reset($operations);
$rows[$set->tsid]['operations'] = array(
'data' => array(
'#type' => 'link',
'#title' => $link['title'],
'#href' => $link['href'],
'#options' => array('query' => $link['query']),
),
);
}
}
$form['translations'] = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('No translation sets available.'),
);
return $form;
}

View File

@@ -0,0 +1,45 @@
<?php
/**
* @file
* API documentation for Internationalization module
*
* Most i18n hooks can be placed on each module.i18n.inc file but in this case
* such file must be listed in the module.info file.
*/
/**
* Provide information about translation sets and involved objects.
*
* @see i18n_translation_set_info()
*
* @see hook_i18n_object_info()
*
* This feature relies on object information provided by i18n_object_info().
*/
function hook_i18n_translation_set_info() {
$info['taxonomy_term'] = array(
'title' => t('Taxonomy term'),
// The class that handles this translation sets
'class' => 'i18n_taxonomy_translation_set',
// Table and field into that table that keeps the translation set id for each item.
'table' => 'taxonomy_term_data',
'field' => 'i18n_tsid',
// This is the parent object (i18n object type).
'parent' => 'taxonomy_vocabulary',
// Placeholders and path information for generating translation set pages for administration.
'placeholder' => '%i18n_taxonomy_translation_set',
'list path' => 'admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/list/sets',
'edit path' => 'admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/list/sets/edit/%i18n_taxonomy_translation_set',
'delete path' => 'admin/structure/taxonomy/%taxonomy_vocabulary_machine_name/list/sets/delete/%i18n_taxonomy_translation_set',
'page callback' => 'i18n_taxonomy_term_translation_page',
);
return $info;
}
/**
* Alter i18n object information provided by modules with the previous hook
*
* @see i18n_translation_set_info()
*/
function hook_i18n_translation_set_info_alter(&$info) {
}

View File

@@ -0,0 +1,474 @@
<?php
/**
* @file
* Internationalization (i18n) module - Translation set
*/
class i18n_translation_set {
public $tsid = NULL;
public $type;
public $bundle = '';
public $status = 0;
public $master_id = 0;
// It may optionally have a title
public $title = '';
// Translations indexed by language
protected $translations = NULL;
// Translation languages indexed by oid
protected $object_languages = array();
// Related translation sets indexed by tsid
// Keep track of old translation sets objects belong to.
protected $related_translations = array();
/**
* Constructor from object/array
*/
public function __construct($translation = NULL) {
if ($translation) {
foreach ((array)$translation as $key => $value) {
$this->$key = $value;
}
}
}
/**
* Delete a translation set
*
* @param $delete_translations
* Whether to unlink translations from the set. Detaults to TRUE.
*/
public function delete($delete_translations = TRUE) {
db_delete('i18n_translation_set')
->condition('tsid', $this->tsid)
->execute();
if ($delete_translations) {
$this->delete_translations();
}
$this->invoke_all('delete');
$this->tsid = NULL;
}
/**
* Invoke all modules
*/
public function invoke_all($op) {
module_invoke_all('i18n_translation_set_' . $op, $this);
module_invoke_all('entity_' . $op, $this, 'i18n_translation');
}
/**
* Create a new translation set
*
* @param $save_translations
* Whether to update linked objects so they belong to this set.
*/
public function insert($save_translations = TRUE) {
$this->created = $this->changed = REQUEST_TIME;
$status = drupal_write_record('i18n_translation_set', $this);
if ($save_translations) {
$this->save_translations();
$this->update_related();
}
$this->invoke_all('insert');
return $status;
}
/**
* Save translation set
*
* @param $save_translations
* Whether to update linked objects so they belong to this set.
*/
public function save($save_translations = TRUE) {
$this->invoke_all('presave');
return empty($this->tsid) ? $this->insert($save_translations) : $this->update($save_translations);
}
/**
* Update a translation set
*
* @param $update_translations
* Whether to update objects linked to this set.
*/
public function update($update_translations = TRUE) {
$this->changed = REQUEST_TIME;
$status = drupal_write_record('i18n_translation_set', $this, 'tsid');
if ($update_translations) {
$this->clean_translations();
$this->save_translations();
$this->update_related();
}
$this->invoke_all('update');
return $status;
}
/**
* Update a translation set or delete if empty.
*/
public function update_delete() {
if ($this->get_translations()) {
$result = $this->save(TRUE);
// Update related translation sets too.
$this->update_related();
return $result;
}
else {
return $this->delete(TRUE);
}
}
/**
* Update related translation sets
*/
protected function update_related($op = 'update_delete') {
foreach ($this->related_translations as $translation_set) {
$translation_set->$op();
}
}
/**
* Clean all items in this translation set
*
* Unlink other items (not current translations from this translation set)
*/
public function clean_translations() {
if (($table = $this->get_table()) && ($field = $this->get_field())) {
$query = db_update($table)
->fields(array($field => 0))
->condition($field, $this->tsid);
if ($translations = $this->get_translations()) {
$query->condition('language', array_keys($translations), 'NOT IN');
}
return $query->execute();
}
}
/**
* Save translations in this translation set
*/
public function save_translations() {
if (($table = $this->get_table()) && ($field = $this->get_field())) {
if ($keys = $this->get_translations_keys()) {
return db_update($table)
->fields(array($field => $this->tsid))
->condition($this->key_field(), $keys)
->execute();
}
else {
return $this->delete_translations();
}
}
}
/**
* Delete translations in this translation set
*
* It won't delete objects, just unlink them from translation set
*/
public function delete_translations() {
if (($table = $this->get_table()) && ($field = $this->get_field())) {
return db_update($table)
->fields(array($field => 0))
->condition($field, $this->tsid)
->execute();
}
}
/**
* Get translations, indexed by language
*/
public function get_translations() {
$translations = array();
foreach ($this->get_objects() as $lang => $object) {
$translations[$lang] = $object->get_object();
}
return $translations;
}
/**
* Reset translations, set empty array or new array of translations.
*
* @param $translations array
* Array of langcode => item
*/
public function reset_translations($translations = array()) {
$this->translations = array();
$this->add_translations($translations);
return $this;
}
/**
* Get translations as i18n objects, indexed by language
*/
public function get_objects() {
if (!isset($this->translations)) {
$this->translations = array();
// Disable selection query altering, just in case
$previous = i18n_select(FALSE);
$this->add_translations($this->load_translations());
i18n_select($previous);
}
return $this->translations;
}
/**
* Get item for language
*/
public function get_item($langcode) {
if (($translations = $this->get_translations()) && isset($translations[$langcode])) {
return $translations[$langcode];
}
else {
return NULL;
}
}
/**
* Get translations keys, indexed by language
*/
public function get_translations_keys() {
$keys = array();
foreach ($this->get_objects() as $lang => $object) {
if ($id = $object->get_key()) {
$keys[$lang] = $id;
}
}
return array_filter($keys);
}
/**
* Get edit path for this translation set
*/
public function get_edit_path() {
if ($path = $this->get_info('edit path')) {
return strtr($path, $this->get_path_placeholders('delete'));
}
else {
return '';
}
}
/**
* Get operations as renderable links
*/
public function get_operations() {
$destination = drupal_get_destination();
$operations = array();
if ($path = $this->get_edit_path()) {
$operations['edit'] = array(
'title' => t('edit'),
'href' => $path,
'query' => $destination,
);
}
if ($path = $this->get_delete_path()) {
$operations['delete'] = array(
'title' => t('delete'),
'href' => $path,
'query' => $destination,
);
}
return $operations;
}
/**
* Get items as renderable links
*/
public function get_links() {
$language_list = language_list();
$items = array();
foreach ($this->get_objects() as $langcode => $object) {
$title = $object->get_title();
$path = $object->get_path();
$language = isset($language_list[$langcode]) ? $language_list[$langcode] : NULL;
$items[$langcode] = array(
'title' => $title,
'href' => $path ? $path : NULL,
'language' => $language,
);
if ($language && function_exists('languageicons_link_add')) {
languageicons_link_add($items[$langcode]);
}
}
return $items;
}
/**
* Get overview (list) path for this translation set
*/
public function get_list_path() {
return $this->get_info('list path');
}
/**
* Get delete path for this translation set
*/
public function get_delete_path() {
if ($path = $this->get_info('delete path')) {
return strtr($path, $this->get_path_placeholders('delete'));
}
else {
return '';
}
}
/**
* Get placeholder values for path replacement
*/
function get_path_placeholders($op = 'list') {
$values['%operation'] = $op;
$values['%type'] = $this->type;
$values['%i18n_translation_set'] = $this->tsid;
if ($placeholder = $this->get_info('placeholder')) {
$values[$placeholder] = $this->tsid;
}
return $values;
}
/**
* Get field on translations table that stores the translation set id (tsid)
*/
protected function get_field() {
return $this->get_info('field');
}
/**
* Get property from translation set info
*/
public function get_info($property, $default = NULL) {
$info = i18n_translation_set_info($this->type);
return $info && isset($info[$property]) ? $info[$property] : $default;
}
/**
* Get table name, where translation items are stored.
*/
protected function get_table() {
return $this->get_info('table');
}
/**
* Get title for this set
*/
public function get_title() {
if (!empty($this->title)) {
return $this->title;
}
elseif ($translations = $this->get_objects()) {
foreach ($translations as $object) {
$names[] = $object->get_title();
}
return implode(' / ', $names);
}
else {
return t('Undefined');
}
}
/**
* Get item list
*/
public function item_list() {
$language_list = language_list();
$items = array();
foreach ($this->get_objects() as $langcode => $object) {
$title = $object->get_title();
$path = $object->get_path();
if ($title && $path) {
$options = isset($language_list[$langcode]) ? array('language' => $language_list[$langcode]) : array();
$items[$langcode] = l($title, $path, $options);
}
elseif ($title) {
$items[$langcode] = check_plain($title);
}
}
return $items;
}
/**
* Add array of translation items
*
* @param $translations array
* Translation items indexed by language code
*/
public function add_translations($translations) {
foreach ($translations as $langcode => $item) {
$this->add_item($item, $langcode);
}
return $this;
}
/**
* Add translation item
*/
public function add_item($item, $langcode = NULL) {
$object = i18n_object($this->type, $item);
$langcode = $langcode ? $langcode : $object->get_langcode();
// Check whether this item belongs to another translation set
$old_tsid = $object->get_tsid();
if ($old_tsid && $old_tsid != $this->tsid) {
$this->related_translations[$old_tsid] = i18n_translation_set_load($old_tsid);
$this->related_translations[$old_tsid]->remove_object($object);
}
if ($langcode) {
$this->get_translations();
$object->set_tsid($this->tsid);
$this->translations[$langcode] = $object;
$this->object_languages[$object->get_index()] = $langcode;
}
return $this;
}
/**
* Remove item / language from translation set
*
* @param $item
* Item to remove from this translation set, it must have a language property.
*/
public function remove_item($item) {
$this->remove_object(i18n_object($this->type, $item));
return $this;
}
/**
* Remove i18n object from translation set.
*/
public function remove_object($object) {
// As object's language may have changed, we use our object_languages index better.
$index = $object->get_index();
$this->get_translations();
if (isset($this->object_languages[$index])) {
$langcode = $this->object_languages[$index];
unset($this->translations[$langcode]);
unset($this->object_languages[$index]);
}
return $this;
}
/**
* Remove language from translation set.
*
* @param $langcode
* Language to remove from this translation set.
*/
public function remove_language($langcode) {
$this->get_translations();
if (isset($this->translations[$langcode])) {
$this->remove_object($this->translations[$langcode]);
}
return $this;
}
/**
* Load all translations as objects indexed by language
*/
public function load_translations() {
if (($table = $this->get_table()) && ($field = $this->get_field())) {
return db_select($table, 't')
->fields('t')
->condition('t.' . $field, $this->tsid)
->execute()
->fetchAllAssoc('language');
}
else {
return array();
}
}
/**
* Get key field for this translation items
*/
protected function key_field() {
$info = i18n_object_info($this->type);
return $info['key'];
}
}

View File

@@ -0,0 +1,14 @@
name = Translation sets
description = Simple translation sets API for generic objects
dependencies[] = i18n
package = Multilingual - Internationalization
core = 7.x
files[] = i18n_translation.inc
; Information added by drupal.org packaging script on 2013-01-13
version = "7.x-1.8"
core = "7.x"
project = "i18n"
datestamp = "1358075001"

View File

@@ -0,0 +1,83 @@
<?php
/**
* @file
* Install, update and uninstall functions for the text module.
*/
/**
* Implements hook_install().
*/
function i18n_translation_install() {
}
/**
* Implements hook_schema().
*/
function i18n_translation_schema() {
$schema['i18n_translation_set'] = array(
'description' => 'Translation set.',
'fields' => array(
'tsid' => array(
'description' => 'The primary identifier for a translation set.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'title' => array(
'description' => 'The title of this translation set, always treated as non-markup plain text.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'type' => array(
'description' => 'Object type or entity type.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => ''
),
'bundle' => array(
'description' => 'Optional bundle for entity translation sets.',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => ''
),
'master_id' => array(
'description' => 'The master object/entity id (the others will be synchronized with this one).',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'status' => array(
'description' => 'Status of this translation set. TBD.',
'type' => 'int',
'not null' => TRUE,
'default' => 1,
),
'created' => array(
'description' => 'The Unix timestamp when the set was created.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
'changed' => array(
'description' => 'The Unix timestamp when the set was most recently saved.',
'type' => 'int',
'not null' => TRUE,
'default' => 0,
),
),
'indexes' => array(
'entity_bundle' => array('type', 'bundle'),
),
'primary key' => array('tsid'),
);
return $schema;
}

View File

@@ -0,0 +1,351 @@
<?php
/**
* @file
* Internationalization (i18n) module - Entity translations
*/
// Language list with only enabled languages
define('I18N_ENTITY_LANGUAGES_ENABLED', 0);
// Language list with all languages
define('I18N_ENTITY_LANGUAGES_EXTENDED', 1);
/**
* Default entity controller for notifications objects
*/
class I18nTranslationSetController extends DrupalDefaultEntityController {
/**
* Builds objects of specific classes upon loading.
*
* @param $queried_entities
* Associative array of query results, keyed on the entity ID.
* @param $revision_id
* ID of the revision that was loaded, or FALSE if teh most current revision
* was loaded.
*/
protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
foreach ($queried_entities as $id => $entity) {
$queried_entities[$id] = i18n_translation_set_build($entity->type, $entity);
}
return parent::attachLoad($queried_entities, $revision_id);
}
}
/**
* Implements hook_entity_info().
*/
function i18n_translation_entity_info() {
$bundles = array();
foreach (i18n_translation_set_info() as $type => $info) {
$bundles[$type] = array(
'label' => $info['title'],
);
}
$return = array(
'i18n_translation' => array(
'label' => t('Translation set'),
'controller class' => 'I18nTranslationSetController',
'base table' => 'i18n_translation_set',
//'uri callback' => 'taxonomy_term_uri',
'fieldable' => FALSE,
'entity keys' => array(
'id' => 'tsid',
'bundle' => 'type',
'label' => 'title',
),
'bundle keys' => array(
'bundle' => 'type',
),
'bundles' => $bundles,
),
);
return $return;
}
/**
* Implements hook_menu()
*/
function i18n_translation_menu() {
$items['admin/config/regional/i18n_translation'] = array(
'title' => 'Translation sets',
'description' => 'Translation sets overview.',
'page callback' => 'i18n_translation_admin_overview',
//'page arguments' => array('i18n_translation_set_overview'),
'access arguments' => array('administer site configuration'),
'file' => 'i18n_translation.admin.inc',
'weight' => 10,
);
$items['admin/config/regional/i18n_translation/configure'] = array(
'title' => 'Translation sets',
'description' => 'Overview of existing translation sets.',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
return $items;
}
/**
* Implements hook_hook_info().
*/
function i18n_translation_hook_info() {
$hooks['i18n_translation_set_info'] = array(
'group' => 'i18n',
);
return $hooks;
}
/**
* Check whether this object can be part of a translation set
*/
function i18n_translation_check_object($type, $object) {
if ($info = i18n_translation_set_info($type)) {
}
}
/**
* Get form element for translation mode and language
*
* @param $object_type
* Object type for the container element
* @param $i18n_mode
* Current or default translation mode
* @param $langcode
* Current or default language code
* @param $options
* Restricted list of translation modes if we don't want all of them
*/
function i18n_translation_mode_element($object_type, $i18n_mode = I18N_MODE_NONE, $langcode = LANGUAGE_NONE, $options = NULL) {
$form['i18n_translation'] = array(
'#type' => 'fieldset',
'#title' => t('Multilingual options'),
'#collapsible' => TRUE,
);
$form['i18n_translation']['i18n_mode'] = array(
'#type' => 'radios',
'#title' => t('Translation mode'),
'#options' => i18n_translation_options($object_type, $options),
'#default_value' => $i18n_mode,
'#description' => t('For localizable elements, to have all items available for translation visit the <a href="@locale-refresh">translation refresh</a> page.', array('@locale-refresh' => url('admin/config/regional/translate/i18n_string'))),
);
$form['i18n_translation']['language'] = array(
'#default_value' => $langcode ? $langcode : LANGUAGE_NONE,
'#description' => t('Predefined language. If set, it will apply to all items.'),
'#required' => TRUE,
'#states' => array(
'visible' => array('input[name="i18n_mode"]' => array('value' => (string)I18N_MODE_LANGUAGE)),
),
) + i18n_element_language_select();
// The option value 'Language neutral' makes no sense here.
$form['i18n_translation']['language']['#options'][LANGUAGE_NONE] = t('- Select a language -');
return $form;
}
/**
* Get list of translation modes
*
* @param $container_type
* Object type for the container
* @param $options
* Options to include. If none, defaults for container type will be returned.
*/
function i18n_translation_options($container_type, $options = NULL) {
// Get names and translation options for container object and items
$container_info = i18n_object_info($container_type, 'translation container');
$replacements = array(
'@container_name' => $container_info['name'],
'@item_name_multiple' => $container_info['item name'],
'@item_name_multiple_capitalized' => ucfirst($container_info['item name']),
);
$options = $options ? $options : $container_info['options'];
return i18n_translation_options_list($replacements, $options);
}
/**
* Get list of translation modes
*/
function i18n_translation_options_list($replacements = array(), $options = array()) {
$list = array(
I18N_MODE_NONE => t('No multilingual options for @item_name_multiple. Only the @container_name will be translatable.', $replacements),
I18N_MODE_LOCALIZE => t('Localize. @item_name_multiple_capitalized are common for all languages, but their name and description may be localized.', $replacements),
I18N_MODE_TRANSLATE => t('Translate. Different @item_name_multiple will be allowed for each language and they can be translated.', $replacements),
I18N_MODE_MULTIPLE => t('Translate and Localize. @item_name_multiple_capitalized with language will allow translations. @item_name_multiple_capitalized without language will be localized.', $replacements),
I18N_MODE_LANGUAGE => t('Fixed Language. @item_name_multiple_capitalized will have a global language and they will only show up for pages in that language.', $replacements),
);
if ($options) {
foreach (array_keys($list) as $key) {
if (!in_array($key, $options, TRUE)) {
unset($list[$key]);
}
}
}
return $list;
}
/**
* Build translation fieldset for object
*/
function i18n_translation_set_element($type, $object) {
$element = array(
'#type' => 'fieldset',
'#title' => t('Translations'),
);
if ($set = i18n_translation_object($type, $object)) {
$element['values']['#markup'] = i18n_translation_format_items($set->item_list());
}
else {
$element['message']['#markup'] = t('No translations');
}
return $element;
}
/**
* Format translation set info as table
*/
function i18n_translation_format_items($translations) {
foreach ($translations as $langcode => $item) {
$rows[] = array(i18n_language_name($langcode), $item);
}
return !empty($rows) ? theme('table', array('rows' => $rows)) : '';
}
/**
* Get translation set for object
*/
function i18n_translation_object($type, $object, $create = FALSE) {
if (($field = i18n_translation_set_info($type, 'field', 'i18n_tsid')) && ($tsid = i18n_object_field($object, $field))) {
return i18n_translation_set_load($tsid, $type);
}
elseif ($create) {
$set = i18n_translation_set_build($type);
if ($langcode = i18n_object_langcode($object)) {
$set->add_item($object, $langcode);
}
return $set;
}
}
/**
* Get information about translation sets
*/
function i18n_translation_set_info($type = NULL, $property = NULL, $default = NULL) {
$info = &drupal_static(__FUNCTION__);
if (!$info) {
$info = module_invoke_all('i18n_translation_set_info');
drupal_alter('i18n_translation_set_info', $info);
}
if ($property && $type) {
return isset($info[$type][$property]) ? $info[$type][$property] : $default;
}
elseif ($type) {
return isset($info[$type]) ? $info[$type] : $default;
}
else {
return $info;
}
}
/**
* Build a translation set from type, data
*/
function i18n_translation_set_build($type, $data = array()) {
$class = i18n_translation_set_info($type, 'class', 'i18n_translation_set');
$set = new $class((array)$data);
$set->type = $type;
return $set;
}
/**
* Create a new translation set
*/
function i18n_translation_set_create($type, $bundle = '', $translations = NULL, $master_id = 0) {
$set = i18n_translation_set_build($type, array('type' => $type, 'bundle' => $bundle, 'master_id' => $master_id, 'translations' => $translations));
$set->insert();
return $set;
}
/**
* Load single translation set.
*
* @param int $tsid
* Translation set id.
* @param string $type
* (Optional) translation set type (bundle).
*/
function i18n_translation_set_load($tsid, $type = NULL) {
$conditions['tsid'] = $tsid;
$list = entity_load('i18n_translation', array($tsid));
$entity = reset($list);
if ($entity && $type && $entity->type != $type) {
return NULL;
}
return $entity;
}
/**
* Index objects in translation set by language
*/
function i18n_translation_set_index($translations) {
$list = array();
foreach ($translations as $object) {
if ($lang = i18n_object_langcode($object)) {
$list[$lang] = $object;
}
}
return $list;
}
/**
* Translation set generic form
*/
function i18n_translation_set_overview($form, &$form_state, $type = NULL, $tsids = NULL) {
module_load_include('admin.inc', 'i18n_translation');
return i18n_translation_admin_form($form, $form_state, $type, $tsids);
}
/**
* Generate a tabular listing of translations for this type.
*/
function i18n_translation_set_list_manage($type) {
module_load_include('admin.inc', 'i18n_translation');
return i18n_translation_admin_overview($type);
}
/**
* Ask for confirmation of translation set deletion
*/
function i18n_translation_set_delete_confirm($form, &$form_state, $translation_set) {
$form['#translation_set'] = $translation_set;
$form['tsid'] = array(
'#type' => 'value',
'#value' => $translation_set->tsid,
);
if ($items = $translation_set->item_list()) {
$form['items'] = array(
'#type' => 'item',
'#title' => t('Items in this translation set'),
'#markup' => theme('item_list', array('items' => $items)),
);
}
return confirm_form($form,
t('Are you sure you want to delete %title translation set?', array('%title' => $translation_set->get_title())),
i18n_translation_set_info($translation_set->type, 'list path'),
t('This action cannot be undone.'),
t('Delete'),
t('Cancel')
);
}
/**
* Execute translation set deletion
*/
function i18n_translation_set_delete_confirm_submit($form, &$form_state) {
if ($form_state['values']['confirm']) {
$set = i18n_translation_set_load($form_state['values']['tsid']);
$set->delete(TRUE);
drupal_set_message(t('The translation set has been deleted.'));
}
$form_state['redirect'] = i18n_translation_set_info($set->type, 'list path');
}

View File

@@ -0,0 +1,13 @@
<?php
/**
* @file
* Generic translation page for objects
*/
/**
* Translate object, create translation set
*/
function i18n_translation_object_translate_page($type, $object) {
$page = i18n_translation_set_info($type, 'page callback');
return call_user_func($page, $type, $object);
}