Apache2-FileManager

 view release on metacpan or  search on metacpan

FileManager.pm  view on Meta::CPAN

  $$o{DR} ||= r->dir_config('DOCUMENT_ROOT') || r->document_root;

  #does user defined document root lie inside real doc root?
  if ($$o{DR} !~ /^$dr/) {
    $$o{DR} = r->document_root;
    r->log_error("Warning: Document root changed to $dr.".
                  " Custom document root must lie inside of ".
                  "real document root.");
  }

  #verify current working directory
  $_ = r->param('FILEMANAGER_curr_dir');
  s/\.\.//g; s/^\///; s/\/$//;
  my $curr_dir = $_;

  #set current directory
  if (! chdir $$o{DR}."/$curr_dir") {
    chdir $$o{DR};
    $curr_dir = "";
  }

  $$o{FILEMANAGER_curr_dir} = $curr_dir;

  #set default view method
  $$o{'view'} = "filemanager";

  return undef;
}





###############################################################################
# ----- Views --------------------------------------------------------------- #
###############################################################################

#after upload files - view
sub view_post_upload {
  r->print(q{
      <SCRIPT>
        window.opener.document.FileManager.submit();
        window.opener.focus();
        window.close();
      </SCRIPT>
      });
  return undef;
}


#after rsync transacation - view
sub view_post_rsync {
  my $o = shift;
  r->print(qq{
    <CENTER>
      <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0>
        <TR><TD>$$o{MESSAGE}</TD></TR>
        <TR>
          <FORM>
            <TD ALIGN=RIGHT>
              <INPUT TYPE=BUTTON VALUE='close'
                      onclick="window.close();">
            </TD>
          </FORM>
        </TR>
      </TABLE>
    </CENTER>
  });
  return undef;
}


