updated core to 7.58 (right after the site was hacked)
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Hooks provided by the node source plugin for TMGMT.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Alter the created node translation.
|
||||
*
|
||||
* @param object
|
||||
* $tnode translated node
|
||||
* @param object
|
||||
* $node source node
|
||||
* @param TMGMTJobItem
|
||||
* $job_item
|
||||
*/
|
||||
function hook_tmgmt_before_update_node_translation_alter($tnode, $node, $job_item) {
|
||||
// Always store new translations as a new revision.
|
||||
$tnode->revision = 1;
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
name = Content Source
|
||||
description = Content Translation source plugin for the Translation Management system.
|
||||
package = Translation Management
|
||||
core = 7.x
|
||||
|
||||
dependencies[] = tmgmt
|
||||
dependencies[] = tmgmt_field
|
||||
dependencies[] = translation
|
||||
|
||||
files[] = tmgmt_node.plugin.inc
|
||||
files[] = tmgmt_node.ui.inc
|
||||
files[] = tmgmt_node.test
|
||||
|
||||
; Views integration and handlers
|
||||
files[] = views/tmgmt_node.views.inc
|
||||
files[] = views/handlers/tmgmt_node_handler_field_translation_language_status.inc
|
||||
files[] = views/handlers/tmgmt_node_handler_field_translation_language_status_single.inc
|
||||
files[] = views/handlers/tmgmt_node_handler_filter_node_translatable_types.inc
|
||||
files[] = views/handlers/tmgmt_node_handler_filter_missing_translation.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-09-21
|
||||
version = "7.x-1.0-rc2+1-dev"
|
||||
core = "7.x"
|
||||
project = "tmgmt"
|
||||
datestamp = "1474446494"
|
||||
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Source plugin for the Translation Management system that handles nodes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_tmgmt_source_plugin_info().
|
||||
*/
|
||||
function tmgmt_node_tmgmt_source_plugin_info() {
|
||||
$info['node'] = array(
|
||||
'label' => t('Node'),
|
||||
'description' => t('Source handler for nodes.'),
|
||||
'plugin controller class' => 'TMGMTNodeSourcePluginController',
|
||||
'ui controller class' => 'TMGMTNodeSourceUIController',
|
||||
'views controller class' => 'TMGMTNodeSourceViewsController',
|
||||
'item types' => array(),
|
||||
);
|
||||
foreach (node_type_get_names() as $type => $name) {
|
||||
if (translation_supported_type($type)) {
|
||||
$info['node']['item types'][$type] = $name;
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form element validator for the missing target language views field handler.
|
||||
*/
|
||||
function tmgmt_node_views_exposed_target_language_validate($form, &$form_state) {
|
||||
if (!empty($form_state['values']['tmgmt_node_missing_translation']) && $form_state['values']['language_1'] == $form_state['values']['tmgmt_node_missing_translation']) {
|
||||
form_set_error('tmgmt_node_missing_translation', t('The source and target languages must not be the same.'));
|
||||
}
|
||||
}
|
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides the node source plugin controller.
|
||||
*/
|
||||
|
||||
class TMGMTNodeSourcePluginController extends TMGMTDefaultSourcePluginController {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Returns the data from the fields as a structure that can be processed by
|
||||
* the Translation Management system.
|
||||
*/
|
||||
public function getData(TMGMTJobItem $job_item) {
|
||||
$node = node_load($job_item->item_id);
|
||||
$source_language = $job_item->getJob()->source_language;
|
||||
$languages = language_list();
|
||||
|
||||
// If the node language is not the same as the job source language try to
|
||||
// load its translation for the job source language.
|
||||
if ($node->language != $source_language) {
|
||||
$translation_loaded = FALSE;
|
||||
foreach (translation_node_get_translations($node->nid) as $language => $translation) {
|
||||
if ($language == $source_language) {
|
||||
$node = node_load($translation->nid);
|
||||
$translation_loaded = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$translation_loaded) {
|
||||
throw new TMGMTException(t('Unable to load %language translation for the node %title',
|
||||
array('%language' => $languages[$source_language]->name, '%title' => $node->title)));
|
||||
}
|
||||
}
|
||||
|
||||
$type = node_type_get_type($node);
|
||||
// Get all the fields that can be translated and arrange their values into
|
||||
// a specific structure.
|
||||
$structure = tmgmt_field_get_source_data('node', $node, $job_item->getJob()->source_language);
|
||||
$structure['node_title']['#label'] = $type->title_label;
|
||||
$structure['node_title']['#text'] = $node->title;
|
||||
return $structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function saveTranslation(TMGMTJobItem $job_item) {
|
||||
if ($node = node_load($job_item->item_id)) {
|
||||
$job = $job_item->getJob();
|
||||
if (empty($node->tnid)) {
|
||||
// We have no translation source nid, this is a new set, so create it.
|
||||
$node->tnid = $node->nid;
|
||||
node_save($node);
|
||||
}
|
||||
$translations = translation_node_get_translations($node->tnid);
|
||||
if (isset($translations[$job->target_language])) {
|
||||
// We have already a translation for the source node for the target
|
||||
// language, so load it.
|
||||
$tnode = node_load($translations[$job->target_language]->nid);
|
||||
}
|
||||
else {
|
||||
// We don't have a translation for the source node yet, so create one.
|
||||
$tnode = clone $node;
|
||||
unset($tnode->nid, $tnode->vid, $tnode->uuid, $tnode->vuuid);
|
||||
$tnode->language = $job->target_language;
|
||||
$tnode->translation_source = $node;
|
||||
}
|
||||
|
||||
// Allow modules and translator plugins to alter, for example in the
|
||||
// case of creating revisions for translated nodes, or altering
|
||||
// properties of the tnode before saving.
|
||||
drupal_alter('tmgmt_before_update_node_translation', $tnode, $node, $job_item);
|
||||
|
||||
// Time to put the translated data into the node.
|
||||
$data = $job_item->getData();
|
||||
// Special case for the node title.
|
||||
if (isset($data['node_title']['#translation']['#text'])) {
|
||||
$tnode->title = $data['node_title']['#translation']['#text'];
|
||||
unset($data['node_title']);
|
||||
}
|
||||
tmgmt_field_populate_entity('node', $tnode, $job->target_language, $data, FALSE);
|
||||
// Reset translation field, which determines outdated status.
|
||||
$tnode->translation['status'] = 0;
|
||||
node_save($tnode);
|
||||
|
||||
// We just saved the translation, set the sate of the job item to
|
||||
// 'finished'.
|
||||
$job_item->accepted();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLabel(TMGMTJobItem $job_item) {
|
||||
if ($node = node_load($job_item->item_id)) {
|
||||
return entity_label('node', $node);
|
||||
}
|
||||
return parent::getLabel($job_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUri(TMGMTJobItem $job_item) {
|
||||
if ($node = node_load($job_item->item_id)) {
|
||||
return entity_uri('node', $node);
|
||||
}
|
||||
return parent::getUri($job_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType(TMGMTJobItem $job_item) {
|
||||
if ($node = node_load($job_item->item_id)) {
|
||||
return node_type_get_name($node);
|
||||
}
|
||||
return parent::getType($job_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSourceLangCode(TMGMTJobItem $job_item) {
|
||||
if ($node = node_load($job_item->item_id)) {
|
||||
return entity_language('node', $node);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExistingLangCodes(TMGMTJobItem $job_item) {
|
||||
$existing_lang_codes = array();
|
||||
if ($node = node_load($job_item->item_id)) {
|
||||
$existing_lang_codes = array(entity_language('node', $node));
|
||||
}
|
||||
if ($translations = translation_node_get_translations($job_item->item_id)) {
|
||||
$existing_lang_codes = array_unique(array_merge($existing_lang_codes, array_keys($translations)));
|
||||
}
|
||||
|
||||
return $existing_lang_codes;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Basic Node Source tests.
|
||||
*/
|
||||
class TMGMTNodeSourceTestCase extends TMGMTEntityTestCaseUtility {
|
||||
|
||||
static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node Source tests',
|
||||
'description' => 'Exporting source data from nodes and saving translations back to nodes',
|
||||
'group' => 'Translation Management',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp(array('tmgmt_node', 'translation'));
|
||||
$this->loginAsAdmin();
|
||||
$this->setEnvironment('de');
|
||||
$this->createNodeType('page', 'Basic page', TRANSLATION_ENABLED, FALSE);
|
||||
$this->attachFields('node', 'page', array(TRUE, TRUE, FALSE, FALSE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests nodes field translation.
|
||||
*/
|
||||
function testNodeSource() {
|
||||
|
||||
// Create a translation job.
|
||||
$job = $this->createJob();
|
||||
$job->translator = $this->default_translator->name;
|
||||
$job->settings = array();
|
||||
$job->save();
|
||||
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
$node = $this->createNode('page');
|
||||
// Create a job item for this node and add it to the job.
|
||||
$item = $job->addItem('node', 'node', $node->nid);
|
||||
$this->assertEqual('Basic page', $item->getSourceType());
|
||||
}
|
||||
|
||||
// Translate the job.
|
||||
$job->requestTranslation();
|
||||
|
||||
foreach ($job->getItems() as $item) {
|
||||
// The source is only available in en.
|
||||
$this->assertJobItemLangCodes($item, 'en', array('en'));
|
||||
|
||||
$item->acceptTranslation();
|
||||
$node = node_load($item->item_id);
|
||||
// Check if the tnid attribute is bigger than 0.
|
||||
$this->assertTrue($node->tnid > 0, 'The source node is part of a translation set.');
|
||||
// The translations may be statically cached, so make make sure
|
||||
// to reset the cache before loading the node translations.
|
||||
$cached_translations = & drupal_static('translation_node_get_translations', array());
|
||||
unset($cached_translations[$node->tnid]);
|
||||
// Load the translation set of the source node.
|
||||
$translations = translation_node_get_translations($node->tnid);
|
||||
$this->assertNotNull($translations['de'], 'Translation found for the source node.');
|
||||
if (isset($translations['de'])) {
|
||||
$tnode = node_load($translations['de']->nid, NULL, TRUE);
|
||||
$this->checkTranslatedData($tnode, $item->getData(), 'de');
|
||||
}
|
||||
|
||||
// The source should be now available for en and de.
|
||||
$this->assertJobItemLangCodes($item, 'en', array('de', 'en'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the source is able to pull content in requested language.
|
||||
*/
|
||||
function testRequestDataForSpecificLanguage() {
|
||||
$this->setEnvironment('sk');
|
||||
$this->setEnvironment('es');
|
||||
$content_type = $this->drupalCreateContentType();
|
||||
|
||||
$node = $this->drupalCreateNode(array(
|
||||
'title' => $this->randomName(),
|
||||
'language' => 'sk',
|
||||
'body' => array('sk' => array(array())),
|
||||
'type' => $content_type->type,
|
||||
));
|
||||
|
||||
$this->drupalCreateNode(array(
|
||||
'title' => 'en translation',
|
||||
'language' => 'en',
|
||||
'tnid' => $node->nid,
|
||||
'body' => array('en' => array(array())),
|
||||
'type' => $content_type->type,
|
||||
));
|
||||
|
||||
// Create a translation job.
|
||||
$job = $this->createJob('en', 'de');
|
||||
$job->save();
|
||||
$job->addItem('node', 'node', $node->nid);
|
||||
|
||||
$data = $job->getData();
|
||||
$this->assertEqual($data[1]['node_title']['#text'], 'en translation');
|
||||
|
||||
// Create new job item with a source language for which the translation
|
||||
// does not exit.
|
||||
$job = $this->createJob('es', 'cs');
|
||||
$job->save();
|
||||
try {
|
||||
$job->addItem('node', 'node', $node->nid);
|
||||
$this->fail('The job item should not be added as there is no translation for language "es"');
|
||||
}
|
||||
catch (TMGMTException $e) {
|
||||
$languages = language_list();
|
||||
$this->assertEqual(t('Unable to load %language translation for the node %title',
|
||||
array('%language' => $languages['es']->name, '%title' => $node->title)), $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the data from an entity with the translated data.
|
||||
*
|
||||
* @param $node
|
||||
* The translated node object.
|
||||
* @param $data
|
||||
* An array with the translated data.
|
||||
* @param $langcode
|
||||
* The code of the target language.
|
||||
*/
|
||||
function checkTranslatedData($node, $data, $langcode) {
|
||||
foreach (element_children($data) as $field_name) {
|
||||
if ($field_name == 'node_title') {
|
||||
$this->assertEqual($node->title, $data['node_title']['#translation']['#text'], 'The title of the translated node matches the translated data.');
|
||||
continue;
|
||||
}
|
||||
foreach (element_children($data[$field_name]) as $delta) {
|
||||
$field_langcode = field_is_translatable('node', field_info_field($field_name)) ? $langcode : LANGUAGE_NONE;
|
||||
foreach (element_children($data[$field_name][$delta]) as $column) {
|
||||
$column_value = $data[$field_name][$delta][$column];
|
||||
if (!isset($column_value['#translate']) || $column_value['#translate']) {
|
||||
$this->assertEqual($node->{$field_name}[$field_langcode][$delta][$column], $column_value['#translation']['#text'], format_string('The translatable field %field:%delta has been populated with the proper translated data.', array(
|
||||
'%field' => $field_name,
|
||||
'delta' => $delta
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides the node source ui controller.
|
||||
*/
|
||||
|
||||
class TMGMTNodeSourceUIController extends TMGMTDefaultSourceUIController {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hook_menu() {
|
||||
// The node source overview is a View using Views Bulk Operations. Therefore
|
||||
// we don't need to provide any menu items.
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hook_forms() {
|
||||
// The node source overview is a View using Views Bulk Operations. Therefore
|
||||
// we don't need to provide any forms.
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hook_views_default_views() {
|
||||
return _tmgmt_load_exports('tmgmt_node', 'views', 'view.inc', 'view');
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
name = Content Source User Interface
|
||||
description = User Interface for the content translation source plugin.
|
||||
package = Translation Management
|
||||
core = 7.x
|
||||
|
||||
dependencies[] = tmgmt_node
|
||||
dependencies[] = tmgmt_ui
|
||||
dependencies[] = views_bulk_operations
|
||||
|
||||
files[] = tmgmt_node_ui.test
|
||||
files[] = tmgmt_node_ui.overview.test
|
||||
|
||||
; Views handlers
|
||||
files[] = views/tmgmt_node_ui_handler_filter_node_translatable_types.inc
|
||||
files[] = views/tmgmt_node_ui_handler_field_jobs.inc
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-09-21
|
||||
version = "7.x-1.0-rc2+1-dev"
|
||||
core = "7.x"
|
||||
project = "tmgmt"
|
||||
datestamp = "1474446494"
|
||||
|
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Main module file for the translation management node source plugin user
|
||||
* interface.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_page_alter().
|
||||
*/
|
||||
function tmgmt_node_ui_page_alter(&$page) {
|
||||
// Translation tabs for nodes.
|
||||
if (($node = menu_get_object()) && entity_access('create', 'tmgmt_job')) {
|
||||
if (isset($page['content']['system_main']['translation_node_overview'])) {
|
||||
module_load_include('inc', 'tmgmt_node_ui', 'tmgmt_node_ui.pages');
|
||||
$page['content']['system_main']['translation_node_overview'] = drupal_get_form('tmgmt_node_ui_node_form', $node, $page['content']['system_main']['translation_node_overview']);
|
||||
}
|
||||
// Support the context module: when context is used for placing the
|
||||
// system_main block, then block contents appear nested one level deeper
|
||||
// under another 'content' key.
|
||||
elseif (isset($page['content']['system_main']['content']['translation_node_overview'])) {
|
||||
module_load_include('inc', 'tmgmt_node_ui', 'tmgmt_node_ui.pages');
|
||||
$page['content']['system_main']['content']['translation_node_overview'] = drupal_get_form('tmgmt_node_ui_node_form', $node, $page['content']['system_main']['content']['translation_node_overview']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_action_info().
|
||||
*/
|
||||
function tmgmt_node_ui_action_info() {
|
||||
return array(
|
||||
'tmgmt_node_ui_checkout_multiple_action' => array(
|
||||
'type' => 'node',
|
||||
'label' => t('Request translations'),
|
||||
'configurable' => false,
|
||||
'aggregate' => true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to do multistep checkout for translations.
|
||||
*
|
||||
* @param array $nodes
|
||||
* Array of Drupal nodes.
|
||||
* @param $info
|
||||
* Action info - not used.
|
||||
*
|
||||
*/
|
||||
function tmgmt_node_ui_checkout_multiple_action($nodes, $info) {
|
||||
$jobs = array();
|
||||
$source_lang_registry = array();
|
||||
|
||||
// Loop through entities and create individual jobs for each source language.
|
||||
foreach ($nodes as $node) {
|
||||
|
||||
try {
|
||||
|
||||
// For given source lang no job exists yet.
|
||||
if (!isset($source_lang_registry[$node->language])) {
|
||||
// Create new job.
|
||||
$job = tmgmt_job_create($node->language, NULL, $GLOBALS['user']->uid);
|
||||
// Add initial job item.
|
||||
$job->addItem('node', 'node', $node->nid);
|
||||
// Add job identifier into registry
|
||||
$source_lang_registry[$node->language] = $job->tjid;
|
||||
// Add newly created job into jobs queue.
|
||||
$jobs[$job->tjid] = $job;
|
||||
}
|
||||
// We have a job for given source lang, so just add new job item for the
|
||||
// existing job.
|
||||
else {
|
||||
$jobs[$source_lang_registry[$node->language]]->addItem('node', 'node', $node->nid);
|
||||
}
|
||||
}
|
||||
catch (TMGMTException $e) {
|
||||
watchdog_exception('tmgmt', $e);
|
||||
drupal_set_message(t('Unable to add job item for node %name. Make sure the source content is not empty.', array('%name' => $node->title)), 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// If necessary, do a redirect.
|
||||
$redirects = tmgmt_ui_job_checkout_multiple($jobs);
|
||||
if ($redirects) {
|
||||
tmgmt_ui_redirect_queue_set($redirects, current_path());
|
||||
drupal_set_message(format_plural(count($redirects), t('One job needs to be checked out.'), t('@count jobs need to be checked out.')));
|
||||
drupal_goto(tmgmt_ui_redirect_queue_dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Content Overview Tests
|
||||
*/
|
||||
class TMGMTNodeSourceUIOverviewTestCase extends TMGMTEntityTestCaseUtility {
|
||||
|
||||
static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node Source UI Overview tests',
|
||||
'description' => 'Tests the user interface for node overviews.',
|
||||
'group' => 'Translation Management',
|
||||
'dependencies' => array('rules'),
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp(array('tmgmt_node_ui'));
|
||||
|
||||
$this->loginAsAdmin();
|
||||
|
||||
$this->setEnvironment('de');
|
||||
$this->setEnvironment('fr');
|
||||
$this->setEnvironment('es');
|
||||
$this->setEnvironment('el');
|
||||
|
||||
$this->createNodeType('page', 'Page', TRANSLATION_ENABLED, FALSE);
|
||||
// 1 means that the node type can have a language but is not translatable.
|
||||
$this->createNodeType('untranslated', 'Untranslated', 1, FALSE);
|
||||
|
||||
$this->checkPermissions(array(), TRUE);
|
||||
|
||||
// Allow auto-accept.
|
||||
$default_translator = tmgmt_translator_load('test_translator');
|
||||
$default_translator->settings = array(
|
||||
'auto_accept' => TRUE,
|
||||
);
|
||||
$default_translator->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests translating through the content source overview.
|
||||
*/
|
||||
function testNodeSourceOverview() {
|
||||
|
||||
// Login as translator to translate nodes.
|
||||
$this->loginAsTranslator(array(
|
||||
'translate content',
|
||||
'edit any page content',
|
||||
'create page content',
|
||||
));
|
||||
|
||||
// Create a bunch of english nodes.
|
||||
$node1 = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
$node2 = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
$node3 = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
$node4 = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Create a node with an undefined language.
|
||||
$node5 = $this->drupalCreateNode(array('type' => 'page'));
|
||||
|
||||
// Create a node of an untranslatable content type.
|
||||
$node6 = $this->drupalCreateNode(array('type' => 'untranslated', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Go to the overview page and make sure the nodes are there.
|
||||
$this->drupalGet('admin/tmgmt/sources/node');
|
||||
|
||||
// Make sure that valid nodes are shown.
|
||||
$this->assertText($node1->title);
|
||||
$this->assertText($node2->title);
|
||||
$this->assertText($node3->title);
|
||||
$this->assertText($node4->title);
|
||||
// Nodes without a language must not be shown.
|
||||
$this->assertNoText($node5->title);
|
||||
// Node with a type that is not enabled for translation must not be shown.
|
||||
$this->assertNoText($node6->title);
|
||||
|
||||
// Now translate them.
|
||||
$edit = array(
|
||||
'views_bulk_operations[0]' => TRUE,
|
||||
'views_bulk_operations[1]' => TRUE,
|
||||
'views_bulk_operations[2]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translations'));
|
||||
|
||||
// Some assertions on the submit form.
|
||||
$this->assertText(t('@title and 2 more (English to ?, Unprocessed)', array('@title' => $node1->title)));
|
||||
$this->assertText($node1->title);
|
||||
$this->assertText($node2->title);
|
||||
$this->assertText($node3->title);
|
||||
$this->assertNoText($node4->title);
|
||||
|
||||
// Translate
|
||||
$edit = array(
|
||||
'target_language' => 'de',
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Submit to translator'));
|
||||
$this->assertNoText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node1->title, '@language' => t('German'))));
|
||||
$this->assertText(t('The translation for @title has been accepted.', array('@title' => $node1->title)));
|
||||
$this->assertNoText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node2->title, '@language' => t('German'))));
|
||||
$this->assertText(t('The translation for @title has been accepted.', array('@title' => $node1->title)));
|
||||
$this->assertNoText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node3->title, '@language' => t('German'))));
|
||||
$this->assertText(t('The translation for @title has been accepted.', array('@title' => $node1->title)));
|
||||
|
||||
// Check the translated node.
|
||||
$this->clickLink($node1->title);
|
||||
$this->clickLink(t('Translate'));
|
||||
$this->assertText('de_' . $node1->title);
|
||||
|
||||
// Test for the source list limit set in the views export.
|
||||
$view = views_get_view('tmgmt_node_source_overview');
|
||||
$view->execute_display('default');
|
||||
$this->assertEqual($view->get_items_per_page(), variable_get('tmgmt_source_list_limit', 20));
|
||||
|
||||
// Test the missing translation filter.
|
||||
|
||||
// Create nodes needed to test the missing translation filter here so that
|
||||
// VBO order is not affected.
|
||||
$node_not_translated = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
$node_de = $this->drupalCreateNode(array('type' => 'page', 'language' => 'de', 'body' => array('de' => array(array()))));
|
||||
|
||||
$this->drupalGet('admin/tmgmt/sources/node');
|
||||
$this->assertText($node1->title);
|
||||
$this->assertText($node_not_translated->title);
|
||||
$this->assertText($node_de->title);
|
||||
|
||||
// Submitting the search form will not work. After the form submission the
|
||||
// page does gets redirected to url without query parameters. So we simply
|
||||
// access the page with desired query.
|
||||
$this->drupalGet('admin/tmgmt/sources/node', array('query' => array(
|
||||
'tmgmt_node_missing_translation' => 'de',
|
||||
'target_status' => 'untranslated',
|
||||
)));
|
||||
$this->assertNoText($node1->title);
|
||||
$this->assertText($node_not_translated->title);
|
||||
$this->assertNoText($node_de->title);
|
||||
|
||||
// Update the the translate flag of the translated node and test if it is
|
||||
// listed among sources with missing translation.
|
||||
db_update('node')->fields(array('translate' => 1))
|
||||
->condition('nid', $node1->nid)->execute();
|
||||
|
||||
$this->drupalGet('admin/tmgmt/sources/node', array('query' => array(
|
||||
'tmgmt_node_missing_translation' => 'de',
|
||||
'target_status' => 'outdated',
|
||||
)));
|
||||
$this->assertText($node1->title);
|
||||
$this->assertNoText($node_not_translated->title);
|
||||
$this->assertNoText($node_de->title);
|
||||
|
||||
$this->drupalGet('admin/tmgmt/sources/node', array('query' => array(
|
||||
'tmgmt_node_missing_translation' => 'de',
|
||||
'target_status' => 'untranslated_or_outdated',
|
||||
)));
|
||||
$this->assertText($node1->title);
|
||||
$this->assertText($node_not_translated->title);
|
||||
$this->assertNoText($node_de->title);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides page and form callbacks for the Translation Management Tool Node
|
||||
* Source User Interface module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Node translation overview form. This form overrides the Drupal core or i18n
|
||||
* Content Translation page with a tableselect form.
|
||||
*/
|
||||
function tmgmt_node_ui_node_form($form, &$form_state, $node, $original) {
|
||||
// Store the node in the form state so we can easily create the job in the
|
||||
// submit handler.
|
||||
$form_state['node'] = $node;
|
||||
|
||||
$form['top_actions']['#type'] = 'actions';
|
||||
$form['top_actions']['#weight'] = -10;
|
||||
tmgmt_ui_add_cart_form($form['top_actions'], $form_state, 'node', 'node', $node->nid);
|
||||
|
||||
// Inject our additional column into the header.
|
||||
array_splice($original['#header'], -1, 0, array(t('Pending Translations')));
|
||||
// Make this a tableselect form.
|
||||
$form['languages'] = array(
|
||||
'#type' => 'tableselect',
|
||||
'#header' => $original['#header'],
|
||||
'#options' => array(),
|
||||
);
|
||||
$languages = module_exists('i18n_node') ? i18n_node_language_list($node) : language_list();
|
||||
// Check if there is a job / job item that references this translation.
|
||||
$items = tmgmt_job_item_load_latest('node', 'node', $node->nid, $node->language);
|
||||
foreach ($languages as $langcode => $language) {
|
||||
if ($langcode == LANGUAGE_NONE) {
|
||||
// Never show language neutral on the overview.
|
||||
continue;
|
||||
}
|
||||
// Since the keys are numeric and in the same order we can shift one element
|
||||
// after the other from the original non-form rows.
|
||||
$option = array_shift($original['#rows']);
|
||||
if ($langcode == $node->language) {
|
||||
$additional = '<strong>' . t('Source') . '</strong>';
|
||||
// This is the source object so we disable the checkbox for this row.
|
||||
$form['languages'][$langcode] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#disabled' => TRUE,
|
||||
);
|
||||
}
|
||||
elseif (isset($items[$langcode])) {
|
||||
/** @var TMGMTJobItem $item */
|
||||
$item = $items[$langcode];
|
||||
if ($item->getJob()->isUnprocessed()) {
|
||||
$uri = $item->getJob()->uri();
|
||||
$additional = l(t('Unprocessed'), $uri['path']);
|
||||
}
|
||||
else {
|
||||
$wrapper = entity_metadata_wrapper('tmgmt_job_item', $item);
|
||||
$uri = $item->uri();
|
||||
$additional = l($wrapper->state->label(), $uri['path']);
|
||||
}
|
||||
// Disable the checkbox for this row since there is already a translation
|
||||
// in progress that has not yet been finished. This way we make sure that
|
||||
// we don't stack multiple active translations for the same item on top
|
||||
// of each other.
|
||||
$form['languages'][$langcode] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#disabled' => TRUE,
|
||||
);
|
||||
}
|
||||
else {
|
||||
// There is no translation job / job item for this target language.
|
||||
$additional = t('None');
|
||||
}
|
||||
// Inject the additional column into the array.
|
||||
array_splice($option, -1, 0, array($additional));
|
||||
// Append the current option array to the form.
|
||||
$form['languages']['#options'][$langcode] = $option;
|
||||
}
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['request'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Request translation'),
|
||||
'#submit' => array('tmgmt_node_ui_translate_form_submit'),
|
||||
'#validate' => array('tmgmt_node_ui_translate_form_validate'),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation callback for the node translation overview form.
|
||||
*/
|
||||
function tmgmt_node_ui_translate_form_validate($form, &$form_state) {
|
||||
$selected = array_filter($form_state['values']['languages']);
|
||||
if (empty($selected)) {
|
||||
form_set_error('languages', t('You have to select at least one language for requesting a translation.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback for the node translation overview form.
|
||||
*/
|
||||
function tmgmt_node_ui_translate_form_submit($form, &$form_state) {
|
||||
$node = $form_state['node'];
|
||||
$values = $form_state['values'];
|
||||
$jobs = array();
|
||||
foreach (array_keys(array_filter($values['languages'])) as $langcode) {
|
||||
// Create the job object.
|
||||
$job = tmgmt_job_create($node->language, $langcode, $GLOBALS['user']->uid);
|
||||
// Add the job item.
|
||||
$job->addItem('node', 'node', $node->nid);
|
||||
// Append this job to the array of created jobs so we can redirect the user
|
||||
// to a multistep checkout form if necessary.
|
||||
$jobs[$job->tjid] = $job;
|
||||
}
|
||||
tmgmt_ui_job_checkout_and_redirect($form_state, $jobs);
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @file
|
||||
* Contains default rules.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_default_rules_configuration().
|
||||
*/
|
||||
function tmgmt_node_ui_default_rules_configuration() {
|
||||
$data = '{ "tmgmt_node_ui_request_translation" : {
|
||||
"LABEL" : "Request translation",
|
||||
"PLUGIN" : "rule",
|
||||
"REQUIRES" : [ "tmgmt" ],
|
||||
"USES VARIABLES" : { "nodes" : { "label" : "Nodes", "type" : "list\u003Cnode\u003E" } },
|
||||
"DO" : [
|
||||
{ "tmgmt_get_first_from_node_list" : {
|
||||
"USING" : { "list" : [ "nodes" ] },
|
||||
"PROVIDE" : { "first_node" : { "first_node" : "Node" } }
|
||||
}
|
||||
},
|
||||
{ "tmgmt_rules_create_job" : {
|
||||
"USING" : { "source_language" : [ "first-node:language" ] },
|
||||
"PROVIDE" : { "job" : { "job" : "Job" } }
|
||||
}
|
||||
},
|
||||
{ "LOOP" : {
|
||||
"USING" : { "list" : [ "nodes" ] },
|
||||
"ITEM" : { "node" : "Node" },
|
||||
"DO" : [
|
||||
{ "tmgmt_rules_job_add_item" : {
|
||||
"job" : [ "job" ],
|
||||
"plugin" : "node",
|
||||
"item_type" : "node",
|
||||
"item_id" : [ "node:nid" ]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "tmgmt_rules_job_checkout" : { "job" : [ "job" ] } }
|
||||
]
|
||||
}
|
||||
}';
|
||||
$rule = rules_import($data);
|
||||
$configs[$rule->name] = $rule;
|
||||
return $configs;
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
#edit-tmgmt-node-missing-translation-wrapper .form-item-target-status,
|
||||
#edit-tmgmt-node-missing-translation-wrapper .form-item-tmgmt-node-missing-translation {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#edit-tmgmt-node-missing-translation-wrapper .form-item-target-status {
|
||||
margin: 0 0 0 55px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
top: -19px;
|
||||
}
|
||||
|
||||
#edit-tmgmt-node-missing-translation-wrapper .form-item-target-status select {
|
||||
margin-top: 9px;
|
||||
}
|
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Basic Node Source UI tests.
|
||||
*/
|
||||
class TMGMTNodeSourceUITestCase extends TMGMTEntityTestCaseUtility {
|
||||
|
||||
static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node Source UI tests',
|
||||
'description' => 'Tests the user interface for node translation sources.',
|
||||
'group' => 'Translation Management',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp(array('tmgmt_node_ui', 'block'));
|
||||
|
||||
// We need the administer blocks permission.
|
||||
$this->loginAsAdmin(array('administer blocks'));
|
||||
|
||||
$this->setEnvironment('de');
|
||||
$this->setEnvironment('fr');
|
||||
$this->setEnvironment('es');
|
||||
$this->setEnvironment('el');
|
||||
|
||||
// @todo Re-enable this when switching to testing profile.
|
||||
// Enable the main page content block for hook_page_alter() to work.
|
||||
$edit = array(
|
||||
'blocks[system_main][region]' => 'content',
|
||||
);
|
||||
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
||||
|
||||
$this->createNodeType('page', 'Page', TRANSLATION_ENABLED, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the create, submit and accept permissions.
|
||||
*/
|
||||
function testPermissions() {
|
||||
|
||||
$no_permissions = $this->drupalCreateUser();
|
||||
$this->drupalLogin($no_permissions);
|
||||
$this->drupalGet('admin/tmgmt');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Test with a user that is only allowed to create jobs.
|
||||
$create_user = $this->drupalCreateUser(array('access administration pages', 'translate content', 'create translation jobs'));
|
||||
$this->drupalLogin($create_user);
|
||||
|
||||
// Create an english source node.
|
||||
$node = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Go to the translate tab.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->clickLink('Translate');
|
||||
|
||||
// Request a translation for german.
|
||||
$edit = array(
|
||||
'languages[de]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translation'));
|
||||
$this->assertText(t('One job has been created.'));
|
||||
// Verify that we are still on the translate tab.
|
||||
$this->assertText(t('Translations of @title', array('@title' => $node->title)));
|
||||
|
||||
// The job is unprocessed, check the status flag in the source list.
|
||||
$this->drupalGet('admin/tmgmt/sources');
|
||||
$links = $this->xpath('//a[contains(@title, :title)]', array(':title' => t('Active job item: @state', array('@state' => t('Unprocessed')))));
|
||||
$attributes = $links[0]->attributes();
|
||||
// Check if the found link points to the job checkout page instead of the
|
||||
// job item review form.
|
||||
$this->assertEqual($attributes['href'], url('admin/tmgmt/jobs/1', array('query' => array('destination' => 'admin/tmgmt/sources'))));
|
||||
|
||||
$this->drupalGet('admin/tmgmt');
|
||||
$this->assertResponse(200);
|
||||
$this->assertLink(t('manage'));
|
||||
$this->assertNoLink(t('submit'));
|
||||
$this->assertNoLink(t('delete'));
|
||||
$this->assertText(t('@title', array('@title' => $node->title)));
|
||||
$this->clickLink(t('manage'));
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoRaw(t('Submit to translator'));
|
||||
|
||||
// Try to access the delete page directly.
|
||||
$this->drupalGet($this->getUrl() . '/delete');
|
||||
$this->assertResponse(403);
|
||||
|
||||
// Log in as user with only submit permission.
|
||||
$submit_user = $this->drupalCreateUser(array('access administration pages', 'translate content', 'submit translation jobs'));
|
||||
$this->drupalLogin($submit_user);
|
||||
|
||||
// Go to the translate tab, verify that there is no request translation
|
||||
// button.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->clickLink('Translate');
|
||||
$this->assertNoRaw(t('Request translation'));
|
||||
|
||||
// Go to the overview and submit the job.
|
||||
$this->drupalGet('admin/tmgmt');
|
||||
$this->assertResponse(200);
|
||||
$this->assertLink(t('submit'));
|
||||
$this->assertNoLink(t('manage'));
|
||||
$this->assertNoLink(t('delete'));
|
||||
$this->assertText(t('@title', array('@title' => $node->title)));
|
||||
|
||||
// Check VBO actions - "submit translation job" has the right to cancel
|
||||
// translation only.
|
||||
$element = $this->xpath('//select[@id=:id]/option/@value', array(':id' => 'edit-operation'));
|
||||
$options = array();
|
||||
foreach ($element as $option) {
|
||||
$options[] = (string) $option;
|
||||
}
|
||||
$this->assertTrue(in_array('rules_component::rules_tmgmt_job_abort_translation', $options));
|
||||
|
||||
// Go to the job checkout page and submit it.
|
||||
$this->clickLink('submit');
|
||||
$this->drupalPost(NULL, array(), t('Submit to translator'));
|
||||
// After submit the redirect goes back to the job overview.
|
||||
$this->assertUrl('admin/tmgmt');
|
||||
|
||||
// Make sure that the job is active now.
|
||||
$this->assertText(t('Active'));
|
||||
// Click abort link and check if we are at the job abort confirm page.
|
||||
$this->clickLink(t('abort'));
|
||||
$this->assertText(t('This will send a request to the translator to abort the job. After the action the job translation process will be aborted and only remaining action will be resubmitting it.'));
|
||||
// Return back to job overview and test the manage link.
|
||||
$this->drupalGet('admin/tmgmt');
|
||||
$this->clickLink(t('manage'));
|
||||
$this->assertText(t('Needs review'));
|
||||
$this->assertNoLink(t('review'));
|
||||
|
||||
// Now log in as user with only accept permission and review the job.
|
||||
$accept_user = $this->drupalCreateUser(array('access administration pages', 'accept translation jobs'));
|
||||
$this->drupalLogin($accept_user);
|
||||
|
||||
$this->drupalGet('admin/tmgmt');
|
||||
|
||||
// Check VBO actions - "accept translation jobs" has the right to accept
|
||||
// translation only.
|
||||
$element = $this->xpath('//select[@id=:id]/option/@value', array(':id' => 'edit-operation'));
|
||||
$options = array();
|
||||
foreach ($element as $option) {
|
||||
$options[] = (string) $option;
|
||||
}
|
||||
$this->assertTrue(in_array('rules_component::rules_tmgmt_job_accept_translation', $options));
|
||||
|
||||
$this->clickLink('manage');
|
||||
$this->clickLink('review');
|
||||
|
||||
$this->drupalPost(NULL, array(), '✓');
|
||||
// Verify that the accepted character is shown.
|
||||
$this->assertText('☑');
|
||||
$this->drupalPost(NULL, array(), t('Save as completed'));
|
||||
$this->assertText(t('Accepted'));
|
||||
$this->assertText('1/0/0');
|
||||
|
||||
$create_user = $this->loginAsAdmin();
|
||||
$this->drupalLogin($create_user);
|
||||
|
||||
$this->drupalGet('admin/tmgmt');
|
||||
// Check VBO actions - "administer tmgmt" has rights for all actions.
|
||||
$element = $this->xpath('//select[@id=:id]/option/@value', array(':id' => 'edit-operation'));
|
||||
$options = array();
|
||||
foreach ($element as $option) {
|
||||
$options[] = (string) $option;
|
||||
}
|
||||
$this->assertTrue(in_array('rules_component::rules_tmgmt_job_accept_translation', $options));
|
||||
$this->assertTrue(in_array('rules_component::rules_tmgmt_job_abort_translation', $options));
|
||||
$this->assertTrue(in_array('rules_component::rules_tmgmt_job_delete', $options));
|
||||
|
||||
// Go to the translate tab, verify that there is no request translation
|
||||
// button.
|
||||
//$this->drupalGet('node/' . $node->nid);
|
||||
//$this->clickLink('Translate');
|
||||
//$this->assertNoRaw(t('Request translation'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the translate tab for a single checkout.
|
||||
*/
|
||||
function testTranslateTabSingleCheckout() {
|
||||
|
||||
// Create a user that is allowed to translate nodes.
|
||||
$translater = $this->drupalCreateUser(array('translate content', 'create translation jobs', 'submit translation jobs', 'accept translation jobs'));
|
||||
$this->drupalLogin($translater);
|
||||
|
||||
// Create an english source node.
|
||||
$node = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Go to the translate tab.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->clickLink('Translate');
|
||||
|
||||
// Assert some basic strings on that page.
|
||||
$this->assertText(t('Translations of @title', array('@title' => $node->title)));
|
||||
$this->assertText(t('Pending Translations'));
|
||||
|
||||
// Request a translation for german.
|
||||
$edit = array(
|
||||
'languages[de]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translation'));
|
||||
|
||||
// Verify that we are on the translate tab.
|
||||
$this->assertText(t('One job needs to be checked out.'));
|
||||
$this->assertText($node->title);
|
||||
|
||||
// Go to the translate tab and check if the pending translation label is
|
||||
// "Unprocessed" and links to the job checkout page.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate');
|
||||
$this->assertLink(t('Unprocessed'));
|
||||
$this->clickLink(t('Unprocessed'));
|
||||
|
||||
// Submit.
|
||||
$this->drupalPost(NULL, array(), t('Submit to translator'));
|
||||
|
||||
// Make sure that we're back on the translate tab.
|
||||
$this->assertEqual(url('node/' . $node->nid . '/translate', array('absolute' => TRUE)), $this->getUrl());
|
||||
$this->assertText(t('Test translation created.'));
|
||||
$this->assertText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node->title, '@language' => t('German'))));
|
||||
|
||||
// Review.
|
||||
$this->clickLink(t('Needs review'));
|
||||
|
||||
// @todo Review job throuh the UI.
|
||||
$items = tmgmt_job_item_load_latest('node', 'node', $node->nid, 'en');
|
||||
$items['de']->acceptTranslation();
|
||||
|
||||
// German node should now be listed and be clickable.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate');
|
||||
$this->clickLink('de_' . $node->title);
|
||||
|
||||
// Test that the destination query argument does not break the redirect
|
||||
// and we are redirected back to the correct page.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate', array('query' => array('destination' => 'node')));
|
||||
|
||||
// Request a spanish translation.
|
||||
$edit = array(
|
||||
'languages[es]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translation'));
|
||||
|
||||
// Verify that we are on the checkout page.
|
||||
$this->assertText(t('One job needs to be checked out.'));
|
||||
$this->assertText($node->title);
|
||||
$this->drupalPost(NULL, array(), t('Submit to translator'));
|
||||
|
||||
// Make sure that we're back on the originally defined destination URL.
|
||||
$this->assertEqual(url('node', array('absolute' => TRUE)), $this->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the translate tab for a single checkout.
|
||||
*/
|
||||
function testTranslateTabMultipeCheckout() {
|
||||
// Create a user that is allowed to translate nodes.
|
||||
$translater = $this->drupalCreateUser(array('translate content', 'create translation jobs', 'submit translation jobs', 'accept translation jobs'));
|
||||
$this->drupalLogin($translater);
|
||||
|
||||
// Create an english source node.
|
||||
$node = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Go to the translate tab.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->clickLink('Translate');
|
||||
|
||||
// Assert some basic strings on that page.
|
||||
$this->assertText(t('Translations of @title', array('@title' => $node->title)));
|
||||
$this->assertText(t('Pending Translations'));
|
||||
|
||||
// Request a translation for german.
|
||||
$edit = array(
|
||||
'languages[de]' => TRUE,
|
||||
'languages[es]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translation'));
|
||||
|
||||
// Verify that we are on the translate tab.
|
||||
$this->assertText(t('2 jobs need to be checked out.'));
|
||||
|
||||
// Submit all jobs.
|
||||
$this->assertText($node->title);
|
||||
$this->drupalPost(NULL, array(), t('Submit to translator and continue'));
|
||||
$this->assertText($node->title);
|
||||
$this->drupalPost(NULL, array(), t('Submit to translator'));
|
||||
|
||||
// Make sure that we're back on the translate tab.
|
||||
$this->assertEqual(url('node/' . $node->nid . '/translate', array('absolute' => TRUE)), $this->getUrl());
|
||||
$this->assertText(t('Test translation created.'));
|
||||
$this->assertText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node->title, '@language' => t('Spanish'))));
|
||||
|
||||
// Review.
|
||||
$this->clickLink(t('Needs review'));
|
||||
|
||||
// @todo Review job throuh the UI.
|
||||
$items = tmgmt_job_item_load_latest('node', 'node', $node->nid, 'en');
|
||||
$items['de']->acceptTranslation();
|
||||
$items['es']->acceptTranslation();
|
||||
|
||||
// Translated nodes should now be listed and be clickable.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate');
|
||||
$this->clickLink('de_' . $node->title);
|
||||
|
||||
// Translated nodes should now be listed and be clickable.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate');
|
||||
$this->clickLink('es_' . $node->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the translate tab for a single checkout.
|
||||
*/
|
||||
function testTranslateTabAutomatedCheckout() {
|
||||
// Hide settings on the test translator.
|
||||
$default_translator = tmgmt_translator_load('test_translator');
|
||||
$default_translator->settings = array(
|
||||
'expose_settings' => FALSE,
|
||||
);
|
||||
$default_translator->save();
|
||||
|
||||
// Create a user that is allowed to translate nodes.
|
||||
$translater = $this->drupalCreateUser(array('translate content', 'create translation jobs', 'submit translation jobs', 'accept translation jobs'));
|
||||
$this->drupalLogin($translater);
|
||||
|
||||
// Create an english source node.
|
||||
$node = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Go to the translate tab.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->clickLink('Translate');
|
||||
|
||||
// Assert some basic strings on that page.
|
||||
$this->assertText(t('Translations of @title', array('@title' => $node->title)));
|
||||
$this->assertText(t('Pending Translations'));
|
||||
|
||||
// Request a translation for german.
|
||||
$edit = array(
|
||||
'languages[de]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translation'));
|
||||
|
||||
// Verify that we are on the translate tab.
|
||||
$this->assertNoText(t('One job needs to be checked out.'));
|
||||
|
||||
// Make sure that we're back on the translate tab.
|
||||
$this->assertEqual(url('node/' . $node->nid . '/translate', array('absolute' => TRUE)), $this->getUrl());
|
||||
$this->assertText(t('Test translation created.'));
|
||||
$this->assertText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node->title, '@language' => t('German'))));
|
||||
|
||||
// Review.
|
||||
$this->clickLink(t('Needs review'));
|
||||
|
||||
// @todo Review job throuh the UI.
|
||||
$items = tmgmt_job_item_load_latest('node', 'node', $node->nid, 'en');
|
||||
$items['de']->acceptTranslation();
|
||||
|
||||
// German node should now be listed and be clickable.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate');
|
||||
$this->clickLink('de_' . $node->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the translate tab for a single checkout.
|
||||
*/
|
||||
function testTranslateTabDisabledQuickCheckout() {
|
||||
variable_set('tmgmt_quick_checkout', FALSE);
|
||||
|
||||
// Hide settings on the test translator.
|
||||
$default_translator = tmgmt_translator_load('test_translator');
|
||||
$default_translator->settings = array(
|
||||
'expose_settings' => FALSE,
|
||||
);
|
||||
$default_translator->save();
|
||||
|
||||
// Create a user that is allowed to translate nodes.
|
||||
$translater = $this->drupalCreateUser(array('translate content', 'create translation jobs', 'submit translation jobs', 'accept translation jobs'));
|
||||
$this->drupalLogin($translater);
|
||||
|
||||
// Create an english source node.
|
||||
$node = $this->drupalCreateNode(array('type' => 'page', 'language' => 'en', 'body' => array('en' => array(array()))));
|
||||
|
||||
// Go to the translate tab.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->clickLink('Translate');
|
||||
|
||||
// Assert some basic strings on that page.
|
||||
$this->assertText(t('Translations of @title', array('@title' => $node->title)));
|
||||
$this->assertText(t('Pending Translations'));
|
||||
|
||||
// Request a translation for german.
|
||||
$edit = array(
|
||||
'languages[de]' => TRUE,
|
||||
);
|
||||
$this->drupalPost(NULL, $edit, t('Request translation'));
|
||||
|
||||
// Verify that we are on the translate tab.
|
||||
$this->assertText(t('One job needs to be checked out.'));
|
||||
$this->assertText($node->title);
|
||||
|
||||
// Submit.
|
||||
$this->drupalPost(NULL, array(), t('Submit to translator'));
|
||||
|
||||
// Make sure that we're back on the translate tab.
|
||||
$this->assertEqual(url('node/' . $node->nid . '/translate', array('absolute' => TRUE)), $this->getUrl());
|
||||
$this->assertText(t('Test translation created.'));
|
||||
$this->assertText(t('The translation of @title to @language is finished and can now be reviewed.', array('@title' => $node->title, '@language' => t('German'))));
|
||||
|
||||
// Review.
|
||||
$this->clickLink(t('Needs review'));
|
||||
|
||||
// @todo Review job throuh the UI.
|
||||
$items = tmgmt_job_item_load_latest('node', 'node', $node->nid, 'en');
|
||||
$items['de']->acceptTranslation();
|
||||
|
||||
// German node should now be listed and be clickable.
|
||||
$this->drupalGet('node/' . $node->nid . '/translate');
|
||||
$this->clickLink('de_' . $node->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the node source specific cart functionality.
|
||||
*/
|
||||
function testCart() {
|
||||
$nodes = array();
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
$nodes[] = $this->createNode('page');
|
||||
}
|
||||
|
||||
$this->loginAsAdmin(array_merge($this->translator_permissions, array('translate content')));
|
||||
|
||||
// Test the source overview.
|
||||
$this->drupalPost('admin/tmgmt/sources/node', array(
|
||||
'views_bulk_operations[0]' => TRUE,
|
||||
'views_bulk_operations[1]' => TRUE,
|
||||
), t('Add to cart'));
|
||||
$this->drupalGet('admin/tmgmt/cart');
|
||||
$this->assertText($nodes[0]->title);
|
||||
$this->assertText($nodes[1]->title);
|
||||
|
||||
// Test the translate tab.
|
||||
$this->drupalGet('node/' . $nodes[3]->nid . '/translate');
|
||||
$this->assertRaw(t('There are @count items in the <a href="@url">translation cart</a>.',
|
||||
array('@count' => 2, '@url' => url('admin/tmgmt/cart'))));
|
||||
|
||||
$this->drupalPost(NULL, array(), t('Add to cart'));
|
||||
$this->assertRaw(t('@count content source was added into the <a href="@url">cart</a>.', array('@count' => 1, '@url' => url('admin/tmgmt/cart'))));
|
||||
$this->assertRaw(t('There are @count items in the <a href="@url">translation cart</a> including the current item.',
|
||||
array('@count' => 3, '@url' => url('admin/tmgmt/cart'))));
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Field handler which shows all jobs which contains a node.
|
||||
*
|
||||
* @TODO: This could probably abstracted into a more generic handler,
|
||||
* or even api function.
|
||||
*/
|
||||
class tmgmt_node_ui_handler_field_jobs extends views_handler_field_prerender_list {
|
||||
function pre_render(&$values) {
|
||||
$nids = array();
|
||||
foreach ($values as $row) {
|
||||
$nid = $this->get_value($row);
|
||||
$nids[] = $nid;
|
||||
}
|
||||
|
||||
$select = db_select('tmgmt_job', 'tj');
|
||||
$select->join('tmgmt_job_item', 'tji', "tj.id = %alias.tjid");
|
||||
$select->join('node', 'n', "tji.item_type = 'node' AND tji.plugin = 'node' AND tji.item_id = node.nid");
|
||||
$select->addField('n', 'nid');
|
||||
$select->addExpression('MAX(tj.id)');
|
||||
|
||||
dpq($select);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Field handler to display the status of all languages.
|
||||
*
|
||||
* @ingroup views_field_handlers
|
||||
*/
|
||||
class tmgmt_node_handler_field_translation_language_status extends views_handler_field {
|
||||
|
||||
/**
|
||||
* @var views_plugin_query_default
|
||||
*/
|
||||
var $query;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $language_items;
|
||||
|
||||
/**
|
||||
* Array of active job items.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $active_job_items = array();
|
||||
|
||||
function init(&$view, &$options) {
|
||||
parent::init($view, $options);
|
||||
$this->view->init_style();
|
||||
$this->additional_fields['nid'] = 'nid';
|
||||
|
||||
/**
|
||||
* Dynamically add new fields so they are used
|
||||
*/
|
||||
$languages = language_list('language');
|
||||
foreach ($languages as $langcode => $lang_info) {
|
||||
$handler = views_get_handler($this->table, $this->field . '_single', 'field');
|
||||
if ($handler) {
|
||||
$id = $options['id'] . '_single_' . $langcode;
|
||||
$this->view->display_handler->handlers['field'][$id] = $handler;
|
||||
$info = array(
|
||||
'id' => $id,
|
||||
'table' => $this->table,
|
||||
'field' => $this->field . '_single',
|
||||
'label' => $lang_info->name,
|
||||
);
|
||||
$handler->langcode = $langcode;
|
||||
$handler->main_field = $options['id'];
|
||||
$handler->init($this->view, $info);
|
||||
$this->language_handlers[$langcode] = $handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pre_render(&$values) {
|
||||
$nids = array();
|
||||
foreach ($values as $value) {
|
||||
$tnid = $this->get_value($value);
|
||||
$tnid = !empty($tnid) ? $tnid : $this->get_value($value, 'nid');
|
||||
$this->active_job_items[$tnid] = tmgmt_job_item_load_latest('node', 'node', $tnid, $value->node_language);
|
||||
$nids[] = $tnid;
|
||||
}
|
||||
if ($nodes = node_load_multiple($nids)) {
|
||||
$result = db_select('node', 'n')
|
||||
->fields('n', array('tnid', 'language', 'translate'))
|
||||
->condition('tnid', $nids)
|
||||
->execute()
|
||||
->fetchAll();
|
||||
|
||||
$this->language_items = array();
|
||||
foreach ($result as $tnode) {
|
||||
// The translate flag is set if the translation node is outdated, revert
|
||||
// to have FALSE for outdated translations.
|
||||
$this->language_items[$tnode->tnid][$tnode->language] = !$tnode->translate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @todo What is this?
|
||||
*/
|
||||
class tmgmt_node_handler_field_translation_language_status_single extends views_handler_field {
|
||||
|
||||
/**
|
||||
* @var tmgmt_node_handler_field_translation_language_status
|
||||
*/
|
||||
var $main_handler;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
var $langcode;
|
||||
|
||||
function init(&$view, &$options) {
|
||||
parent::init($view, $options);
|
||||
$this->additional_fields['nid'] = array(
|
||||
'table' => 'node',
|
||||
'field' => 'nid',
|
||||
);
|
||||
}
|
||||
|
||||
function render($values) {
|
||||
$nid = $values->nid;
|
||||
$langcode = $this->langcode;
|
||||
|
||||
// Check if this is the source language.
|
||||
if ($langcode == $values->node_language) {
|
||||
$translation_status = 'original';
|
||||
}
|
||||
// Check if there is a translation.
|
||||
elseif (!isset($this->view->field[$this->main_field]->language_items[$nid][$langcode])) {
|
||||
$translation_status = 'missing';
|
||||
}
|
||||
// Check if the translation is outdated.
|
||||
elseif (!$this->view->field[$this->main_field]->language_items[$nid][$langcode]) {
|
||||
$translation_status = 'outofdate';
|
||||
}
|
||||
else {
|
||||
$translation_status = 'current';
|
||||
}
|
||||
|
||||
$job_item = NULL;
|
||||
|
||||
if (isset($this->view->field[$this->main_field]->active_job_items[$nid][$langcode])) {
|
||||
$job_item = $this->view->field[$this->main_field]->active_job_items[$nid][$langcode];
|
||||
}
|
||||
|
||||
return theme('tmgmt_ui_translation_language_status_single', array(
|
||||
'translation_status' => $translation_status,
|
||||
'job_item' => $job_item,
|
||||
));
|
||||
}
|
||||
|
||||
function query() {
|
||||
$this->add_additional_fields();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of tmgmt_node_handler_filter_missing_translation.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Filter by language.
|
||||
*
|
||||
* @ingroup views_filter_handlers
|
||||
*/
|
||||
class tmgmt_node_handler_filter_missing_translation extends views_handler_filter {
|
||||
|
||||
/**
|
||||
* The target status to use for the query.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $target_status = 'untranslated_or_outdated';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function query() {
|
||||
$this->ensure_my_table();
|
||||
|
||||
// Don't do anything if no language was selected.
|
||||
if (!$this->value) {
|
||||
return;
|
||||
}
|
||||
|
||||
$join = new views_join();
|
||||
$join->definition['left_table'] = $this->table_alias;
|
||||
$join->definition['left_field'] = $this->real_field;
|
||||
$join->definition['table'] = 'node';
|
||||
$join->definition['field'] = 'tnid';
|
||||
$join->definition['type'] = 'LEFT';
|
||||
$join->construct();
|
||||
|
||||
$join->extra = array(array(
|
||||
'field' => 'language',
|
||||
'value' => $this->value,
|
||||
));
|
||||
|
||||
$table_alias = $this->query->add_table('node', $this->relationship, $join);
|
||||
|
||||
$this->query->add_where_expression($this->options['group'], "{$this->table_alias}.language != :language", array(':language' => $this->value));
|
||||
|
||||
if ($this->target_status == 'untranslated_or_outdated') {
|
||||
$this->query->add_where_expression($this->options['group'], "($table_alias.nid IS NULL OR {$this->table_alias}.translate = 1)");
|
||||
}
|
||||
elseif ($this->target_status == 'outdated') {
|
||||
$this->query->add_where_expression($this->options['group'], "{$this->table_alias}.translate = 1");
|
||||
}
|
||||
elseif ($this->target_status == 'untranslated') {
|
||||
$this->query->add_where_expression($this->options['group'], "$table_alias.nid IS NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function value_form(&$form, &$form_state) {
|
||||
$options = array();
|
||||
foreach (language_list() as $langcode => $language) {
|
||||
$options[$langcode] = $language->name;
|
||||
}
|
||||
|
||||
$identifier = $this->options['expose']['identifier'];
|
||||
|
||||
$form['value'][$identifier] = array(
|
||||
'#type' => 'select',
|
||||
'#options' => $options,
|
||||
'#empty_option' => t('Any'),
|
||||
'#id' => 'tmgmt_node_missing_target_language',
|
||||
'#element_validate' => array('tmgmt_node_views_exposed_target_language_validate'),
|
||||
);
|
||||
// Attach css to style the target_status element inline.
|
||||
$form['#attached']['css'][] = drupal_get_path('module', 'tmgmt_node_ui') . '/tmgmt_node_ui.source_overview.css';
|
||||
$form['value']['target_status'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Target status'),
|
||||
'#options' => array(
|
||||
'untranslated_or_outdated' => t('Untranslated or outdated'),
|
||||
'untranslated' => t('Untranslated'),
|
||||
'outdated' => t('Outdated'),
|
||||
),
|
||||
'#states' => array(
|
||||
'invisible' => array(
|
||||
':input[id="tmgmt_node_missing_target_language"]' => array('value' => ''),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function accept_exposed_input($input) {
|
||||
$return = parent::accept_exposed_input($input);
|
||||
if ($return && isset($input['target_status'])) {
|
||||
$this->target_status = $input['target_status'];
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains tmgmt_node_ui_handler_filter_node_translatable_types.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Limits node types to those enabled for content translation.
|
||||
*/
|
||||
class tmgmt_node_ui_handler_filter_node_translatable_types extends views_handler_filter {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function query() {
|
||||
$this->ensure_my_table();
|
||||
$valid_types = array_keys(tmgmt_source_translatable_item_types('node'));
|
||||
if ($valid_types) {
|
||||
$this->query->add_where($this->options['group'], "$this->table_alias.$this->real_field", array_values($valid_types), 'IN');
|
||||
}
|
||||
else {
|
||||
// There are no valid translatable node types, do not return any results.
|
||||
$this->query->add_where_expression($this->options['group'], '1 = 0');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
function admin_summary() { }
|
||||
}
|
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Please supply a file description.
|
||||
*/
|
||||
|
||||
class TMGMTNodeSourceViewsController extends TMGMTDefaultSourceViewsController {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function views_data() {
|
||||
// Relationships between job items and nodes.
|
||||
$data['tmgmt_job_item']['job_item_to_node'] = array(
|
||||
'title' => t('Content'),
|
||||
'help' => t('Content that is associated with this job item.'),
|
||||
'real field' => 'item_id',
|
||||
'relationship' => array(
|
||||
'label' => t('Content'),
|
||||
'base' => 'node',
|
||||
'base field' => 'vid',
|
||||
'relationship field' => 'item_id',
|
||||
'extra' => array(
|
||||
array(
|
||||
'table' => 'tmgmt_job_item',
|
||||
'field' => 'item_type',
|
||||
'operator' => '=',
|
||||
'value' => 'node',
|
||||
),
|
||||
array(
|
||||
'table' => 'tmgmt_job_item',
|
||||
'field' => 'plugin',
|
||||
'operator' => '=',
|
||||
'value' => 'node',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$data['node']['node_to_job_item'] = array(
|
||||
'title' => t('Translation job item'),
|
||||
'help' => t('Job items of this node.'),
|
||||
'relationship' => array(
|
||||
'real field' => 'vid',
|
||||
'label' => t('Translation job item'),
|
||||
'base' => 'tmgmt_job_item',
|
||||
'base field' => 'item_id',
|
||||
'extra' => array(
|
||||
array(
|
||||
'field' => 'item_type',
|
||||
'operator' => '=',
|
||||
'value' => 'node',
|
||||
),
|
||||
array(
|
||||
'field' => 'plugin',
|
||||
'operator' => '=',
|
||||
'value' => 'node',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$data['node']['tmgmt_translatable_types_all'] = array(
|
||||
'group' => t('Content translation'),
|
||||
'title' => t('All translatable types'),
|
||||
'help' => t('Enforces that only nodes from node types which are translatable are '),
|
||||
'filter' => array(
|
||||
'handler' => 'tmgmt_node_ui_handler_filter_node_translatable_types',
|
||||
'real field' => 'type',
|
||||
),
|
||||
);
|
||||
$data['node']['tmgmt_node_missing_translation'] = array(
|
||||
'group' => t('Content translation'),
|
||||
'title' => t('Missing translation'),
|
||||
'help' => t('Enables the search for nodes with missing translation ofr the specified language'),
|
||||
'filter' => array(
|
||||
'handler' => 'tmgmt_node_handler_filter_missing_translation',
|
||||
'real field' => 'nid',
|
||||
),
|
||||
);
|
||||
$data['node']['tmgmt_jobs'] = array(
|
||||
'title' => t('Translation jobs'),
|
||||
'help' => t('Shows all translation jobs which contains this node'),
|
||||
'field' => array(
|
||||
'handler' => 'tmgmt_node_ui_handler_field_jobs',
|
||||
'real field' => 'nid',
|
||||
),
|
||||
);
|
||||
$data['node']['tmgmt_job_item'] = array(
|
||||
'title' => t('Job item'),
|
||||
'real field' => 'vid',
|
||||
'relationship' => array(
|
||||
'title' => t('Translation job item'),
|
||||
'label' => t('Translation job item'),
|
||||
'base' => 'tmgmt_job_item',
|
||||
'base field' => 'item_id',
|
||||
'extra' => array(
|
||||
array(
|
||||
'field' => 'item_type',
|
||||
'operator' => '=',
|
||||
'value' => 'node',
|
||||
),
|
||||
array(
|
||||
'field' => 'plugin',
|
||||
'operator' => '=',
|
||||
'value' => 'node',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$data['node']['translation_language_status'] = array(
|
||||
'group' => t('Content translation'),
|
||||
'title' => t('All translation languages'),
|
||||
'help' => t('Display all target lanuages.'),
|
||||
'real field' => 'tnid',
|
||||
'field' => array(
|
||||
'handler' => 'tmgmt_node_handler_field_translation_language_status',
|
||||
),
|
||||
);
|
||||
$data['node']['translation_language_status_single'] = array(
|
||||
'title' => t('All translation languages (single)'),
|
||||
'help' => t("Don't use this in the user interface."),
|
||||
'field' => array(
|
||||
'handler' => 'tmgmt_node_handler_field_translation_language_status_single',
|
||||
),
|
||||
);
|
||||
$data['node']['tmgmt_translatable_types_select'] = array(
|
||||
'group' => t('Content translation'),
|
||||
'title' => t('Select translatable content types'),
|
||||
'help' => t('Allows to filter on specific translatable types.'),
|
||||
'filter' => array(
|
||||
'handler' => 'views_handler_filter_in_operator',
|
||||
'real field' => 'type',
|
||||
'options callback' => 'tmgmt_source_translatable_item_types',
|
||||
'options arguments' => array($this->pluginType),
|
||||
),
|
||||
);
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
$view = new view();
|
||||
$view->name = 'tmgmt_node_source_overview';
|
||||
$view->description = 'Node source overview for bulk operations.';
|
||||
$view->tag = 'Translation Management';
|
||||
$view->base_table = 'node';
|
||||
$view->human_name = 'Node Source Overview';
|
||||
$view->core = 7;
|
||||
$view->api_version = '3.0';
|
||||
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
|
||||
|
||||
/* Display: Master */
|
||||
$handler = $view->new_display('default', 'Master', 'default');
|
||||
$handler->display->display_options['title'] = 'Content overview';
|
||||
$handler->display->display_options['use_more_always'] = FALSE;
|
||||
$handler->display->display_options['group_by'] = TRUE;
|
||||
$handler->display->display_options['access']['type'] = 'perm';
|
||||
$handler->display->display_options['access']['perm'] = 'create translation jobs';
|
||||
$handler->display->display_options['cache']['type'] = 'none';
|
||||
$handler->display->display_options['query']['type'] = 'views_query';
|
||||
$handler->display->display_options['query']['options']['query_comment'] = FALSE;
|
||||
$handler->display->display_options['exposed_form']['type'] = 'basic';
|
||||
$handler->display->display_options['exposed_form']['options']['submit_button'] = 'Search';
|
||||
$handler->display->display_options['pager']['type'] = 'full';
|
||||
$handler->display->display_options['pager']['options']['items_per_page'] = variable_get('tmgmt_source_list_limit', 20);
|
||||
$handler->display->display_options['pager']['options']['offset'] = '0';
|
||||
$handler->display->display_options['pager']['options']['id'] = '0';
|
||||
$handler->display->display_options['pager']['options']['quantity'] = '9';
|
||||
$handler->display->display_options['style_plugin'] = 'table';
|
||||
$handler->display->display_options['style_options']['columns'] = array(
|
||||
'title' => 'title',
|
||||
);
|
||||
$handler->display->display_options['style_options']['default'] = '-1';
|
||||
$handler->display->display_options['style_options']['info'] = array(
|
||||
'title' => array(
|
||||
'sortable' => 0,
|
||||
'default_sort_order' => 'asc',
|
||||
'align' => '',
|
||||
'separator' => '',
|
||||
'empty_column' => 0,
|
||||
),
|
||||
);
|
||||
/* No results behavior: Global: Text area */
|
||||
$handler->display->display_options['empty']['area']['id'] = 'area';
|
||||
$handler->display->display_options['empty']['area']['table'] = 'views';
|
||||
$handler->display->display_options['empty']['area']['field'] = 'area';
|
||||
$handler->display->display_options['empty']['area']['content'] = 'There are no nodes that match the specified filter criteria.';
|
||||
$handler->display->display_options['empty']['area']['format'] = 'filtered_html';
|
||||
/* Relationship: User */
|
||||
$handler->display->display_options['relationships']['uid']['id'] = 'uid';
|
||||
$handler->display->display_options['relationships']['uid']['table'] = 'node';
|
||||
$handler->display->display_options['relationships']['uid']['field'] = 'uid';
|
||||
$handler->display->display_options['relationships']['uid']['ui_name'] = 'User';
|
||||
$handler->display->display_options['relationships']['uid']['label'] = 'User';
|
||||
/* Field: Bulk operations */
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['id'] = 'views_bulk_operations';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['table'] = 'node';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['field'] = 'views_bulk_operations';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['ui_name'] = 'Bulk operations';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['label'] = '<!--views-bulk-operations-select-all-->';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['element_label_colon'] = FALSE;
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['display_type'] = '1';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['enable_select_all_pages'] = 1;
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['force_single'] = 0;
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['vbo_settings']['entity_load_capacity'] = '10';
|
||||
$handler->display->display_options['fields']['views_bulk_operations']['vbo_operations'] = array(
|
||||
'rules_component::tmgmt_node_ui_tmgmt_nodes_add_items_to_cart' => array(
|
||||
'selected' => 1,
|
||||
'skip_confirmation' => 1,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_assign_owner_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::views_bulk_operations_delete_item' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::views_bulk_operations_script_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_make_sticky_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_make_unsticky_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::views_bulk_operations_modify_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
'settings' => array(
|
||||
'show_all_tokens' => 1,
|
||||
'display_values' => array(
|
||||
'_all_' => '_all_',
|
||||
),
|
||||
),
|
||||
),
|
||||
'action::views_bulk_operations_argument_selector_action' => array(
|
||||
'selected' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
'settings' => array(
|
||||
'url' => '',
|
||||
),
|
||||
),
|
||||
'action::node_promote_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_publish_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_unpromote_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'rules_component::tmgmt_node_ui_request_translation' => array(
|
||||
'selected' => 0,
|
||||
'skip_confirmation' => 1,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::tmgmt_node_ui_checkout_multiple_action' => array(
|
||||
'selected' => 1,
|
||||
'skip_confirmation' => 1,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_save_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::system_send_email_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_unpublish_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
'action::node_unpublish_by_keyword_action' => array(
|
||||
'selected' => 0,
|
||||
'postpone_processing' => 0,
|
||||
'skip_confirmation' => 0,
|
||||
'override_label' => 0,
|
||||
'label' => '',
|
||||
),
|
||||
);
|
||||
/* Field: Title */
|
||||
$handler->display->display_options['fields']['title']['id'] = 'title';
|
||||
$handler->display->display_options['fields']['title']['table'] = 'node';
|
||||
$handler->display->display_options['fields']['title']['field'] = 'title';
|
||||
$handler->display->display_options['fields']['title']['ui_name'] = 'Title';
|
||||
$handler->display->display_options['fields']['title']['label'] = 'Title (in source language)';
|
||||
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
|
||||
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
|
||||
/* Field: Type */
|
||||
$handler->display->display_options['fields']['type']['id'] = 'type';
|
||||
$handler->display->display_options['fields']['type']['table'] = 'node';
|
||||
$handler->display->display_options['fields']['type']['field'] = 'type';
|
||||
$handler->display->display_options['fields']['type']['ui_name'] = 'Type';
|
||||
/* Field: All translation languages */
|
||||
$handler->display->display_options['fields']['translation_language_status_1']['id'] = 'translation_language_status_1';
|
||||
$handler->display->display_options['fields']['translation_language_status_1']['table'] = 'node';
|
||||
$handler->display->display_options['fields']['translation_language_status_1']['field'] = 'translation_language_status';
|
||||
$handler->display->display_options['fields']['translation_language_status_1']['ui_name'] = 'All translation languages';
|
||||
$handler->display->display_options['fields']['translation_language_status_1']['exclude'] = TRUE;
|
||||
/* Field: Author */
|
||||
$handler->display->display_options['fields']['name']['id'] = 'name';
|
||||
$handler->display->display_options['fields']['name']['table'] = 'users';
|
||||
$handler->display->display_options['fields']['name']['field'] = 'name';
|
||||
$handler->display->display_options['fields']['name']['relationship'] = 'uid';
|
||||
$handler->display->display_options['fields']['name']['ui_name'] = 'Author';
|
||||
$handler->display->display_options['fields']['name']['label'] = 'Author';
|
||||
/* Field: Updated date */
|
||||
$handler->display->display_options['fields']['changed']['id'] = 'changed';
|
||||
$handler->display->display_options['fields']['changed']['table'] = 'node';
|
||||
$handler->display->display_options['fields']['changed']['field'] = 'changed';
|
||||
$handler->display->display_options['fields']['changed']['ui_name'] = 'Updated date';
|
||||
$handler->display->display_options['fields']['changed']['date_format'] = 'short';
|
||||
/* Sort criterion: Post date */
|
||||
$handler->display->display_options['sorts']['created']['id'] = 'created';
|
||||
$handler->display->display_options['sorts']['created']['table'] = 'node';
|
||||
$handler->display->display_options['sorts']['created']['field'] = 'created';
|
||||
$handler->display->display_options['sorts']['created']['ui_name'] = 'Post date';
|
||||
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
|
||||
/* Filter criterion: Content: Title */
|
||||
$handler->display->display_options['filters']['title']['id'] = 'title';
|
||||
$handler->display->display_options['filters']['title']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['title']['field'] = 'title';
|
||||
$handler->display->display_options['filters']['title']['operator'] = 'word';
|
||||
$handler->display->display_options['filters']['title']['group'] = 1;
|
||||
$handler->display->display_options['filters']['title']['exposed'] = TRUE;
|
||||
$handler->display->display_options['filters']['title']['expose']['operator_id'] = 'title_op';
|
||||
$handler->display->display_options['filters']['title']['expose']['label'] = 'Node title';
|
||||
$handler->display->display_options['filters']['title']['expose']['operator'] = 'title_op';
|
||||
$handler->display->display_options['filters']['title']['expose']['identifier'] = 'title';
|
||||
/* Filter criterion: Published */
|
||||
$handler->display->display_options['filters']['status']['id'] = 'status';
|
||||
$handler->display->display_options['filters']['status']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['status']['field'] = 'status';
|
||||
$handler->display->display_options['filters']['status']['ui_name'] = 'Published';
|
||||
$handler->display->display_options['filters']['status']['value'] = '1';
|
||||
$handler->display->display_options['filters']['status']['group'] = 1;
|
||||
$handler->display->display_options['filters']['status']['exposed'] = TRUE;
|
||||
$handler->display->display_options['filters']['status']['expose']['operator_id'] = '';
|
||||
$handler->display->display_options['filters']['status']['expose']['label'] = 'Published';
|
||||
$handler->display->display_options['filters']['status']['expose']['operator'] = 'status_op';
|
||||
$handler->display->display_options['filters']['status']['expose']['identifier'] = 'status';
|
||||
$handler->display->display_options['filters']['status']['expose']['required'] = TRUE;
|
||||
/* Filter criterion: Source translation */
|
||||
$handler->display->display_options['filters']['source_translation']['id'] = 'source_translation';
|
||||
$handler->display->display_options['filters']['source_translation']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['source_translation']['field'] = 'source_translation';
|
||||
$handler->display->display_options['filters']['source_translation']['ui_name'] = 'Source translation';
|
||||
$handler->display->display_options['filters']['source_translation']['operator'] = '1';
|
||||
$handler->display->display_options['filters']['source_translation']['group'] = 1;
|
||||
/* Filter criterion: Content: Language */
|
||||
$handler->display->display_options['filters']['language']['id'] = 'language';
|
||||
$handler->display->display_options['filters']['language']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['language']['field'] = 'language';
|
||||
$handler->display->display_options['filters']['language']['operator'] = 'not in';
|
||||
$handler->display->display_options['filters']['language']['value'] = array(
|
||||
'und' => 'und',
|
||||
);
|
||||
$handler->display->display_options['filters']['language']['group'] = 1;
|
||||
/* Filter criterion: Content: Language */
|
||||
$handler->display->display_options['filters']['language_1']['id'] = 'language_1';
|
||||
$handler->display->display_options['filters']['language_1']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['language_1']['field'] = 'language';
|
||||
$handler->display->display_options['filters']['language_1']['group'] = 1;
|
||||
$handler->display->display_options['filters']['language_1']['exposed'] = TRUE;
|
||||
$handler->display->display_options['filters']['language_1']['expose']['operator_id'] = 'language_1_op';
|
||||
$handler->display->display_options['filters']['language_1']['expose']['label'] = 'Source language';
|
||||
$handler->display->display_options['filters']['language_1']['expose']['operator'] = 'language_1_op';
|
||||
$handler->display->display_options['filters']['language_1']['expose']['identifier'] = 'language_1';
|
||||
/* Filter criterion: Content translation: Select translatable content types */
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['id'] = 'tmgmt_translatable_types_select';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['field'] = 'tmgmt_translatable_types_select';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['exposed'] = TRUE;
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['expose']['operator_id'] = 'tmgmt_translatable_types_select_op';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['expose']['label'] = 'Content type';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['expose']['operator'] = 'tmgmt_translatable_types_select_op';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_select']['expose']['identifier'] = 'tmgmt_translatable_types_select';
|
||||
/* Filter criterion: Content translation: All translatable types */
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_all']['id'] = 'tmgmt_translatable_types_all';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_all']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['tmgmt_translatable_types_all']['field'] = 'tmgmt_translatable_types_all';
|
||||
/* Filter criterion: Content translation: Missing translation */
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['id'] = 'tmgmt_node_missing_translation';
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['table'] = 'node';
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['field'] = 'tmgmt_node_missing_translation';
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['exposed'] = TRUE;
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['expose']['operator_id'] = 'tmgmt_node_missing_translation_op';
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['expose']['label'] = 'Target language';
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['expose']['operator'] = 'tmgmt_node_missing_translation_op';
|
||||
$handler->display->display_options['filters']['tmgmt_node_missing_translation']['expose']['identifier'] = 'tmgmt_node_missing_translation';
|
||||
|
||||
/* Display: Page */
|
||||
$handler = $view->new_display('page', 'Page', 'page');
|
||||
$handler->display->display_options['path'] = 'admin/tmgmt/sources/node';
|
||||
$handler->display->display_options['menu']['type'] = 'tab';
|
||||
$handler->display->display_options['menu']['title'] = 'Content';
|
||||
$handler->display->display_options['menu']['weight'] = -20;
|
||||
$handler->display->display_options['menu']['context'] = 0;
|
||||
$translatables['tmgmt_node_source_overview'] = array(
|
||||
t('Master'),
|
||||
t('Content overview'),
|
||||
t('more'),
|
||||
t('Search'),
|
||||
t('Reset'),
|
||||
t('Sort by'),
|
||||
t('Asc'),
|
||||
t('Desc'),
|
||||
t('Items per page'),
|
||||
t('- All -'),
|
||||
t('Offset'),
|
||||
t('« first'),
|
||||
t('‹ previous'),
|
||||
t('next ›'),
|
||||
t('last »'),
|
||||
t('There are no nodes that match the specified filter criteria.'),
|
||||
t('User'),
|
||||
t('<!--views-bulk-operations-select-all-->'),
|
||||
t('Title (in source language)'),
|
||||
t('Type'),
|
||||
t('All translation languages'),
|
||||
t('Author'),
|
||||
t('Updated date'),
|
||||
t('Node title'),
|
||||
t('Published'),
|
||||
t('Source language'),
|
||||
t('Content type'),
|
||||
t('Page'),
|
||||
);
|
Reference in New Issue
Block a user