215 lines
6.8 KiB
Perl
215 lines
6.8 KiB
Perl
package Koha::Schema::Component::Localization;
|
|
|
|
=head1 NAME
|
|
|
|
Koha::Schema::Component::Localization
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
package Koha::Schema::Result::SomeTable;
|
|
|
|
# ... generated code ...
|
|
|
|
__PACKAGE__->load_components('+Koha::Schema::Component::Localization');
|
|
|
|
__PACKAGE__->localization_add_relationships(
|
|
'some_table_localizations',
|
|
'some_table_id' => 'some_table_id',
|
|
'first_column',
|
|
'second_column',
|
|
# ...
|
|
);
|
|
|
|
package main;
|
|
|
|
my $rows = $schema->resultset('SomeTable');
|
|
my $row = $rows->first;
|
|
$row->localizations->search($cond);
|
|
$row->create_related('first_column_localizations', { lang => $lang, translation => $translation })
|
|
|
|
while (my $row = $rows->next)
|
|
# first call will fetch all localizations for the current language and
|
|
# the result will be cached, next calls will not execute a query
|
|
$row->localization('first_column', $lang);
|
|
|
|
# no query executed
|
|
$row->localization('second_column', $lang);
|
|
}
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This is a DBIx::Class component that helps to manage database localizations by
|
|
adding several relationships and methods to a "Result Class"
|
|
|
|
This can handle several localizable columns (also referred as "properties") per
|
|
table
|
|
|
|
To add database localizations to an existing database table, you need to:
|
|
|
|
=over
|
|
|
|
=item * Create a new table with:
|
|
|
|
=over
|
|
|
|
=item * An auto incremented column as primary key
|
|
|
|
=item * A foreign key column referencing the existing table
|
|
|
|
=item * 3 string (varchar or text) columns named 'property', 'lang',
|
|
'translation'
|
|
|
|
=item * A unique key comprising the foreign key column, 'property' and 'lang'
|
|
|
|
=back
|
|
|
|
=item * Regenerate the DBIx::Class schema with
|
|
misc/devel/update_dbix_class_files.pl
|
|
|
|
=item * Add calls to load_components and localization_add_relationships at the
|
|
end of the result class
|
|
|
|
=back
|
|
|
|
This will give you a relationship named 'localizations' through which you can
|
|
access all localizations of a particular table row.
|
|
|
|
And for every property, you will have:
|
|
|
|
=over
|
|
|
|
=item * a "has_many" relationship named <property>_localizations, giving access
|
|
to all localizations of a particular table row for this particular property
|
|
|
|
=item * a "might_have" relationship named <property>_localization, giving
|
|
access to the localization of a particular table row for this particular
|
|
property and for the current language (uses C4::Languages::getlanguage)
|
|
|
|
=back
|
|
|
|
The "row" object will also gain a method C<localization($property, $lang)>
|
|
which returns a specific translation and uses cache to avoid executing lots of
|
|
queries
|
|
|
|
=cut
|
|
|
|
use Modern::Perl;
|
|
use Carp;
|
|
|
|
use base qw(DBIx::Class);
|
|
|
|
=head2 localization_add_relationships
|
|
|
|
Add relationships to the localization table
|
|
|
|
=cut
|
|
|
|
sub localization_add_relationships {
|
|
my ( $class, $pk_column, @properties ) = @_;
|
|
|
|
my $rel_class = 'Koha::Schema::Result::Localization';
|
|
my $source_name = $class =~ s/.*:://r;
|
|
|
|
$class->has_many(
|
|
'localizations',
|
|
$rel_class,
|
|
sub {
|
|
my ($args) = @_;
|
|
|
|
return (
|
|
{
|
|
"$args->{foreign_alias}.code" => { -ident => "$args->{self_alias}.$pk_column" },
|
|
"$args->{foreign_alias}.entity" => $source_name,
|
|
},
|
|
!$args->{self_result_object} ? () : {
|
|
"$args->{foreign_alias}.code" => $args->{self_result_object}->get_column($pk_column),
|
|
"$args->{foreign_alias}.entity" => $source_name,
|
|
},
|
|
);
|
|
},
|
|
{ cascade_copy => 0, cascade_delete => 1, cascade_update => 0 },
|
|
);
|
|
|
|
foreach my $property (@properties) {
|
|
$class->might_have(
|
|
$property . '_localization',
|
|
$rel_class,
|
|
sub {
|
|
my ($args) = @_;
|
|
|
|
# Not a 'use' because we don't want to load C4::Languages (and
|
|
# thus C4::Context) while loading the schema
|
|
require C4::Languages;
|
|
my $lang = C4::Languages::getlanguage();
|
|
|
|
return (
|
|
{
|
|
"$args->{foreign_alias}.code" => { -ident => "$args->{self_alias}.$pk_column" },
|
|
"$args->{foreign_alias}.entity" => $source_name,
|
|
"$args->{foreign_alias}.property" => $property,
|
|
"$args->{foreign_alias}.lang" => $lang,
|
|
},
|
|
!$args->{self_result_object} ? () : {
|
|
"$args->{foreign_alias}.code" => $args->{self_result_object}->get_column($pk_column),
|
|
"$args->{foreign_alias}.entity" => $source_name,
|
|
"$args->{foreign_alias}.property" => $property,
|
|
"$args->{foreign_alias}.lang" => $lang,
|
|
},
|
|
);
|
|
},
|
|
{ cascade_copy => 0, cascade_delete => 0, cascade_update => 0 },
|
|
);
|
|
|
|
$class->has_many(
|
|
$property . '_localizations',
|
|
$rel_class,
|
|
sub {
|
|
my ($args) = @_;
|
|
|
|
return (
|
|
{
|
|
"$args->{foreign_alias}.code" => { -ident => "$args->{self_alias}.$pk_column" },
|
|
"$args->{foreign_alias}.entity" => $source_name,
|
|
"$args->{foreign_alias}.property" => $property,
|
|
},
|
|
!$args->{self_result_object} ? () : {
|
|
"$args->{foreign_alias}.code" => $args->{self_result_object}->get_column($pk_column),
|
|
"$args->{foreign_alias}.entity" => $source_name,
|
|
"$args->{foreign_alias}.property" => $property,
|
|
},
|
|
);
|
|
},
|
|
{ cascade_copy => 0, cascade_delete => 0, cascade_update => 0 },
|
|
);
|
|
}
|
|
}
|
|
|
|
sub localization {
|
|
my ( $self, $property, $lang ) = @_;
|
|
|
|
my $result_source = $self->result_source;
|
|
|
|
my $cache = Koha::Caches->get_instance('localization');
|
|
my $cache_key = sprintf( '%s:%s', $result_source->source_name, $lang );
|
|
my $localizations_map = $cache->get_from_cache($cache_key);
|
|
unless ($localizations_map) {
|
|
$localizations_map = {};
|
|
|
|
my $localizations = $result_source->schema->resultset('Localization')->search( { lang => $lang } );
|
|
while ( my $localization = $localizations->next ) {
|
|
my $fk = $localization->get_column('code');
|
|
my $localization_key = sprintf( '%s:%s', $fk, $localization->property );
|
|
$localizations_map->{$localization_key} = $localization->translation;
|
|
}
|
|
|
|
$cache->set_in_cache( $cache_key, $localizations_map );
|
|
}
|
|
|
|
my ($pk) = $self->id;
|
|
my $localization_key = sprintf( '%s:%s', $pk, $property );
|
|
|
|
return $localizations_map->{$localization_key};
|
|
}
|
|
|
|
1;
|