Merge branch 'b-3.6.1' of ../kivitendo-erp_20220811
[kivitendo-erp.git] / sql / Pg-upgrade2-auth / clients_webdav.pl
1 # @tag: clients_webdav
2 # @description: WebDAV-Migration für Mandanten
3 # @depends: clients
4 # @ignore: 0
5 package SL::DBUpgrade2::Auth::clients_webdav;
6
7 use strict;
8 use utf8;
9
10 use parent qw(SL::DBUpgrade2::Base);
11
12 use File::Find ();
13 use File::Path qw(make_path);
14 use IO::Dir;
15 use List::MoreUtils qw(any all);
16 use List::Util qw(first);
17
18 use SL::DBConnect;
19 use SL::DBUtils;
20 use SL::Template;
21 use SL::Helper::Flash;
22
23 use Rose::Object::MakeMethods::Generic (
24   'scalar --get_set_init' => [ qw(clients old_folders) ],
25 );
26
27 sub init_clients {
28   my ($self) = @_;
29   return [ selectall_hashref_query($::form, $self->dbh, qq|SELECT * FROM auth.clients ORDER BY lower(name)|) ];
30 }
31
32 sub init_old_folders {
33   tie my %dir, 'IO::Dir', 'webdav';
34   return [ sort grep { -d } keys %dir ];
35 }
36
37 sub _unlink_old_folders {
38   my ($self, %params) = @_;
39
40   rmdir $_ for @{ $self->old_folders };
41
42   return 1;
43 }
44
45 sub _ensure_one_client_exists {
46   my ($self, %params) = @_;
47
48   return if 0 != scalar @{ $self->clients };
49
50   my $sql = <<SQL;
51     INSERT INTO auth.clients (name, dbhost, dbport, dbname, dbuser, dbpasswd, is_default)
52     VALUES                   (?,    ?,      5432,   ?,      ?,      ?,        true)
53 SQL
54
55   $self->dbh->do($sql, undef, $::locale->text('Default Client (unconfigured)'), ($::locale->text('unconfigured')) x 4);
56
57   undef $self->{clients};
58 }
59
60 sub _move_files_into {
61   my ($self, $client) = @_;
62
63   tie my %dir, 'IO::Dir', 'webdav';
64   my @entries = grep { !m/^\.\.?$/ } keys %dir;
65
66   make_path('webdav/' . $client->{id});
67   rename "webdav/$_", "webdav/" . $client->{id} . "/$_" for @entries;
68 }
69
70 sub _create_folders {
71   my ($self, $client) = @_;
72   make_path('webdav/' . $client->{id} . "/$_") for qw(angebote bestellungen anfragen lieferantenbestellungen verkaufslieferscheine einkaufslieferscheine gutschriften rechnungen einkaufsrechnungen);
73 }
74
75 sub _create_symlink {
76   my ($self, $client) = @_;
77
78   my $name =  $client->{name} // '';
79   $name    =~ s:/+:_:g;
80
81   make_path('webdav/links');
82   symlink '../' . $client->{id}, "webdav/links/${name}";
83 }
84
85 sub _webdav_folders_used {
86   my ($self, %params) = @_;
87
88   my $contains_files  = 0;
89   my $wanted          = sub {
90     $contains_files   = 1 if -f && !m{/(?:\.gitignore|.dummy|webdav-user)$};
91   };
92
93   File::Find::find({ wanted => $wanted, no_chdir => 1 }, 'webdav');
94
95   return $contains_files;
96 }
97
98 sub run {
99   my ($self) = @_;
100
101   # WebDAV not used? Remove old folders, and we're done.
102   return $self->_unlink_old_folders if !$self->_webdav_folders_used;
103
104   # Ensure at least one client exists.
105   $self->_ensure_one_client_exists;
106
107   my $client_to_use;
108   if (1 == scalar @{ $self->clients }) {
109     # Exactly one client? Great, use that one without bothering the
110     # user.
111     $client_to_use = $self->clients->[0];
112
113   } else {
114     # If there's more than one client then let the user select which
115     # client to move the old files into. Maybe she already did?
116     $client_to_use = first { $_->{id} == $::form->{client_id} } @{ $self->clients } if $::form->{client_id};
117
118     if (!$client_to_use) {
119       # Nope, let's select it.
120       print $::form->parse_html_template('dbupgrade/auth/clients_webdav', { SELF => $self, default_client => (first { $_->{is_default} } @{ $self->clients }) });
121       return 2;
122     }
123   }
124
125   # Move files for the selected client.
126   $self->_move_files_into($client_to_use);
127
128   # Create the directory structures for all (even the selected client
129   # -- folders might be missing).
130   for (@{ $self->clients }) {
131     $self->_create_folders($_);
132     $self->_create_symlink($_);
133   }
134
135   return 1;
136 }
137
138 1;