<<

NAME

Koha::File::Transport - Base class for file transport handling

SYNOPSIS

    use Koha::File::Transports;

    # Create/retrieve a transport (polymorphic - returns SFTP/FTP/Local subclass)
    my $transport = Koha::File::Transports->find($id);

    # SIMPLIFIED API (recommended) - connection and directory management are automatic
    # Connections are established on-demand and directories are managed automatically

    # Example 1: Upload to custom path (connection happens automatically)
    $transport->upload_file('/local/file.txt', 'remote.txt', { path => '/custom/dir/' });

    # Example 2: Download using configured download_directory (auto-managed)
    $transport->download_file('remote.txt', '/local/file.txt');

    # Example 3: List files in custom directory (one-shot operation)
    my $files = $transport->list_files({ path => '/some/directory/' });

    # TRADITIONAL API - manual connection and directory management
    # Useful when you need fine-grained control or want to perform multiple
    # operations in the same directory without repeating the path

    $transport->connect();                          # Optional - will auto-connect if omitted
    $transport->change_directory('/work/dir/');     # Sets working directory
    $transport->upload_file('/local/1.txt', '1.txt');
    $transport->upload_file('/local/2.txt', '2.txt'); # Uses same directory
    my $files = $transport->list_files();           # Lists /work/dir/
    $transport->rename_file('1.txt', '1_old.txt');
    $transport->download_file('2.txt', '/local/2.txt');
    $transport->disconnect();                       # Optional - cleaned up automatically

    # HYBRID APPROACH - mixing both APIs
    # Once you explicitly set a directory, auto-management is disabled

    $transport->change_directory('/work/dir/');     # Explicit directory change
    $transport->upload_file('/local/file.txt', 'file.txt');  # Uses /work/dir/
    $transport->list_files();                       # Still uses /work/dir/
    # The configured upload_directory/download_directory won't be used anymore

DESCRIPTION

Base class providing common functionality for FTP/SFTP/Local file transport.

This class supports two distinct usage patterns:

Simplified API (Auto-Managing)

The simplified API automatically manages connections and directories:

Traditional API (Explicit Control)

The traditional API provides manual control over connection and directory state:

How It Works

The implementation uses a _user_set_directory flag to track which mode is active:

This design allows you to mix both approaches in the same codebase, choosing the right pattern for each use case.

API

Class methods

store

    $server->store;

Overloaded store method that ensures directory paths end with a forward slash.

_ensure_connected

    $transport->_ensure_connected();

Internal method that ensures a connection exists, connecting if needed. Returns true if connected, false if connection failed.

_is_connected

    my $connected = $transport->_is_connected();

Internal method to check if transport is currently connected. Must be implemented by subclasses.

_auto_change_directory

    $transport->_auto_change_directory($dir_type, $custom_path);

Internal method that automatically changes to the appropriate directory. $dir_type is 'upload' or 'download', $custom_path is optional override.

plain_text_password

    my $password = $server->plain_text_password;

Returns the decrypted plaintext password.

plain_text_key

    my $key = $server->plain_text_key;

Returns the decrypted plaintext key file.

to_api

    my $json = $transport->to_api;

Returns a JSON representation of the object suitable for API output, excluding sensitive data.

to_api_mapping

This method returns the mapping for representing a Koha::File::Transport object on the API.

test_connection

    $transport->test_connection

Method to test the connection for the configuration of the current file server

Subclass methods

Interface methods that must be implemented by subclasses

connect

    my $success = $transport->connect();

Establishes a connection to the remote server.

Note: Calling this method is entirely optional. All file operations (upload_file, download_file, list_files, etc.) automatically establish a connection if one doesn't already exist. You only need to call this explicitly if you want to verify connectivity before performing operations.

Returns: True on success, undef on failure. Check object_messages() for details.

_connect

    my $success = $transport->_connect();

Internal method that performs the protocol-specific connection operation. Must be implemented by subclasses. Called by connect() after resetting directory state.

upload_file

    # Signature:
    my $success = $transport->upload_file($local_file, $remote_file, \%options);

Uploads a file to the remote server. Automatically establishes a connection if needed.

Parameters:

