COnfig export, popravljeno in dopolnjeno prevajanje

popravki-prevodi-urednikovanje
Jurij Podgoršek 2024-07-24 14:41:25 +02:00
parent 6a80ee7d13
commit f01f264ad9
33 changed files with 545 additions and 140 deletions

View File

@ -6,5 +6,5 @@ _core:
default_config_hash: zglzjmYxi0G0ag9MZ02y0LSJOdpWRwJxyP_OvFojFyo
id: basic
label: 'Basic block'
revision: 0
revision: false
description: 'A basic block contains a title and a body.'

View File

@ -5,6 +5,7 @@ dependencies:
config:
- field.field.node.page.body
- field.field.node.page.field_media
- field.field.node.page.field_strojni_prevod
- node.type.page
module:
- content_moderation
@ -20,7 +21,7 @@ mode: default
content:
body:
type: text_textarea_with_summary
weight: 31
weight: 9
region: content
settings:
rows: 9
@ -30,73 +31,80 @@ content:
third_party_settings: { }
created:
type: datetime_timestamp
weight: 10
weight: 4
region: content
settings: { }
third_party_settings: { }
field_media:
type: media_library_widget
weight: 5
weight: 3
region: content
settings:
media_types: { }
third_party_settings: { }
field_strojni_prevod:
type: boolean_checkbox
weight: 12
region: content
settings:
display_label: true
third_party_settings: { }
langcode:
type: language_select
weight: 2
weight: 1
region: content
settings:
include_locked: true
third_party_settings: { }
moderation_state:
type: moderation_state_default
weight: 100
weight: 10
region: content
settings: { }
third_party_settings: { }
path:
type: path
weight: 30
weight: 8
region: content
settings: { }
third_party_settings: { }
promote:
type: boolean_checkbox
weight: 15
weight: 6
region: content
settings:
display_label: true
third_party_settings: { }
status:
type: boolean_checkbox
weight: 120
weight: 11
region: content
settings:
display_label: true
third_party_settings: { }
sticky:
type: boolean_checkbox
weight: 16
weight: 7
region: content
settings:
display_label: true
third_party_settings: { }
title:
type: string_textfield
weight: -5
weight: 0
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
translation:
weight: 10
weight: 5
region: content
settings: { }
third_party_settings: { }
uid:
type: entity_reference_autocomplete
weight: 5
weight: 2
region: content
settings:
match_operator: CONTAINS

View File

@ -5,6 +5,7 @@ dependencies:
config:
- field.field.node.page.body
- field.field.node.page.field_media
- field.field.node.page.field_strojni_prevod
- node.type.page
module:
- text
@ -32,6 +33,16 @@ content:
third_party_settings: { }
weight: 0
region: content
field_strojni_prevod:
type: boolean
label: above
settings:
format: default
format_custom_false: ''
format_custom_true: ''
third_party_settings: { }
weight: 104
region: content
links:
settings: { }
third_party_settings: { }

View File

@ -6,6 +6,7 @@ dependencies:
- core.entity_view_mode.node.teaser
- field.field.node.page.body
- field.field.node.page.field_media
- field.field.node.page.field_strojni_prevod
- node.type.page
module:
- text
@ -30,4 +31,5 @@ content:
region: content
hidden:
field_media: true
field_strojni_prevod: true
langcode: true

View File

@ -0,0 +1,23 @@
uuid: 2958b0de-fe09-4c7b-b5e4-a92d0ee61fb3
langcode: sl
status: true
dependencies:
config:
- field.storage.node.field_strojni_prevod
- node.type.page
id: node.page.field_strojni_prevod
field_name: field_strojni_prevod
entity_type: node
bundle: page
label: 'Strojni prevod?'
description: ''
required: false
translatable: true
default_value:
-
value: 0
default_value_callback: ''
settings:
on_label: Da
off_label: Ne
field_type: boolean

View File

@ -1 +0,0 @@
label: 'Indeks pretraživanja'

View File

@ -1 +0,0 @@
label: Mamac

View File

@ -1 +0,0 @@
label: 'Stranica taksonomijskog pojma'

View File