sub view_filemanager {
  my $o = shift;

  my ($location, $up_a_href) = $o->html_location_toolbar();
  $up_a_href ||= "";

  my $message = "<I><FONT COLOR=#990000>".$$o{MESSAGE}."</FONT></I>";
  r->print("
    <!-- Scripts -->
    ".$o->html_javascript(r->hostname())."

    <!-- Styles -->
    ".$o->html_style_sheet()."

    <FORM NAME=FileManager ACTION='".r->uri."' METHOD=POST>
    ".$o->html_hidden_fields()."

      <!-- Header -->
      ".$o->html_top()."

      <!-- Special message -->
      $message

      <TABLE CELLPADDING=2 CELLSPACING=2
             BORDER=0 WIDTH=100% BGCOLOR=#606060>
        <TR><TD>".$o->html_cmd_toolbar()."</TD></TR>
        <TR BGCOLOR=WHITE><TD>$location</TD></TR>
        <TR><TD>".$o->html_file_list($up_a_href)."</TD></TR>
      </TABLE>

      <!-- Footer -->
      ".$o->html_bottom()."

    </FORM>
    ");

  return undef;
}


sub view_pre_editfile {
  my $o = shift;

  my $editfile = r->param('FILEMANAGER_editfile');
  my $base = "http://".r->hostname."/$editfile";
  $editfile =~ /([^\/]+)$/;
  my $filename = $1;

  my $fh;
  if (-T $filename && -w $filename) {
    $fh = IO::File->new("< ".$filename);
  }

  my $message = "";
  if ($$o{MESSAGE}) {
    $message =
      "<I><FONT COLOR=#990000>".$$o{MESSAGE}."</FONT></I><BR>";
  }

  if (! $fh) {
    r->print("
      <HTML>
      <HEAD>
      <BODY>
      <CENTER><BR>$message

      <TABLE BORDER=1 CELLPADDING=10 CELLSPACING=0
             BGCOLOR=#606060>
        <TR BGCOLOR=WHITE>
          <TD ALIGN=CENTER>
            could not open file: <I>$base</I> in text writing mode
          </TD>
        </TR>
        <TR BGCOLOR=#efefef>
          <TD ALIGN=RIGHT>
            <FORM>
              <INPUT TYPE=BUTTON VALUE=close
                onclick=\"
                  window.close();
                  return false;\">
            </FORM>
          </TD>
        </TR>
      </TABLE>

      <BR>
      </CENTER>
      </BODY>
      </HTML>");
  }

  else {

    my $data;
    {
      local $/=undef;
      $data = scalar(<$fh>);
    }

    r->print("
    <SCRIPT>
      function show_preview () {
        var f = window.document.FileManagerEditFile;
        var w = window.open('',
                  'FileManagerPreviewEditFile',
                  'scrollbars,resizable,menubar,status,toolbar');
        var d = w.document.open();
        d.write('<HTML><HEAD><BASE HREF=\"$base\"></HEAD>');
        d.write(f.FILEMANAGER_filedata.value);
        d.write('</HTML>');
        d.close();
        w.focus();
      }
      $$o{JS}
    </SCRIPT>

    <!-- Styles -->
    ".$o->html_style_sheet()."

    <FORM NAME=FileManagerEditFile
          ACTION='".r->uri."'
          METHOD=POST>

      ".$o->html_hidden_fields()."

      <INPUT TYPE=HIDDEN NAME=FILEMANAGER_editfile
             VALUE=\"".r->param('FILEMANAGER_editfile')."\">

      <!-- Header -->
      <TABLE WIDTH=100% CELLPADDING=0 CELLSPAING=0>
        <TR>
          <TD>
            <FONT COLOR=#3a3a3a><B>$base</B></FONT>
          </TD>
        </TR>
      </TABLE>

      <!-- Special message -->
      $message

      <TABLE CELLPADDING=2 CELLSPACING=2
             BORDER=0 WIDTH=100% BGCOLOR=#606060>

        <!-- Toolbar -->
        <TR>
          <TD ALIGN=CENTER>
            <TABLE CELLPADDING=0 CELLSPACING=0
                   BORDER=0 WIDTH=90%>
              <TR ALIGN=CENTER>
                <TD ALIGN=CENTER>
                  <INPUT TYPE=BUTTON VALUE='cancel'
                    onclick=\"
                      window.close();
                      return false;\">
                </TD>

                <TD ALIGN=CENTER>
                  <INPUT TYPE=BUTTON VALUE='preview'
                    onclick=\"
                      window.show_preview();
                      return false;\">
                </TD>

                <TD ALIGN=CENTER>
                  <INPUT TYPE=BUTTON VALUE='save'
                    onclick=\"
                      var f = window.document.FileManagerEditFile;
                      f.FILEMANAGER_cmd.value = 'savefiledata';
                      f.submit();
                      return false;\">
                </TD>
              </TR>
            </TABLE>
          </TD>
        </TR>

        <!-- file edit box -->
        <TR>
          <TD ALIGN=CENTER BGCOLOR=#efefef>
          <TEXTAREA NAME=FILEMANAGER_filedata
            COLS=$$o{EDIT_COLS}
            ROWS=$$o{EDIT_ROWS}>$data</TEXTAREA>
          </TD>
        </TR>

        <!-- Toolbar -->
        <TR>
          <TD ALIGN=CENTER>
            <TABLE CELLPADDING=0 CELLSPACING=0
                   BORDER=0 WIDTH=90%>
              <TR ALIGN=CENTER>
                <TD ALIGN=CENTER>
                  <INPUT TYPE=BUTTON VALUE='cancel'
                    onclick=\"
                      window.close();
                      return false;\">
                </TD>

                <TD ALIGN=CENTER>
                  <INPUT TYPE=BUTTON VALUE='preview'
                    onclick=\"
                      window.show_preview();
                      return false;\">
                </TD>

                <TD ALIGN=CENTER>
                  <INPUT TYPE=BUTTON VALUE='save'
                    onclick=\"
                      var f = window.document.FileManagerEditFile;
                      f.FILEMANAGER_cmd.value = 'savefiledata';
                      f.submit();
                      return false;\">
                </TD>
              </TR>
            </TABLE>
          </TD>
        </TR>
      </TABLE>
      <!-- Footer -->
      ".$o->html_bottom()."
    </FORM>
    ");
  }

  return undef;
}





###############################################################################
# ---- HTML Component Output ------------------------------------------------ #
###############################################################################

sub html_javascript {
  my $o = shift;

  my $hostname = r->hostname();
  my $cookie_name = uc($hostname);
  $cookie_name =~ s/[^A-Z]//g;
  $cookie_name .= "_FM";

  #start return literal
  return "
    <NOSCRIPT>
      <H1><FONT COLOR=#990000>please enable javascript</FONT></H1>
    </NOSCRIPT>
    <SCRIPT>
    <!--
    var cookie_name = '$cookie_name';

    function select_all () {
      var f = window.document.FileManager;
      var ck_stat;
      var ar = get_ckbox_array();

      if (ar.length > 0) {
        if (f.FILEMANAGER_last_select_all.value == '1') {
          ck_stat = false;
          f.FILEMANAGER_last_select_all.value = '0';
        } else {
          ck_stat = true;
          f.FILEMANAGER_last_select_all.value = '1';
        }
      }

      for (var i=0; i < ar.length; i++) {
        ar[i].checked = ck_stat;
      }
    }

    function display_help () {
      var w=window.open('', 'help',
                        'resizable=yes,scrollbars=yes,width=650,height=650');
      var d = w.document.open();
      d.write(
        \"<HTML> <UL><B><U><FONT SIZE=+1>Help</FONT></U></B><BR><BR>\"+

        \"<LI><A NAME=upload><B>How do I upload files?</B></A><BR>\"+
        \"Click on the upload menu item. After the <I>Upload Files</I>\"+
        \"window opens, click the <I>Browse</I> button. \"+
        \"This will pop open another window showing files on your computer. \"+
        \"Select a file you want to upload. You can not upload directories. \"+
        \"If you want to upload a directory, archive it first into a \"+
        \"<I>zip</I> file or a tarball. You will then be able to extract \"+
        \"it on the server. You can upload up to 10 files at a time. \"+
        \"After selecting the files you want to upload, click the \"+
        \"<I>upload</I> button to transfer the files from your machine to \"+
        \"the server.<BR><BR>\"+

        \"<LI><A NAME=move><B>How do I copy or move files?</B></A><BR>\"+
        \"First click the check boxes next to the file names that you would \"+
        \"like to copy or paste. Next click the <I>copy</I> or <I>paste</I> \"+
        \"button. Then go to the directory you would like them pasted in. \"+
        \"Finally, click <I>paste</I>.<BR><BR>\"+

        \"<LI><A NAME=move><B>Why does the file manager seem broken in \"+
        \"certain directories or when copying or pasting certain files?\"+
        \"</B></A><BR>\"+
        \"This occurs when the file manager does not have permission to \"+
        \"access these files. To fix the problem, contact your system \"+
        \"administrator and ask them to grant the webserver \"+
        \"READ, WRITE, and EXECUTE access to your files.<BR><BR>\"+

        \"</UL><CENTER>\"+
        \"<FORM><INPUT TYPE=BUTTON VALUE='close' onclick='window.close();'>\"+
        \"</FORM></CENTER></HTML>\");
      d.close();
      w.focus();
    }

    function getexpirydate(nodays){
      var UTCstring;
      Today = new Date();
      nomilli=Date.parse(Today);
      Today.setTime(nomilli+nodays*24*60*60*1000);
      UTCstring = Today.toUTCString();
      return UTCstring;
    }

    function getcookie(cookiename) {
      var cookiestring=''+document.cookie;
      var index1=cookiestring.indexOf(cookiename);
      if (index1==-1 || cookiename=='') return '';
      var index2=cookiestring.indexOf(';',index1);
      if (index2==-1) index2=cookiestring.length;
      escsubstring = cookiestring.substring(index1+cookiename.length+1, index2)
      return unescape(escsubstring);
    }

    function setcookie(name,value,duration){
      cookiestring=name+'='+escape(value)+';EXPIRES='+getexpirydate(duration);
      document.cookie=cookiestring;
      if (!getcookie(name)) {
        return false;
      } else{
        return true;
      }
    }

    function print_upload () {
      var w = window.open('','FileManagerUpload',
                          'scrollbars=yes,resizable=yes,width=500,height=440');
      var d = w.document.open();
      d.write(\"<HTML><BODY><CENTER><H1>Upload Files</H1>\"+
              \"<FORM NAME=UploadForm ACTION='".r->uri."' \"+
              \"      METHOD=POST onsubmit='window.opener.focus();' \"+
              \"      ENCTYPE=multipart/form-data>\"+
              \"  <INPUT TYPE=HIDDEN NAME=FILEMANAGER_curr_dir \"+
              \"         VALUE='".r->param('FILEMANAGER_curr_dir')."'>\");

      for (var i=1; i <= 10; i++) {
        d.write(\"<INPUT TYPE=FILE SIZE=40 NAME=FILEMANAGER_file\"+i+\"><BR>\");
      }
      d.write(\"<INPUT TYPE=BUTTON VALUE='cancel' onclick='window.close();'>\"+
              \"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"+
              \"<INPUT TYPE=SUBMIT NAME=FILEMANAGER_cmd\"+
              \"       VALUE=upload></CENTER></BODY></HTML>\");
      d.close();
      w.focus();
    }

    // make input check box form elements into an array ALL the time
    function get_ckbox_array() {
      var ar;
      sel_files = window.document.FileManager.FILEMANAGER_sel_files;

      // no files
      if (sel_files == null) {
        ar = new Array();
      }

      // 1 file (no length)
      else if (sel_files.length == null) {
        ar = [ sel_files ];
      }

      // more than one file
      else {
        ar = sel_files;
      }
      return ar;
    }


    // make array of check box objects that are selected
    function get_sel_ckbox_array() {
      var sel_ar = new Array();
      var ar = window.get_ckbox_array();

      for (var i=0; i < ar.length; i++) {
        if (ar[i].checked == true) {
          sel_ar.push(ar[i]);
        }
      }

      return sel_ar;
    }




    // get the number checked
    function get_num_checked() {
      var sel_ar = get_sel_ckbox_array();
      return sel_ar.length;
    }

    //function to edit file
    function edit_file () {
      var sel_ar = get_sel_ckbox_array();

      //make sure there is 1 and only 1 selected file
      if (sel_ar.length != 1) {
        window.alert('Please select ONE file to edit by clicking on a '+
                     'check box with the mouse.');
      }

FileManager.pm  view on Meta::CPAN

        window.setcookie(cookie_name,ac,1);
      }
    }

    //test if browser cookies are enabled
    if (! window.document.cookie ) {
      window.setcookie(cookie_name,'test',1);
      if (! window.document.cookie) {
          document.write('<H1><FONT COLOR=#990000>'+
                          'please enable cookies</FONT></H1>');
      }
      window.setcookie(cookie_name,'',-1);
    }
    $$o{JS}
    --></SCRIPT> "; #end return literal
}


sub html_style_sheet {
  return "
    <STYLE TYPE='text/css'>
      <!--
        BODY {
          background-color: white;
          font-family: serif;
          margin-top: 0;
          margin-right: 0;
          margin-bottom: 0;
          margin-left: 0;
          padding-top: 0;
          padding-bottom: 0;
          padding-right: 1;
          padding-left: 1;
          border-top: 0;
          border-bottom: 0;
          border-right: 0;
          border-left: 0;
          border-style: 0;
        }

        A:link {
          color: #990000;
          text-decoration: none;
        }

        A:visited {
          color: #990000;
          text-decoration: none;
        }

        A:hover {
          color: #990000;
          text-decoration: underline;
        }
    --> </STYLE>";
}


sub html_hidden_fields {
  return "
    <INPUT TYPE=HIDDEN NAME=FILEMANAGER_curr_dir
           VALUE='".r->param('FILEMANAGER_curr_dir')."'>
    <INPUT TYPE=HIDDEN NAME=FILEMANAGER_cmd VALUE=''>
    <INPUT TYPE=HIDDEN NAME=FILEMANAGER_arg VALUE=''>
    <INPUT TYPE=HIDDEN NAME=FILEMANAGER_last_select_all
           VALUE='".r->param('FILEMANAGER_last_select_all')."'>
    ";
}


sub html_location_toolbar {
  my $o = shift;

  my @loc = split /\//, r->param('FILEMANAGER_curr_dir');

  #already in base directory?
  return "<B>location: / </B>" if ($#loc == -1);

  #for all elements in the loc except the last one
  my @ac;
  my $up_a_href = "
    <A HREF=#
      onclick=\"
        var f=window.document.FileManager;
        f.FILEMANAGER_curr_dir.value='';
        f.submit();
        return false;\">
      <FONT COLOR=#006699 SIZE=+1><B>..</B></FONT></A>
      &nbsp;
    ";

  for (my $i = 0; $i < $#loc; $i++) {
    push @ac, $loc[$i];
    my $url = join("/", @ac);

    $loc[$i] = "
      <A HREF=#
        onclick=\"
          var f=window.document.FileManager;
          f.FILEMANAGER_curr_dir.value='$url';
          f.submit();
          return false;\">
        <FONT COLOR=#006699 SIZE=+1><B>".$loc[$i]."</B></FONT></A>
      ";

    if ($i == ($#loc - 1)) {
      $up_a_href = "
        <A HREF=#
          onclick=\"
            var f=window.document.FileManager;
            f.FILEMANAGER_curr_dir.value='$url';
            f.submit();
            return false;\">
          <FONT COLOR=#006699 SIZE=+1><B>..</B></FONT></A>
        &nbsp;
        ";
    }
  }

  $loc[$#loc] = "<FONT SIZE=+1><B>".$loc[$#loc]."</B></FONT>";

  my $location = "
    <B>location: </B>
    <A HREF=#
      onclick=\"

FileManager.pm  view on Meta::CPAN

      $size = "<TD ALIGN=CENTER>--</TD>";
      $type = "/"; # "/" designates "directory"
      $link = "<A HREF=#
                onclick=\"
                  var f=window.document.FileManager;
                  f.FILEMANAGER_curr_dir.value='"
                      .Apache2::Util::escape_path($curr_dir.$file, r->pool)."';
                  f.submit();
                  return false;\">
                <FONT COLOR=#006699>$file$type</FONT></A>";
    }

    #must be a file
    elsif (-f $file) {

      #get file size
      my $stat = stat($file);
      $size = $stat->size;
      if ($size > 1024000) {
        $size = sprintf("%0.2f",$size/1024000) . " <I>M</I>";
      } elsif ($stat->size > 1024) {
        $size = sprintf("%0.2f",$size/1024). " <I>K</I>";
      } else {
        $size = sprintf("%.2f",$size). " <I>b</I>";
      }
      $size =~ s/\.0{1,2}//;
      $size = "<TD NOWRAP ALIGN=RIGHT>$size</TD>";

      #get last modified
      $last_modified = $o->formated_date($stat->mtime);

      #get file type
      if (-S $file) {
        $type = "="; # "=" designates "socket"
      }
      elsif (-l $file) {
        $type = "@"; # "@" designates "link"
      }
      elsif (-x $file) {
        $type = "*"; # "*" designates "executable"
      }

      my $true_doc_root = r->document_root;
      my $fake_doc_root = $$o{DR};
      $fake_doc_root =~ s/^$true_doc_root//;
      $fake_doc_root =~ s/^\///; $fake_doc_root =~ s/\/$//;

      my $href = $curr_dir;
      $href = $fake_doc_root."/".$href if $fake_doc_root;

      $link = "
          <A HREF=\"/$href"."$file?nossi=1\"
             TARGET=_blank><FONT COLOR=BLACK>"
             .Apache2::Util::escape_path($file.$type, r->pool).
            "</FONT>
          </A>";
    }

    $acum .= "
        <TR BGCOLOR=#$bgcolor>
        <TD><INPUT TYPE=CHECKBOX NAME=FILEMANAGER_sel_files
                   VALUE='$curr_dir"."$file'></TD>
        <TD>$link</TD>
        <TD ALIGN=CENTER NOWRAP>$last_modified</TD>
        $size
        </TR>";

    #alternate bgcolor so it is easier to read
    $bgcolor = ( ($bgcolor eq "ffffff") ? "efefef" : "ffffff" );
  }

  #print a message if there were no files in this directory
  if ($ct_rows == 0) {
    $acum .= "
        <TR ALIGN=CENTER><TD COLSPAN=3>
          <TABLE BORDER=1 WIDTH=100% BGCOLOR=WHITE>
            <TR>
              <TD ALIGN=CENTER><BR><I>no files found</I><BR><BR></TD>
            </TR>
          </TABLE>
        </TD>
      </TR>";
  }

  return "
      <!-- Files list -->
      <TABLE CELLPADDING=3 CELLSPACING=0 WIDTH=100% BORDER=0>

      <!-- Headers -->
      <TR BGCOLOR=#606060>
        <TD WIDTH=1% ALIGN=CENTER>
          <A HREF=# onclick=\"
              window.select_all();
              return false;\"
          ><FONT COLOR=WHITE>+</FONT> </A>
        </TD>
        <TD WIDTH=80%>
            <FONT COLOR=WHITE><B>filename</B></FONT>
        </TD>
        <TD WIDTH=15% ALIGN=CENTER NOWRAP>
            <FONT COLOR=WHITE><B>last modified</B></FONT>
        </TD>
        <TD WIDTH=4% ALIGN=CENTER>
            <FONT COLOR=WHITE><B>size</B></FONT>
        </TD>
      </TR>

      <! -- Files -->
      $acum
      </TD></TR></TABLE>";
}


sub html_top {
  return "
      <TABLE WIDTH=100% CELLPADDING=0 CELLSPAING=0>
        <TR>
          <TD>
            <FONT SIZE=+2 COLOR=#3a3a3a>
              <B>".r->hostname." - file manager</B></FONT>
          </TD>



( run in 0.860 second using v1.01-cache-2.11-cpan-39bf76dae61 )