Usage Patterns:

    # Pattern 1: Simplified API with custom path
    $transport->upload_file('/tmp/data.csv', 'data.csv', { path => '/uploads/' });

    # Pattern 2: Simplified API with configured upload_directory
    $transport->upload_file('/tmp/data.csv', 'data.csv');

    # Pattern 3: Traditional API with explicit directory
    $transport->change_directory('/uploads/');
    $transport->upload_file('/tmp/data.csv', 'data.csv');

Returns: True on success, undef on failure. Check object_messages() for details.

_upload_file

    $transport->_upload_file($local_file, $remote_file);

Internal method that performs the protocol-specific upload operation. Must be implemented by subclasses. Called by upload_file after connection and directory management.

download_file

    # Signature:
    my $success = $transport->download_file($remote_file, $local_file, \%options);

Downloads a file from the remote server. Automatically establishes a connection if needed.

Parameters:

Usage Patterns:

    # Pattern 1: Simplified API with custom path
    $transport->download_file('data.csv', '/tmp/data.csv', { path => '/downloads/' });

    # Pattern 2: Simplified API with configured download_directory
    $transport->download_file('data.csv', '/tmp/data.csv');

    # Pattern 3: Traditional API with explicit directory
    $transport->change_directory('/downloads/');
    $transport->download_file('data.csv', '/tmp/data.csv');

Returns: True on success, undef on failure. Check object_messages() for details.

_download_file

    $transport->_download_file($remote_file, $local_file);

Internal method that performs the protocol-specific download operation. Must be implemented by subclasses. Called by download_file after connection and directory management.

rename_file

    my $success = $transport->rename_file($old_name, $new_name);

Method for renaming a file on the current file server

_rename_file

    $transport->_rename_file($old_name, $new_name);

Internal method that performs the protocol-specific file rename operation. Must be implemented by subclasses. Called by rename_file after connection verification.

list_files

    # Signature:
    my $files = $transport->list_files(\%options);

Lists files in a directory on the remote server. Automatically establishes a connection if needed.

Parameters:

Usage Patterns:

    # Pattern 1: Simplified API with custom path
    my $files = $transport->list_files({ path => '/incoming/' });

    # Pattern 2: Simplified API with configured download_directory
    my $files = $transport->list_files();

    # Pattern 3: Traditional API with explicit directory
    $transport->change_directory('/incoming/');
    my $files = $transport->list_files();

Returns: Arrayref of hashrefs on success, undef on failure. Each hashref contains file metadata (filename, size, permissions, etc.). The exact structure varies by transport type but always includes a 'filename' key.

_list_files

    my $files = $transport->_list_files();

Internal method that performs the protocol-specific file listing operation. Must be implemented by subclasses. Called by list_files after connection and directory management.

disconnect

    $transport->disconnect();

Closes the connection to the remote server.

Note: Calling this method is entirely optional. Connections are automatically cleaned up when the transport object is destroyed (goes out of scope). You only need to call this explicitly if you want to free resources before the object is destroyed, such as in long-running processes.

Returns: True on success, undef on failure.

_disconnect

    $transport->_disconnect();

Internal method that performs the protocol-specific disconnection operation. Must be implemented by subclasses. Called by disconnect() after resetting directory state.

change_directory

    my $success = $transport->change_directory($path);

Changes the current working directory on the remote server.

Important: Calling this method explicitly switches the transport to "manual mode" and disables automatic directory management. After calling this method, all subsequent file operations will use this directory (or relative paths from it) until you call change_directory() again or create a new connection.

Parameters:

Example:

    # After calling change_directory explicitly:
    $transport->change_directory('/work/dir/');
    $transport->upload_file($local, $remote);  # Uses /work/dir/, not upload_directory
    $transport->list_files();                  # Lists /work/dir/, not download_directory

Returns: True on success, undef on failure. Check object_messages() for details.

_change_directory

    my $success = $transport->_change_directory($path);

Internal method that performs the protocol-specific directory change operation. Must be implemented by subclasses. Called by change_directory() after setting the _user_set_directory flag.

_post_store_trigger

    $server->_post_store_trigger;

Method triggered by parent store to allow local additions to the store call

Internal methods

_encrypt_sensitive_data

Handle encryption of sensitive data

_dos2unix

Return a CR-free string from an input

_type

Return type of Object relating to Schema Result

<<