@ -2,7 +2,7 @@ label: 'Custom block library'
description: 'Find and manage custom blocks.'
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
title: 'Custom block library'
fields:
@ -14,7 +14,6 @@ display:
label: Operacije
exposed_form:
options:
submit_button: Primjeni
reset_button_label: Ponastavi
exposed_sorts_label: 'Rasporedi po'
sort_asc_label: Naraščajoče
@ -27,7 +26,6 @@ display:
expose:
label: 'Opis bloka'
page_1:
display_title: Stranica
display_options:
menu:
title: 'Custom block library'

View File

@ -1,7 +1,7 @@
label: Komentari
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
title: Komentari
fields:

View File

@ -1,7 +1,7 @@
label: 'Posljednji komentari'
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
title: 'Posljednji komentari'
empty:

View File

@ -1,7 +1,7 @@
label: Mediji
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
title: Mediji
fields:
@ -12,6 +12,7 @@ display:
uid:
label: Avtor
status:
label: Status
settings:
format_custom_true: Objavljeno
changed:

View File

@ -1,6 +1,6 @@
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
title: Mediji
fields:
@ -26,7 +26,6 @@ display:
expose:
label: Jezik
page:
display_title: Stranica
display_options:
fields:
media_bulk_form:
@ -38,10 +37,6 @@ display:
widget:
display_title: Widget
display_options:
arguments:
bundle:
exception:
title: Svi
filters:
name:
expose:
@ -60,10 +55,6 @@ display:
label: Avtor
changed:
label: Posodobljeno
arguments:
bundle:
exception:
title: Svi
filters:
name:
expose:

View File

@ -1,12 +1,14 @@
label: 'Moderirane vsebine'
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
title: 'Moderirane vsebine'
fields:
title:
label: Naslov
type:
label: 'Content type'
name:
label: Avtor
changed:
@ -24,6 +26,9 @@ display:
title:
expose:
label: Naslov
type:
expose:
label: 'Content type'
langcode:
expose:
label: Jezik

View File

@ -1,18 +1,11 @@
label: 'Pojam taksonomije'
display:
default:
display_title: Zadano
display_title: Privzeto
display_options:
exposed_form:
options:
submit_button: Primjeni
reset_button_label: Ponastavi
exposed_sorts_label: 'Rasporedi po'
sort_asc_label: Naraščajoče
sort_desc_label: Padajoče
arguments:
tid:
exception:
title: Svi
page_1:
display_title: Stranica

View File

@ -7,7 +7,7 @@ _core:
name: Article
type: article
description: 'Use <em>articles</em> for time-sensitive content like news, press releases or blog posts.'
help: ''
help: null
new_revision: true
preview_mode: 1
display_submitted: true

View File

@ -12,7 +12,7 @@ third_party_settings:
name: Koncept
type: concept
description: 'Osnovni element manifesta'
help: ''
help: null
new_revision: true
preview_mode: 1
display_submitted: true

View File

@ -7,7 +7,7 @@ _core:
name: 'Basic page'
type: page
description: "Use <em>basic pages</em> for your static content, such as an 'About us' page."
help: ''
help: null
new_revision: true
preview_mode: 1
display_submitted: false

View File

@ -3,4 +3,4 @@ _core:
threshold:
requirements_warning: 172800
requirements_error: 1209600
logging: 1
logging: true

View File

@ -1,10 +1,10 @@
_core:
default_config_hash: t7clj3mzmOGrXX0HuCH5usf0vEqRtnMTBFVBIEmZ5pc
first_day: 0
first_day: 1
country:
default: ''
default: null
timezone:
default: UTC
default: Europe/Ljubljana
user:
configurable: true
default: 0

View File

@ -8,3 +8,4 @@ name: Tags
vid: tags
description: 'Use tags to group articles on similar topics into categories.'
weight: 0
new_revision: false

View File

@ -273,6 +273,7 @@ display:
type: mini
options:
offset: 0
pagination_heading_level: h4
items_per_page: 50
total_pages: null
id: 0

View File

@ -533,6 +533,7 @@ display:
type: full
options:
offset: 0
pagination_heading_level: h4
items_per_page: 50
total_pages: null
id: 0

