You are here

function webfm_ajax in Web File Manager 5.2

Same name and namespace in other branches
  1. 5 webfm.module \webfm_ajax()

Ajax post requests

1 string reference to 'webfm_ajax'
webfm_menu in ./webfm.module
Implementation of hook_menu().

File

./webfm.module, line 758

Code

function webfm_ajax() {
  global $user;
  static $webfm_root_path;
  static $webfm_access_roles = array();
  static $webfm_roots = array();

  //3 possible outcomes - the user is either an admin, user or prohibited
  if ($user->uid == 1 || user_access('administer webfm')) {

    // Admins have total access
    $webfm_perm = WEBFM_ADMIN;
  }
  else {
    if (user_access('access webfm')) {
      $webfm_perm = WEBFM_USER;

      // Roles with 'access webfm' perm
      if (!count($webfm_access_roles)) {
        $webfm_access_roles = user_roles(TRUE, 'access webfm');
        $webfm_roots = array();
        foreach ($user->roles as $key => $role) {
          if (in_array($role, $webfm_access_roles)) {

            // Roles with 'access webfm' perm that user possesses
            $path = variable_get("root_dir_" . $key, '');
            $webfm_roots[$key] = empty($path) ? NULL : "/" . $path;
          }
        }
      }
    }
    else {

      //no feedback
      exit;
    }
  }

  //Get root directory of module
  if (empty($webfm_root_path)) {
    $webfm_root_path = variable_get('webfm_root_dir', '');
    if (empty($webfm_root_path)) {

      //WebFM root dir must exist
      webfm_json(array(
        'status' => FALSE,
        'err' => t('WebFM root not set'),
      ));
      exit;
    }
    else {
      $webfm_root_path = '/' . $webfm_root_path;
    }
  }
  if (isset($_POST["action"])) {
    switch (trim(strtolower($_POST["action"]))) {

      //Read directory trees
      case "readtrees":
        $trees = array();
        $err = '';
        if ($webfm_perm == WEBFM_ADMIN) {

          //Build webfm directory tree
          unset($_SESSION['tree_' . $webfm_root_path]);
          $trees[0] = webfm_tree($webfm_root_path);
        }
        else {
          foreach ($webfm_roots as $key => $sub_root) {

            //Build webfm directory tree(s) for WEBFM_USER
            if (!empty($sub_root)) {
              $sub_root_path = file_directory_path() . $webfm_root_path . $sub_root;
              if (is_dir($sub_root_path)) {
                $current = $webfm_root_path . $sub_root;
                unset($_SESSION['tree_' . $current]);
                $trees[$key] = webfm_tree($current);
              }
            }
            else {
              $err .= t('root directory not set for @role role ', array(
                '@role' => $webfm_access_roles[$key],
              ));
            }
          }
        }

        //clear static array of roles with webfm access ($webfm_roots cached only for 'read' op)
        $webfm_access_roles = array();
        if (count($trees)) {
          webfm_json(array(
            'status' => TRUE,
            'tree' => $trees,
            'current' => $webfm_root_path,
            'admin' => $webfm_perm == WEBFM_ADMIN,
            'err' => $err,
          ));
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'err' => $err,
          ));
        }
        exit;
        break;

      //Read directory tree
      case "readtree":
        $tree = '';
        unset($current);
        if ($webfm_perm == WEBFM_ADMIN) {

          //Build webfm directory tree
          $current = $webfm_root_path;
        }
        else {
          if (isset($_POST["param0"])) {
            if ($root = variable_get("root_dir_" . trim(rawurldecode($_POST["param0"])), '')) {
              $root = "/" . $root;
              $current = $webfm_root_path . $root;
            }
          }
        }
        if (!isset($current)) {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'unknown tree',
          ));
          exit;
          break;
        }
        if (isset($_POST["param1"])) {
          unset($_SESSION['tree_' . $current]);
        }
        if (!is_dir(file_directory_path() . $current)) {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'unknown role',
          ));
        }
        else {
          $tree = webfm_tree($current);
          webfm_json(array(
            'status' => isset($tree) ? TRUE : FALSE,
            'tree' => $tree,
            'current' => $current,
            'admin' => $webfm_perm == WEBFM_ADMIN,
          ));
        }
        exit;
        break;

      //Read directory set in $_POST["param0"]
      case "read":
        if (isset($_POST["param0"])) {
          $read_dir = trim(rawurldecode($_POST["param0"]));
          if (ereg('\\.\\.', $read_dir)) {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'illegal read dir',
            ));
            exit;
          }

          // If WEBFM_USER, test that read path is inside a legal root dir
          $perm_flag = FALSE;
          if ($webfm_perm == WEBFM_ADMIN) {
            if (webfm_check_path($read_dir, $webfm_root_path)) {
              $perm_flag = TRUE;
            }
          }
          else {
            foreach ($webfm_roots as $key => $sub_root) {
              if ($sub_root && webfm_check_path($read_dir, $webfm_root_path . $sub_root)) {
                $perm_flag = TRUE;
                break;
              }
            }
          }
          if ($perm_flag) {
            if (!is_dir(file_directory_path() . $read_dir)) {
              webfm_json(array(
                'status' => FALSE,
                'data' => file_directory_path() . $read_dir . ' path does not exist - refresh required',
              ));
              exit;
            }

            //Build current directory listings
            $dirlist = new webfm_build_dir_list(file_directory_path(), $read_dir, $webfm_perm);
            if ($dirlist
              ->get_breadcrumb()) {
              webfm_json(array(
                'status' => TRUE,
                'current' => $read_dir,
                'bcrumb' => $dirlist
                  ->get_breadcrumb(),
                'dirs' => $dirlist
                  ->get_dir_listing(),
                'files' => $dirlist
                  ->get_file_listing(),
                'user' => $user->uid,
                'admin' => $webfm_perm == WEBFM_ADMIN,
              ));
            }
            else {

              //invalid directory
              webfm_json(array(
                'status' => FALSE,
                'data' => 'invalid dir',
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'forbidden dir',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;
      case "delete":

        //Only admins can delete directories
        if (isset($_POST["param0"])) {
          $source = file_directory_path() . trim(rawurldecode($_POST["param0"]));
          if (is_dir($source) && $webfm_perm != WEBFM_ADMIN) {

            //Only admins can delete directories
            webfm_json(array(
              'status' => FALSE,
              'data' => 'permission denied',
            ));
            exit;
            break;
          }

          // prevent any ../ shenanigans
          if ($source && !ereg('\\.\\.', $source)) {
            $err_arr[] = array();
            $ret = webfm_delete($source, $webfm_perm == WEBFM_USER ? $user->uid : 1, $err_arr);
            webfm_json(array(
              'status' => $ret,
              'data' => $err_arr,
            ));
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'illegal dirname',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;

      //Create new directory
      case "mkdir":

        //Only admins can create directories
        if ($webfm_perm == WEBFM_ADMIN) {
          if (isset($_POST["param0"])) {
            $source = file_directory_path() . trim(rawurldecode($_POST["param0"]));
            $dest = t("New_Folder");
            $err_arr[] = array();

            // third param is right to rename if a dir of same name already
            // exixts in current folder
            $ret = webfm_mkdir($source, $dest, TRUE, $err_arr);
            webfm_json(array(
              'status' => $ret,
              'data' => $err_arr,
            ));

            //          if($ret)
            //            unset($_SESSION['tree_'.$webfm_root_path]);
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'insufficient params',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'permission denied',
          ));
        }
        exit;
        break;

      //Move a file or directory (drag and drop)
      case "move":
        if (isset($_POST["param0"]) && isset($_POST["param1"])) {
          $source = file_directory_path() . trim(rawurldecode($_POST["param0"]));
          $dest = file_directory_path() . trim(rawurldecode($_POST["param1"]));
          if (is_dir($source) && $webfm_perm != WEBFM_ADMIN) {

            //Only admins can manipulate directories
            webfm_json(array(
              'status' => FALSE,
              'data' => 'permission denied',
            ));
            exit;
            break;
          }
          if ($source != $dest) {

            // prevent any ../ shenanigans
            if (!ereg('\\.\\.', $dest)) {
              $err_arr[] = array();
              $ret = webfm_move($source, $dest, $webfm_perm == WEBFM_USER ? $user->uid : 1, $err_arr);
              webfm_json(array(
                'status' => $ret,
                'data' => $err_arr,
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => 'illegal destination path',
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'move operation not permitted',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;

      //Rename an existing file or directory
      case "rename":
        if (isset($_POST["param0"]) && isset($_POST["param1"])) {
          $source = file_directory_path() . trim(rawurldecode($_POST["param0"]));
          $dest = file_directory_path() . trim(rawurldecode($_POST["param1"]));

          // prevent any ../ shenanigans
          if (!ereg('\\.\\.', $dest)) {
            $err_arr[] = array();

            //rename permissions inside webfm_rename (users can change own files)
            $ret = webfm_rename($source, $dest, $webfm_perm == WEBFM_USER ? $user->uid : 1, $err_arr);
            webfm_json(array(
              'status' => $ret,
              'data' => $err_arr,
            ));
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'illegal name',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;

      //Search current directory for filename
      case "search":
        if (isset($_POST["param0"]) && isset($_POST["param1"])) {
          $source = trim(rawurldecode($_POST["param0"]));
          $searchpattern = trim(rawurldecode($_POST["param1"]));
          if ($searchpattern != "") {
            $regexpsearch = '';
            @clearstatcache();
            $search = new webfm_searchFiles($source, $searchpattern, $regexpsearch, $webfm_perm == WEBFM_USER ? $user->uid : 1);
            webfm_json(array(
              'files' => $search
                ->get_files(),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;

      //Get file metadata
      case "getmeta":
        if (isset($_POST["param0"])) {
          $fid = rawurldecode($_POST["param0"]);
          if (($file = webfm_get_file_record($fid)) !== FALSE) {
            $meta = array();

            //presence of fid used to grant js metadata access
            if ($webfm_perm == WEBFM_ADMIN || $user->uid == $file->uid) {
              $meta['id'] = $file->fid;
            }
            $meta['u'] = $file->uid;
            $meta['n'] = strrev(substr(strrev($file->fpath), 0, strpos(strrev($file->fpath), '/')));
            $meta['t'] = $file->ftitle;
            $meta['d'] = $file->fdesc;
            $meta['l'] = $file->flang;
            $meta['p'] = $file->fpublisher;
            $meta['f'] = $file->fformat;
            if ($i = @getimagesize($file->fpath)) {
              if ($i[0] != 0 && $i[1] != 0) {
                $meta['i'] = (int) $i[2];
                $meta['w'] = (int) $i[0];
                $meta['h'] = (int) $i[1];
              }
            }
            webfm_json(array(
              'status' => TRUE,
              'meta' => $meta,
            ));
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'file record not found',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;

      //Change file metadata
      case "putmeta":
        if (isset($_POST["param0"]) && isset($_POST["param1"])) {

          //permission check in webfm_putmeta so single access to webfm_file table
          $ret = webfm_putmeta(rawurldecode($_POST["param0"]), rawurldecode($_POST["param1"]), $webfm_perm == WEBFM_ADMIN ? 1 : $user->uid, $err);
          webfm_json(array(
            'status' => $ret,
            'data' => $err,
          ));
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'unknown action',
          ));
        }
        exit;
        break;

      //Get attached items
      case "attach":
        global $node;

        //if user can see attachments - they can make attachments
        $node_str = trim(strtolower(rawurldecode($_POST["param0"])));

        // the 'node' var passed via AJAX is the action attribute of id=node-form
        if (($node_num = strstr($node_str, 'node/')) !== FALSE) {
          $node_arr = explode("/", $node_num);

          //'admin' is true (allow drag&drop) since only owners of a node can edit it
          webfm_json(array(
            'status' => TRUE,
            'attach' => webfm_get_attachments($node_arr[1]),
            'admin' => 'attach',
          ));
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'illegal path',
          ));
        }
        exit;
        break;

      //Get file info by fid for attachment
      case "attachfile":
        if (isset($_POST["param0"])) {

          // param0 = fid
          $fid = rawurldecode($_POST["param0"]);
          if (($_file = webfm_get_file_record($fid)) !== FALSE) {
            $file = new webfm_fdesc($_file);
            if ($file->result != FALSE) {
              webfm_json(array(
                'status' => TRUE,
                'attach' => $file,
                'admin' => 'attach',
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => 'file ' . $fid . ' path not found',
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'file ' . $fid . ' record not found',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        exit;
        break;
      case "insert":

        //Only admins can insert files into database
        if ($webfm_perm == WEBFM_ADMIN) {
          if (isset($_POST["param0"]) && isset($_POST["param1"])) {
            $source = file_directory_path() . trim(rawurldecode($_POST["param0"]));
            $err_arr[] = array();
            $result = FALSE;
            switch (trim(rawurldecode($_POST["param1"]))) {
              case "file":

                //dir insert methods already return class object
                $ret = webfm_insert_file($source, $err_arr);
                $result = new stdClass();
                $result->cnt = 0;
                $result->errcnt = 0;
                $result->err = '';
                if (!$ret) {
                  $result->errcnt = 1;
                  $result->err = $err_arr;
                  webfm_json(array(
                    'status' => FALSE,
                    'data' => $result,
                  ));
                }
                else {
                  $result->cnt = 1;
                  webfm_json(array(
                    'status' => TRUE,
                    'data' => $result,
                  ));
                }
                break;
              case "dir":
                $result = webfm_insert_dir($source, FALSE, $err_arr);
                if ($result->errcnt) {
                  $result->err = $err_arr;
                }
                webfm_json(array(
                  'status' => $result->cnt > 0,
                  'data' => $result,
                ));
                break;
              case "recur":
                $result = webfm_insert_dir($source, TRUE, $err_arr);
                if ($result->errcnt) {
                  $result->err = $err_arr;
                }
                webfm_json(array(
                  'status' => $result->cnt > 0,
                  'data' => $result,
                ));
                break;
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'insufficient params',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'permission denied',
          ));
        }
        exit;
        break;
      case "dbrem":

        //Only admins can remove files from database
        if ($webfm_perm == WEBFM_ADMIN) {
          if (isset($_POST["param0"])) {
            if ($ret = trim(rawurldecode($_POST["param0"]))) {
              $ret = webfm_dbdelete_file($ret);
              webfm_json(array(
                'status' => $ret,
                'data' => 'webfm_dbdelete_file() success',
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => 'file not in db',
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'insufficient params',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'permission denied',
          ));
        }
        exit;
        break;
      case "version":
        if (isset($_POST["param0"]) && isset($_POST["param1"])) {
          $op = trim(rawurldecode($_POST["param0"]));
          $filename = trim(rawurldecode($_POST["param1"]));
          if (strcmp($_SESSION['temp_upload']->filename, $filename) === 0) {
            switch ($op) {
              case CANCEL:

                //Cancel button
                webfm_json(array(
                  'status' => FALSE,
                  'data' => 'Upload Cancelled',
                ));
                break;
              case RENAME_NEW:

                // Insert new file into database with munged name & auto-incremented fid
                if (file_move($_SESSION['temp_upload'], $_SESSION['temp_upload']->dest)) {

                  // file was moved to its final destination
                  if ($_SESSION['temp_upload']->db_check == TRUE) {

                    //Insert file into database if under webfm_root
                    if (webfm_dbinsert_file($_SESSION['temp_upload'], $err)) {

                      // file was inserted into the database
                      webfm_json(array(
                        'status' => TRUE,
                        'data' => 'Upload success',
                      ));
                    }
                    else {
                      file_delete($_SESSION['temp_upload']->filepath);
                      webfm_json(array(
                        'status' => FALSE,
                        'data' => 'file insertion failed',
                      ));
                    }
                  }
                  else {

                    // Uploaded to non-db-controlled area
                    webfm_json(array(
                      'status' => TRUE,
                      'data' => 'Upload success',
                    ));
                  }
                }
                else {
                  webfm_json(array(
                    'status' => FALSE,
                    'data' => 'file_move to ' . $_SESSION['temp_upload']->dest . 'failed',
                  ));
                }
                break;
              case REPLACE_RENAME:

                // Retrieve file record for original file
                // Rename (munge) original file
                // Move new file to destination
                // Update existing original record with data from new file
                // Create new db record for original file
                // Restore original file if error
                $path = $_SESSION['temp_upload']->dest . '/' . $_SESSION['temp_upload']->filename;
                if ($_SESSION['temp_upload']->db_check == TRUE) {
                  if (($record = webfm_get_file_record('', $path)) === FALSE) {
                    webfm_json(array(
                      'status' => FALSE,
                      'data' => 'Replace-Delete webfm_get_file_record fail',
                    ));
                    break;
                  }
                }
                if ($pos = strrpos($path, '.')) {
                  $name = substr($path, 0, $pos);
                  $ext = substr($path, $pos);
                }
                else {
                  $name = $basename;
                }
                $counter = 0;
                do {
                  $temp_path = $name . '_' . $counter++ . $ext;
                } while (file_exists($temp_path));
                rename($path, $temp_path);
                if (file_move($_SESSION['temp_upload'], $_SESSION['temp_upload']->dest)) {

                  // file was moved to its final destination
                  if ($_SESSION['temp_upload']->db_check == TRUE) {

                    //Insert file into database if under webfm_root
                    $time = @filemtime($_SESSION['temp_upload']->filepath);
                    $row = db_query("UPDATE {webfm_file} SET fsize = %d, fcreatedate = %d, fversion = %d  WHERE fid = %d", $_SESSION['temp_upload']->filesize, $time, $record->fversion + 1, $record->fid);
                    if ($row === FALSE) {
                      webfm_json(array(
                        'status' => FALSE,
                        'data' => 'Replace-Delete update fail',
                      ));

                      // Delete new file and restore name of original file
                      file_delete($path);
                      rename($temp_path, $path);
                    }
                    else {
                      webfm_json(array(
                        'status' => TRUE,
                        'data' => 'Upload success',
                      ));
                      $newfile = new stdClass();
                      $newfile->filepath = $temp_path;
                      $newfile->filesize = $record->fsize ? $record->fsize : filesize($temp_path);
                      $newfile->filemime = $record->fmime;
                      webfm_dbinsert_file($newfile, $err, (array) $record);
                    }
                  }
                  else {

                    // Uploaded to non-db-controlled area
                    webfm_json(array(
                      'status' => TRUE,
                      'data' => 'Upload success',
                    ));
                  }
                }
                else {
                  webfm_json(array(
                    'status' => FALSE,
                    'data' => 'file_move fail',
                  ));
                  rename($temp_path, $path);
                }
                break;
              case REPLACE_DELETE:

                // Retrieve db record for original file & rename file
                // Move new file to destination
                // Update existing original record with data from new file
                // Restore original file if error, else delete
                $path = $_SESSION['temp_upload']->dest . '/' . $_SESSION['temp_upload']->filename;
                if ($_SESSION['temp_upload']->db_check == TRUE) {
                  if (($record = webfm_get_file_record('', $path)) === FALSE) {
                    webfm_json(array(
                      'status' => FALSE,
                      'data' => 'Replace-Delete webfm_get_file_record fail',
                    ));
                    break;
                  }
                }

                //use temp for rollback on error
                $temp_path = $path . '~';
                rename($path, $temp_path);
                if (file_move($_SESSION['temp_upload'], $_SESSION['temp_upload']->dest)) {

                  // file was moved to its final destination
                  if ($_SESSION['temp_upload']->db_check == TRUE) {

                    //Insert file into database if under webfm_root
                    $time = @filemtime($_SESSION['temp_upload']->filepath);
                    $row = db_query("UPDATE {webfm_file} SET fsize = %d, fcreatedate = %d, fversion = %d  WHERE fid = %d", $_SESSION['temp_upload']->filesize, $time, $record->fversion + 1, $record->fid);
                    if ($row === FALSE) {
                      webfm_json(array(
                        'status' => FALSE,
                        'data' => 'Replace-Delete update fail',
                      ));

                      // Delete new file and restore name of original file
                      file_delete($path);
                      rename($temp_path, $path);
                    }
                    else {
                      webfm_json(array(
                        'status' => TRUE,
                        'data' => 'Upload success',
                      ));
                      file_delete($temp_path);
                    }
                  }
                  else {

                    // Uploaded to non-db-controlled area
                    webfm_json(array(
                      'status' => TRUE,
                      'data' => 'Upload success',
                    ));
                    file_delete($temp_path);
                  }
                }
                else {
                  webfm_json(array(
                    'status' => FALSE,
                    'data' => 'file_move fail',
                  ));
                  rename($temp_path, $path);
                }
                break;
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => 'invalid file name',
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => 'insufficient params',
          ));
        }
        unset($_SESSION['temp_upload']);
        exit;
        break;
      default:
        webfm_json(array(
          'status' => FALSE,
          'data' => 'illegal operation',
        ));
        exit;
        break;
    }
    exit;
  }
  exit;
}