php - List contents of a directory in HTML form dropdown and button to move selected file into a different directory

I am trying do two things.

  1. Build a HTML form dropdown that lists the files in a specific directory.
  2. On submit of a selected file from the dropdown list move the selected file from its current location to a new directory.

So far I have the following HTML/PHP for the dropdown:

</div>
        <div class="u-form u-form-1">
          <form action="end.php" method="POST"  class="u-clearfix u-form-spacing-25 u-form-vertical u-inner-form" source="email" name="End" style="padding: 10px;">
            <div class="u-form-group u-form-select u-form-group-1">
              <label for="select-7512" class="u-custom-font u-heading-font u-label u-label-1">Select File</label>
              <div class="u-form-select-wrapper">
                <select id="select-7512" name="end" class="u-border-1 u-border-custom-color-1 u-custom-font u-heading-font u-input u-input-rectangle u-radius-50 u-white u-input-1" required="required">
                  <?php

$path = "/usr/local/data/"; 
$show = array( '.conf' ); 

 $file_matcher = realpath(dirname(__FILE__)) . '/usr/local/data/*.{conf}';

foreach( glob($file_matcher, GLOB_BRACE) as $file ) {
  $file_name = basename($file);
  $select .= "<option value='$file'>$file_name</option>\n";
}

echo "$select";
?>
                </select>
                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="12" version="1" class="u-caret"><path fill="currentColor" d="M4 8L0 4h8z"></path></svg>
              </div>
            </div>
            <div class="u-align-left u-form-group u-form-submit">
              <a href="#" class="u-btn u-btn-round u-btn-submit u-button-style u-custom-color-2 u-custom-font u-heading-font u-radius-50 u-btn-1">End<br>

This is getting me a dropdown menu but it does not list any of the files in the /usr/local/data/ directory. I have checked and the permissions to this directory are okay. I believe my code must be wrong.

Once a file has been selected from the dropdown list I would like the submit button to run a PHP script that will move the selected file from its current dir /usr/local/data/ to /usr/local/archive/ maintaining its filename. I am not so familiar with PHP so I believe my script is probably majorly wrong here but I was building something like this:

    <?php
$filePath = '/usr/local/data/';
$destinationFilePath = '/isr/local/archive/';
rename($source_file, $destination_path . pathinfo($source_file, PATHINFO_BASENAME));
}
else {
echo "The file has been moved";
}
?>

Apologies in advance for any glaring problems but could someone please help me as to where I am going wrong with both steps here. Thanks for any guidance!

UPDATE

<?php
# the pattern for file matching by file extension
$pttn='@(\.conf)$@i';

# the folder to scan /path/to/directory ~ ie: /usr/local/data/
$path="/usr/local/data/";

# find the files using glob and file match using preg_grep
$files=preg_grep( $pttn, glob(  $path . '/*.*' ) );

# process file found that match the pattern and build the select menu
echo '<select name="end">';
foreach( $files as $filepath )printf('<option value="%s">%s', realpath( $filepath ), pathinfo( basename( $filepath ),PATHINFO_FILENAME) );
echo '</select>
<!--
    handle the user selection from dropdown menu...
-->
<script>
    document.querySelector("select[name='end']").addEventListener("change",function(e){
    if( this.options.selectedIndex > 0 ){
        let fd=new FormData();
            fd.set("filepath", this.value );

        fetch( "archivefile.php", { method:"post", body:fd } )
            .then( r=>r.text() )
            .then( text=>{
                this.removeChild( this.options[ this.options.selectedIndex ] );
                alert( text )
            })
    }
})
</script>';

file archive script

<?php
    if( isset( $_POST['filepath'] ) ){

        $source = realpath( $_POST['filepath'] );
        $targetdir = sprintf( '%s/usr/local/archive', __DIR__ );
        $destination = sprintf( '%s/%s', $targetdir, basename( $source ) );

        if( !file_exists( $targetdir ) )mkdir( $targetdir, 0777, true );
        clearstatcache();

        if( $source && file_exists( $source ) ){
            $status=rename( $source, $destination );
        }
        clearstatcache();

        exit( $status ? 'Success ' : 'Failure.' );
    }
?>

Answer

Solution:

The filepath you cite in the question is a *nix type path and I have no means by which to test this script as it is written on a windoze system so the path variable might need tweaking?!

The following scans the current working directory ( __DIR__ ) and lists the .conf or .config files found therein - should be simple enough to use your path and possibly tweak the regex pattern if you need more filetypes added.

# the pattern for file matching by file extension
$pttn='@(\.conf|\.config)$@i';

# the folder to scan /path/to/directory ~ ie: /usr/local/data/
$path=__DIR__;

# find the files using glob and file match using preg_grep
$files=preg_grep( $pttn, glob(  $path . '/*.*' ) );

# process file found that match the pattern and build the select menu
echo '<select name="end">';
foreach( $files as $filepath )printf('<option value="%s">%s', realpath( $filepath ), pathinfo( basename( $filepath ),PATHINFO_FILENAME) );
echo '</select>
<!--
    handle the user selection from dropdown menu...
-->
<script>
    document.querySelector("select[name=\'end\']").addEventListener("change",function(e){
        alert( this.value )
    })
</script>';

updates

The Javascript I would modify like this so that it fires off an AJAX request to whatever backend script determined to be the upload/move handler.

document.querySelector("select[name='end']").addEventListener("change",function(e){
    if( this.options.selectedIndex > 0 ){
        let fd=new FormData();
            fd.set("filepath", this.value );
            
        fetch( "file-move-target.php", { method:"post", body:fd } )
            .then( r=>r.text() )
            .then( text=>{
                this.removeChild( this.options[ this.options.selectedIndex ] );
                alert( text )
            })
    }
})

And the endpoint to handle the file move:

<?php
    if( isset( $_POST['filepath'] ) ){
        $status=false;
        $source = realpath( $_POST['filepath'] );
        $targetdir = sprintf( '%s/usr/local/archive', '' );
        $destination = sprintf( '%s/%s', $targetdir, basename( $source ) );
        
        if( !file_exists( $targetdir ) )mkdir( $targetdir, 0777, true );
        clearstatcache();
        
        if( $source && file_exists( $source ) ){
            $status=rename( $source, $destination );
        }
        clearstatcache();
        
        exit( $status ? 'File moved' : 'Error: unable to move file' );
    }
?>

Source