View File

@ -19,7 +19,7 @@ base_field: nid
display:
default:
id: default
display_title: Zadano
display_title: Privzeto
display_plugin: default
position: 0
display_options:
@ -427,6 +427,7 @@ display:
pager:
type: full
options:
pagination_heading_level: h4
items_per_page: 50
tags:
next: 'Next '

View File

@ -522,6 +522,7 @@ display:
type: full
options:
offset: 0
pagination_heading_level: h4
items_per_page: 50
total_pages: null
id: 0

View File

@ -139,6 +139,7 @@ display:
type: mini
options:
offset: 0
pagination_heading_level: h4
items_per_page: 24
total_pages: null
id: 0

View File

@ -418,6 +418,7 @@ display:
type: full
options:
offset: 0
pagination_heading_level: h4
items_per_page: 50
total_pages: null
id: 0

View File

@ -29,6 +29,7 @@ display:
type: mini
options:
offset: 0
pagination_heading_level: h4
items_per_page: 10
total_pages: 0
id: 0

View File

@ -90,6 +90,72 @@ display:
multi_type: separator
separator: ', '
field_api_classes: false
vid:
id: vid
table: node_field_revision
field: vid
relationship: nid
group_type: group
admin_label: ''
entity_type: node
entity_field: vid
plugin_id: field
label: 'ID stare različice'
exclude: true
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: number_integer
settings:
thousand_separator: ''
prefix_suffix: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
vid_1:
id: vid_1
table: node_field_revision
@ -156,72 +222,6 @@ display:
multi_type: separator
separator: ', '
field_api_classes: false
vid:
id: vid
table: node_field_revision
field: vid
relationship: nid
group_type: group
admin_label: ''
entity_type: node
entity_field: vid
plugin_id: field
label: 'Latest Revision ID'
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: number_integer
settings:
thousand_separator: ''
prefix_suffix: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
title:
id: title
table: node_field_revision
@ -287,6 +287,72 @@ display:
multi_type: separator
separator: ', '
field_api_classes: false
langcode:
id: langcode
table: node_field_revision
field: langcode
relationship: nid
group_type: group
admin_label: ''
entity_type: node
entity_field: langcode
plugin_id: field_language
label: Jezik
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: language
settings:
link_to_entity: 0
native_language: 0
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: 0
moderation_state:
id: moderation_state
table: node_field_revision
@ -496,6 +562,7 @@ display:
type: mini
options:
offset: 0
pagination_heading_level: h4
items_per_page: 20
total_pages: null
id: 0

View File

@ -0,0 +1,259 @@
uuid: 251e836d-f4e6-4f56-b284-0dad8b4c002c
langcode: sl
status: true
dependencies:
config:
- node.type.concept
module:
- node
- user
id: zadnje_spremembe_2
label: 'Zadnje spremembe 2'
module: views
description: ''
tag: ''
base_table: node_field_revision
base_field: nid
display:
default:
id: default
display_title: Default
display_plugin: default
position: 0
display_options:
title: 'Zadnje spremembe 2'
fields:
changed:
id: changed
table: node_field_revision
field: changed
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: changed
plugin_id: field
label: ''
exclude: false
alter:
alter_text: false
make_link: false
absolute: false
word_boundary: false
ellipsis: false
strip_tags: false
trim: false
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: timestamp
settings:
date_format: medium
custom_date_format: ''
timezone: ''
tooltip:
date_format: ''
custom_date_format: ''
time_diff:
enabled: false
future_format: '@interval hence'
past_format: '@interval ago'
granularity: 2
refresh: 60
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
title:
id: title
table: node_field_revision
field: title
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: title
plugin_id: field
label: ''
exclude: false
alter:
alter_text: false
make_link: false
absolute: false
word_boundary: false
ellipsis: false
strip_tags: false
trim: false
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: string
settings:
link_to_entity: false
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
pager:
type: mini
options:
offset: 0
pagination_heading_level: h4
items_per_page: 10
total_pages: null
id: 0
tags:
next:
previous:
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Ponastavi
exposed_sorts_label: 'Rasporedi po'
expose_sort_order: true
sort_asc_label: Naraščajoče
sort_desc_label: Padajoče
access:
type: perm
options:
perm: 'view all revisions'
cache:
type: tag
options: { }
empty: { }
sorts:
changed:
id: changed
table: node_field_revision
field: changed
relationship: none
group_type: group
admin_label: ''
entity_type: node
entity_field: changed
plugin_id: date
order: DESC
expose:
label: ''
field_identifier: ''
exposed: false
granularity: second
arguments: { }
filters:
status:
id: status
table: node_field_revision
field: status
entity_type: node
entity_field: status
plugin_id: boolean
value: '1'
group: 1
expose:
operator: ''
type:
id: type
table: node_field_data
field: type
relationship: nid
entity_type: node
entity_field: type
plugin_id: bundle
value:
concept: concept
style:
type: default
row:
type: fields
query:
type: views_query
options:
query_comment: ''
disable_sql_rewrite: false
distinct: false
replica: false
query_tags: { }
relationships:
nid:
id: nid
table: node_field_revision
field: nid
relationship: none
group_type: group
admin_label: 'Get the actual content from a content revision.'
entity_type: node
entity_field: nid
plugin_id: standard
required: true
header: { }
footer: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }
page_1:
id: page_1
display_title: Page
display_plugin: page
position: 1
display_options:
display_extenders: { }
path: zadnje-spremembe-2
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }

View File

@ -111,14 +111,20 @@ class AddConcept extends ResourceBase {
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
// Fields: naslov, text, povezani pojmi, email
// Optional fields: language, related concept.
if (empty($data['title']) || empty($data['text']) || empty($data['uuid'])) {
throw new MissingDataException('Title, uuid or text missing.');
// Fields: naslov, text, email, language
// Optional fields: email, related_concept @TODO
if (empty($data['title']) || empty($data['text']) || empty($data['uuid']) || empty($data['language'])) {
throw new MissingDataException('Title, uuid, text or language missing.');
}
$uid = $this->getUserIdByEmail($data['email'] ?? null);
if ($concept = $this->getConceptFromUuid($data['uuid'])) {
// Concept exists - create a new revision.
if ($concept->hasTranslation($data['language'])) {
$concept = $concept->getTranslation($data['language']);
} else {
$concept = $concept->addTranslation($data['language']);
}
$concept->setNewRevision(TRUE);
$concept->setRevisionUserId($uid);
$concept->setRevisionCreationTime(\Drupal::time()->getRequestTime());
@ -133,14 +139,14 @@ class AddConcept extends ResourceBase {
$concept->setRevisionLogMessage('New revision by concept endpoint.');
$concept->set('moderation_state', 'draft');
$concept->set('status', 0);
$concept->set('field_strojni_prevod', 0);
$concept->save();
$this->logger->notice('New concept @title revision @revid created by uid @uid.', [
'@title' => $concept->getTitle(),
'@revid' => $concept->getRevisionId(),
'@uid' => $uid,
]);
}
else {
} else {
// Concept does not exist - create a new node.
$concept = [
'type' => 'concept',
@ -149,6 +155,8 @@ class AddConcept extends ResourceBase {
'uuid' => $data['uuid'],
'uid' => $uid,
'moderation_state' => 'draft',
'field_strojni_prevod' => 0,
'language' => $data['language']
];
// @TODO Check if related concepts are set and add them to the concept.
// @TODO Check language and add set it on concept if exists.

View File

@ -7,6 +7,7 @@ namespace Drupal\yufu_concept;
use Psr\Http\Client\ClientInterface;
use Drupal\Core\Site\Settings;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Exception\BadResponseException;
/**
* Ta service omogoča prevajanje preko libretranslate APIja.
@ -31,18 +32,26 @@ final class Translate {
* Prevede $besedila iz $izvorniJezik v $ciljniJezik
*/
public function prevedi(array $besedila, $izvorniJezik, $ciljniJezik): ?array {
$odziv = $this->request('translate', [
'json' => [
'q' => $besedila,
'source' => $izvorniJezik,
'target' => $ciljniJezik,
'format' => 'text'
]
]);
$retry = 0;
while ($retry < 3) {
try {
$odziv = $this->request('translate', [
'json' => [
'q' => $besedila,
'source' => $izvorniJezik,
'target' => $ciljniJezik,
'format' => 'text'
]
]);
if ($odziv->getStatusCode() == 200) {
$json = json_decode($odziv->getBody()->getContents(), true);
return $json['translatedText'];
if ($odziv->getStatusCode() == 200) {
$json = json_decode($odziv->getBody()->getContents(), true);
return $json['translatedText'];
}
$retry += 1;
} catch (BadResponseException $e) {
$retry += 1;
}
}
return null;

View File

@ -15,9 +15,10 @@ use Symfony\Component\HttpClient\HttpClient;
*/
function yufu_concept_node_presave(EntityInterface $entity) {
if ($entity instanceOf NodeInterface && $entity->bundle() == 'concept') {
// Dodaj avtorja spremembe med urednike, če še ni
$transition = \Drupal::service('content_moderation_notifications.notification_information')->getTransition($entity);
if ($transition->id() == 'publish') {
// Ko je sprememba koncepta potrjena
if ($transition->id() == 'publish' && !$entity->field_strojni_prevod->value) {
// Dodaj avtorja spremembe med urednike, če še ni
if ($user = $entity->uid->entity) {
if (!$user->status->value) {
$user->set('status', 1);
@ -29,13 +30,34 @@ function yufu_concept_node_presave(EntityInterface $entity) {
}
}
// Dodaj oz. posodobi manjkajoce prevode (ampak samo ce ne gre za
// strojni prevod!)
// Dodaj oz. posodobi manjkajoce prevode navadnih strani
function yufu_concept_node_insert(EntityInterface $entity) {
uskladi_prevode($entity);
if ($entity instanceOf NodeInterface && $entity->bundle() == 'page') {
uskladi_prevode($entity);
}
if ($entity instanceOf NodeInterface && $entity->bundle() == 'concept') {
$transition = \Drupal::service('content_moderation_notifications.notification_information')->getTransition($entity);
// Ko je sprememba koncepta potrjena
if ($transition->id() == 'publish' && !$entity->field_strojni_prevod->value) {
/* Posodobi strojne prevode */
uskladi_prevode($entity);
}
}
}
function yufu_concept_node_update(EntityInterface $entity) {
uskladi_prevode($entity);
if ($entity instanceOf NodeInterface && $entity->bundle() == 'page') {
uskladi_prevode($entity);
}
if ($entity instanceOf NodeInterface && $entity->bundle() == 'concept') {
$transition = \Drupal::service('content_moderation_notifications.notification_information')->getTransition($entity);
// Ko je sprememba koncepta potrjena
if ($transition->id() == 'publish' && !$entity->field_strojni_prevod->value) {
/* Posodobi strojne prevode */
uskladi_prevode($entity);
}
}
}
function prevedi_koncept(EntityInterface $entity, EntityInterface $prevod) {
@ -66,12 +88,14 @@ function prevedi_koncept(EntityInterface $entity, EntityInterface $prevod) {
$prevod->set('title', $naslov);
$prevod->set('body', $tekst);
$prevod->setNewRevision();
$prevod->moderation_state = 'published';
}
function uskladi_prevode(EntityInterface $entity) {
if ($entity instanceOf NodeInterface
&& $entity->bundle() == 'concept'
&& !$entity->field_strojni_prevod->value) {
&& !$entity->field_strojni_prevod->value
&& ($entity->bundle() == 'concept' || $entity->bundle() == 'page')) {
$vsiJeziki = array_keys(\Drupal::languageManager()->getLanguages());
@ -86,6 +110,7 @@ function uskladi_prevode(EntityInterface $entity) {
$prevod = $entity->addTranslation($jezik, $entity->toArray());
prevedi_koncept($entity, $prevod);
$prevod->set('field_strojni_prevod', true);
$prevod->setNewRevision();
$prevod->save();
$ostaliJeziki = array_diff($ostaliJeziki, [$jezik]);