You are here

function webfm_ajax in Web File Manager 5

Same name and namespace in other branches
  1. 5.2 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 1048

Code

function webfm_ajax() {
  global $user;

  //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;
    }
    else {

      //no feedback
      exit;
    }
  }
  $webfm_root_path = webfm_get_root_path();
  if ($webfm_root_path == NULL) {

    //WebFM root dir must exist
    webfm_json(array(
      'status' => FALSE,
      'err' => t('WebFM root not set'),
    ));
    exit;
  }
  $root_dir = $webfm_perm == WEBFM_ADMIN ? file_directory_path() : file_directory_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($root_dir, $webfm_root_path);
        }
        else {

          //clear static array of roles with webfm access ($webfm_roots cached only for 'read' op)
          $webfm_roots = webfm_get_root_dirs(TRUE);
          if (count($webfm_roots)) {
            foreach ($webfm_roots as $key => $sub_root) {

              //Build webfm directory tree(s) for WEBFM_USER
              if (!empty($sub_root)) {
                $sub_root_path = $root_dir . $sub_root;
                if (is_dir($sub_root_path)) {
                  $current = $sub_root;
                  unset($_SESSION['tree_' . $current]);
                  $trees[$key] = webfm_tree($root_dir, $current);
                }
                else {
                  $err .= ' ' . $sub_root_path . t(' root dir not found.');
                }
              }
              else {
                $err .= t(' Root directory not set for @role role ', array(
                  '@role' => $webfm_access_roles[$key],
                ));
              }
            }
          }
          else {
            $err = t('No root directory set in WebFM settings for this role');
          }
        }
        if (count($trees)) {
          webfm_json(array(
            'status' => TRUE,
            'tree' => $trees,
            'current' => $webfm_root_path,
            'admin' => $webfm_perm == WEBFM_ADMIN,
            'err' => $err,
          ));
        }
        else {
          $err .= t(' No trees found.');
          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"])) {

            //role root must exist and this user must be a member of that role
            $webfm_roots = webfm_get_root_dirs();
            $root_role = trim(rawurldecode($_POST["param0"]));
            if (($root = variable_get("root_dir_" . $root_role, '')) && array_key_exists($root_role, $webfm_roots)) {
              $current = "/" . $root;
            }
          }
        }
        if (!isset($current)) {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('unknown tree'),
          ));
          exit;
          break;
        }
        if (isset($_POST["param1"])) {
          unset($_SESSION['tree_' . $current]);
        }
        if (!is_dir($root_dir . $current)) {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('unknown role'),
          ));
        }
        else {
          $tree = webfm_tree($root_dir, $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"])) {
          $param0 = trim(rawurldecode($_POST["param0"]));
          if (ereg('\\.\\.', $param0)) {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('illegal read dir'),
            ));
            exit;
          }

          // Test access rights
          $perm_flag = FALSE;
          if ($webfm_perm == WEBFM_ADMIN) {

            // WEBFM_ADMIN always has access
            if (webfm_check_path($param0, $webfm_root_path)) {
              $perm_flag = TRUE;
            }
          }
          else {

            // If WEBFM_USER, test that read path is inside a legit root dir
            $webfm_roots = webfm_get_root_dirs();
            foreach ($webfm_roots as $key => $sub_root) {

              // The read path must be contained within a legitimate role root dir for this user
              if ($sub_root && webfm_check_path($param0, $sub_root)) {
                $perm_flag = TRUE;
                break;
              }
            }
          }
          if ($perm_flag) {
            if (!is_dir($root_dir . $param0)) {
              webfm_json(array(
                'status' => FALSE,
                'data' => $root_dir . $param0 . t(' path does not exist - refresh required'),
              ));
              exit;
            }

            //Build current directory listings
            $dirlist = new webfm_build_dir_list($root_dir, $param0, $webfm_perm);
            if ($dirlist
              ->get_breadcrumb()) {
              webfm_json(array(
                'status' => TRUE,
                'current' => $param0,
                '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' => t('invalid dir'),
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('forbidden dir'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('insufficient params'),
          ));
        }
        exit;
        break;
      case "delete":

        // Get path of object to be deleted
        if (isset($_POST["param0"])) {
          $param0 = trim(rawurldecode($_POST["param0"]));

          // prevent any .. shenanigans
          if ($param0 && !ereg('\\.\\.', $param0)) {
            $source = $root_dir . $param0;
            if (is_dir($source)) {

              //Only admins can delete directories (and contained files)
              if ($webfm_perm == WEBFM_ADMIN) {
                $err_arr[] = array();
                $ret = webfm_delete_dir_recur($source, TRUE, $err_arr);
                webfm_json(array(
                  'status' => $ret,
                  'data' => $err_arr,
                ));
                exit;
                break;
              }
            }
            else {
              if (is_file($source)) {
                $permit = FALSE;
                $file = webfm_get_file_record('', $source);
                if ($webfm_perm == WEBFM_ADMIN) {

                  // Admins can delete files
                  $permit = TRUE;
                }
                else {
                  if ($file) {
                    if ($user->uid == $file->uid || webfm_file_mod_access($file)) {

                      // File owner can delete the file
                      // Files marked as modifiable by role can be deleted
                      $permit = TRUE;
                    }
                  }
                }
                if ($permit) {

                  // Delete file and file record if in db
                  $error = "";
                  $ret = TRUE;
                  if (@unlink($source)) {
                    if ($file && !webfm_dbdelete_file($file->fid)) {
                      $error = t('webfm_dbdelete_file() fail for ') . $source;
                      $ret = FALSE;
                    }
                  }
                  else {
                    if (file_exists($source)) {
                      $error = $source . t(' could not be deleted');
                      $ret = FALSE;
                    }
                  }
                  webfm_json(array(
                    'status' => $ret,
                    'data' => $error,
                  ));
                  exit;
                  break;
                }
              }
            }
          }
          webfm_json(array(
            'status' => FALSE,
            'data' => t('permission denied'),
          ));
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('insufficient params'),
          ));
        }
        exit;
        break;

      //Create new directory
      case "mkdir":

        //Only admins can create directories
        if ($webfm_perm == WEBFM_ADMIN) {
          if (isset($_POST["param0"])) {
            $source = $root_dir . 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
            if (($ret = webfm_mkdir($source, $dest, TRUE, $err_arr)) !== FALSE) {
              $ret = ltrim($ret, $root_dir);
              webfm_json(array(
                'status' => TRUE,
                'data' => $ret,
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => $err_arr,
              ));
            }
            if ($ret) {
              unset($_SESSION['tree_' . $webfm_root_path]);
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('insufficient params'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('permission denied'),
          ));
        }
        exit;
        break;

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

            //Only admins can manipulate directories
            webfm_json(array(
              'status' => FALSE,
              'data' => t('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' => t('illegal destination path'),
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('move operation not permitted'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('insufficient params'),
          ));
        }
        exit;
        break;

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

          // prevent any ../ shenanigans
          if (!ereg('\\.\\.', $dest) && dirname(rawurldecode($_POST["param0"])) == dirname(rawurldecode($_POST["param1"]))) {
            $err_arr[] = array();

            //rename permissions inside webfm_rename
            $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' => t('illegal name'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('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($root_dir, $source, $searchpattern, $regexpsearch, $webfm_perm == WEBFM_USER ? $user->uid : 1);
            webfm_json(array(
              'files' => $search
                ->get_files(),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('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) {

            //presence of fid used to grant js metadata access
            if ($webfm_perm == WEBFM_ADMIN || $user->uid == $file->uid || webfm_file_mod_access($file) || webfm_file_view_access($file)) {
              $meta = array();

              //presence of fid used to grant js metadata access
              if ($webfm_perm == WEBFM_ADMIN || $user->uid == $file->uid || webfm_file_mod_access($file)) {
                $meta['id'] = $file->fid;
                if ($webfm_perm == WEBFM_ADMIN) {

                  // Only admins get uid
                  $meta['u'] = $file->uid;
                }
              }
              $query = 'SELECT name FROM {users} WHERE uid = %d';
              $meta['un'] = db_result(db_query($query, $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;
              $meta['c'] = $file->dl_cnt;
              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];
                }
              }
              if ($file->perm & WEBFM_FILE_ACCESS_PUBLIC_VIEW) {

                //permissions allow file to be linked for public view
                global $base_url;
                $meta['lk'] = '<a href="' . $base_url . '/webfm_send/' . $file->fid . '">' . $meta['n'] . '</a>';
              }
              webfm_json(array(
                'status' => TRUE,
                'data' => $meta,
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => t('permission denied'),
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('file record not found'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('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' => t('insufficient params'),
          ));
        }
        exit;
        break;

      //Get file permissions
      case "getperm":
        if (isset($_POST["param0"])) {
          $fid = rawurldecode($_POST["param0"]);
          if (($file = webfm_get_file_record($fid)) !== FALSE) {
            if ($webfm_perm == WEBFM_ADMIN || $user->uid == $file->uid || webfm_file_mod_access($file)) {
              $perm = array();
              $perm['id'] = $file->fid;
              $perm['u'] = $file->uid;
              $perm['n'] = strrev(substr(strrev($file->fpath), 0, strpos(strrev($file->fpath), '/')));
              $perm['p'] = $file->perm;
              webfm_json(array(
                'status' => TRUE,
                'data' => $perm,
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => t('permission denied'),
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('file record not found'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('insufficient params'),
          ));
        }
        exit;
        break;

      //Change file permissions
      case "putperm":
        if (isset($_POST["param0"]) && isset($_POST["param1"])) {
          $fid = rawurldecode($_POST["param0"]);
          if (($file = webfm_get_file_record($fid)) !== FALSE) {
            if ($webfm_perm == WEBFM_ADMIN || $user->uid == $file->uid || webfm_file_mod_access($file)) {
              $perm = array();
              $msg = '';
              $perm['perm'] = (int) rawurldecode($_POST["param1"]);
              $status = FALSE;

              // Validate permission value
              if ($perm['perm'] >= 0 && $perm['perm'] <= WEBFM_MAX_FILE_ACCESS) {
                if (webfm_dbupdate_file($fid, '', $perm)) {

                  // Send back permissions to confirm value for form reset
                  $msg = t('Permissions saved');
                  $status = TRUE;
                }
                else {
                  $msg = t('webfm_dbupdate_file() fail');
                }
              }
              else {
                $msg = t('invalid permission');
              }
            }
            else {
              $msg = t('permission denied');
            }
          }
          else {
            $msg = t('file record not found');
          }
        }
        else {
          $msg = t('insufficient params');
        }
        webfm_json(array(
          'status' => $status,
          'data' => $perm,
          'msg' => $msg,
        ));
        exit;
        break;

      //Get attached items
      case "attach":
        global $node;
        if (isset($_POST["param0"])) {

          // If $_POST["param1"] is set, we are in a preview or validation failure
          // and have fids stored in the edit-attachments form, those that we fetched
          // from the database before and those which are not yet attached (during
          // a preview). Those fids are transfered through param1.
          if (isset($_POST["param1"])) {
            $fids = trim(strtolower(rawurldecode($_POST["param1"])));
            webfm_json(array(
              'status' => TRUE,
              'data' => webfm_get_temp_attachments($fids),
              'admin' => 'attach',
            ));
            exit;
            break;
          }

          // Here we are in the edit form for the first time.
          $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,
              'data' => webfm_get_attachments($node_arr[1]),
              'admin' => 'attach',
            ));
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('illegal path'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('insufficient params'),
          ));
        }
        exit;
        break;

      //Get file for attachment to node
      case "attachfile":
        if (isset($_POST["param0"])) {

          // param0 = fid
          $fid = rawurldecode($_POST["param0"]);
          if (($_file = webfm_get_file_record($fid)) !== FALSE) {
            if ($webfm_perm == WEBFM_ADMIN || $user->uid == $_file->uid || webfm_file_mod_access($_file) || webfm_file_att_access($_file)) {
              $file = new webfm_fdesc($_file);
              if ($file->result != FALSE) {
                webfm_json(array(
                  'status' => TRUE,
                  'data' => $file,
                  'admin' => 'attach',
                ));
              }
              else {
                webfm_json(array(
                  'status' => FALSE,
                  'data' => t('file ') . $fid . t(' path not found'),
                ));
              }
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => t('invalid permission'),
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('file ') . $fid . t(' record not found'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('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 = $root_dir . 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' => t('insufficient params'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('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' => t('webfm_dbdelete_file() success'),
              ));
            }
            else {
              webfm_json(array(
                'status' => FALSE,
                'data' => t('file not in db'),
              ));
            }
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('insufficient params'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('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) {
            $ver_data = array();
            $ver_data['msg'] = 'Upload Fail';
            $ret = webfm_version_upload($op, $msg);
            if ($ret) {
              $ver_data['fid'] = $ret;
              $ver_data['msg'] = t('Upload Success');
            }
            webfm_json(array(
              'status' => $ret,
              'data' => $ver_data,
            ));
          }
          else {
            webfm_json(array(
              'status' => FALSE,
              'data' => t('invalid file name'),
            ));
          }
        }
        else {
          webfm_json(array(
            'status' => FALSE,
            'data' => t('insufficient params'),
          ));
        }

        // clear uploaded file
        unset($_SESSION['temp_upload']);
        exit;
        break;
      default:
        webfm_json(array(
          'status' => FALSE,
          'data' => t('illegal operation'),
        ));
        exit;
        break;
    }
    exit;
  }
  exit;
}