/** * Method for uploading a file * * @param array $file The file information * @param integer $dir The directory id * @param boolean $stream If set to true, use data stream * @param integer $parent_id If set, will try to move the original file to the revs folder * * @return mixed Array with file info on success, otherwise False */ public function upload($file = NULL, $dir = 0, $stream = false, $parent_id = 0) { // Dont allow upload to root dir if ((int) $dir <= 1) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_SELECT_DIRECTORY')); return false; } // Check allowed file extension $allowed = PFrepoHelper::getAllowedFileExtensions(); $config = JComponentHelper::getParams('com_pfrepo'); $user = JFactory::getUser(); $filter_admin = $config->get('filter_ext_admin'); $is_admin = $user->authorise('core.admin'); if ($is_admin && !$filter_admin) { $allowed = array(); } if (count($allowed)) { $ext = strtolower(JFile::getExt($file['name'])); if (!in_array($ext, $allowed)) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_INVALID_FILE_EXT')); return false; } } $query = $this->_db->getQuery(true); $query->select('project_id, path')->from('#__pf_repo_dirs')->where('id = ' . (int) $dir); $this->_db->setQuery($query); $dir = $this->_db->loadObject(); if (empty($dir)) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_SELECT_DIRECTORY')); return false; } $project = $dir->project_id; $uploadpath = PFrepoHelper::getBasePath() . '/' . $dir->path; if (!is_array($file) || !isset($file['tmp_name'])) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_NO_FILE_SELECTED')); return false; } // Try to create the upload path destination if (!JFolder::exists($uploadpath)) { if (!JFolder::create($uploadpath)) { return false; } } $errnum = (int) $file['error']; if ($errnum > 0) { $errmsg = PFrepoHelper::getFileErrorMsg($errnum, $file['name'], $file['size']); $this->setError($errmsg); return false; } // If we have a parent id, move it to the revisions folder first if ($parent_id) { $query->clear()->select('project_id, dir_id, file_name')->from('#__pf_repo_files')->where('id = ' . (int) $parent_id); $this->_db->setQuery($query); $head = $this->_db->loadObject(); if (empty($head)) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_HEAD_NOT_FOUND')); return false; } // Prepare file paths $head_dest = PFrepoHelper::getBasePath($head->project_id) . '/_revs/file_' . (int) $parent_id; $head_path = PFrepoHelper::getFilePath($head->file_name, $head->dir_id); if (empty($head_path)) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_HEAD_FILE_NOT_FOUND')); return false; } if (!JFolder::exists($head_dest)) { if (JFolder::create($head_dest) !== true) { return false; } } $head_path .= '/' . $head->file_name; $head_name = $this->generateNewFileName($head_dest, $head->file_name); $head_dest .= '/' . $head_name; // Move the file $move = JFile::move($head_path, $head_dest); if ($move !== true) { if (!is_bool($move)) { $this->setError($move); } return false; } } $name = $this->generateNewFileName($uploadpath, $file['name']); $ext = JFile::getExt($name); if ($stream) { // Check file size $flimit = PFrepoHelper::getMaxUploadSize(); $plimit = PFrepoHelper::getMaxPostSize(); $size = isset($_SERVER["CONTENT_LENGTH"]) ? (int) $_SERVER["CONTENT_LENGTH"] : 0; if ($flimit < $size) { $msg = JText::sprintf('COM_PROJECTFORK_WARNING_FILE_UPLOAD_ERROR_1', $name, $flimit); $this->setError($msg); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } elseif ($plimit < $size) { $msg = JText::sprintf('COM_PROJECTFORK_WARNING_FILE_UPLOAD_ERROR_9', $name, $plimit); $this->setError($msg); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } $fp = fopen("php://input", "r"); $temp = tmpfile(); if ($fp === false) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_STREAM_ERROR_1')); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } if ($temp === false) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_STREAM_ERROR_2')); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } $check = stream_copy_to_stream($fp, $temp); fclose($fp); if ($check != $size || empty($size)) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_STREAM_ERROR_3')); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } $dest = fopen($uploadpath . '/' . $name, "w"); if ($dest === false) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_STREAM_ERROR_4')); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } fseek($temp, 0, SEEK_SET); $check = stream_copy_to_stream($temp, $dest); fclose($dest); if ($check != $size) { $this->setError(JText::_('COM_PROJECTFORK_WARNING_FILE_STREAM_ERROR_5')); if ($parent_id) { JFile::move($head_dest, $head_path); } return false; } $file['size'] = $size; if ($parent_id) { // Rename the file name in the db if ($head_name != $head->file_name) { $query->clear()->update('#__pf_repo_files')->set('file_name = ' . $this->_db->quote($head_name))->where('id = ' . $parent_id); $this->_db->setQuery($query); $this->_db->execute(); } } return array('name' => $name, 'size' => $file['size'], 'extension' => $ext); } else { if (JFile::upload($file['tmp_name'], $uploadpath . '/' . $name) === true) { if ($parent_id) { // Rename the file name in the db if ($head_name != $head->file_name) { $query->clear()->update('#__pf_repo_files')->set('file_name = ' . $this->_db->quote($head_name))->where('id = ' . $parent_id); $this->_db->setQuery($query); $this->_db->execute(); } } return array('name' => $name, 'size' => $file['size'], 'extension' => $ext); } } if ($parent_id) { JFile::move($head_dest, $head_path); } return false; }