* * Licensed under AGPLv3 * (see COPYING for full license text) * */ class Mmultipaste extends CI_Model { function __construct() { parent::__construct(); $this->load->model("muser"); $this->load->model("mfile"); } /** * Returns an unused ID * * @param min minimal length of the resulting ID * @param max maximum length of the resulting ID */ public function new_id($min = 3, $max = 6) { static $id_blacklist = NULL; if ($id_blacklist == NULL) { // This prevents people from being unable to access their uploads // because of URL rewriting $id_blacklist = scandir(FCPATH); $id_blacklist[] = "file"; $id_blacklist[] = "user"; } $max_tries = 100; for ($try = 0; $try < $max_tries; $try++) { $id = "m-".random_alphanum($min, $max); // TODO: try to insert the id into file_groups instead of checking with // id_exists (prevents race conditio) if ($this->id_exists($id) || in_array($id, $id_blacklist)) { continue; } $this->db->insert("multipaste", array( "url_id" => $id, "user_id" => $this->muser->get_userid(), "date" => time(), )); return $id; } throw new \exceptions\PublicApiException("file/new_id-try-limit", "Failed to find unused ID after $max_tries tries"); } public function id_exists($id) { if (!$id) { return false; } $sql = ' SELECT url_id FROM '.$this->db->dbprefix.'multipaste WHERE url_id = ? LIMIT 1'; $query = $this->db->query($sql, array($id)); return $query->num_rows() == 1; } public function valid_id($id) { $files = $this->get_files($id); if (count($files) === 0) { return false; } foreach ($files as $file) { if (!$this->mfile->valid_id($file["id"])) { return false; } } return true; } function adopt($id) { $userid = $this->muser->get_userid(); $this->db->set(array('user_id' => $userid )) ->where('url_id', $id) ->where('user_id', 0) ->update('multipaste'); return $this->db->affected_rows(); } public function get_tarball_path($id) { return $this->config->item("upload_path")."/special/multipaste-tarballs/".substr(md5($id), 0, 3)."/$id.tar.gz"; } public function delete_by_user($userid) { $query = $this->db->select("url_id") ->where("user_id", $userid) ->get("multipaste")->result_array(); $ids = array_map(function ($a) {return $a['url_id'];}, $query); foreach ($ids as $id) { $this->delete_id($id); } } public function delete_id($id) { $this->db->where('url_id', $id) ->delete('multipaste'); $path = $this->get_tarball_path($id); $f = new \service\storage($this->get_tarball_path($id)); $f->unlink(); return $this->id_exists($id); } public function get_owner($id) { return $this->db->query(" SELECT user_id FROM ".$this->db->dbprefix."multipaste WHERE url_id = ? ", array($id))->row_array()["user_id"]; } public function get_multipaste($id) { return $this->db->query(" SELECT url_id, user_id, date FROM ".$this->db->dbprefix."multipaste WHERE url_id = ? ", array($id))->row_array(); } public function get_files($url_id) { $ret = array(); $query = $this->db->query(" SELECT mfm.file_url_id FROM ".$this->db->dbprefix."multipaste_file_map mfm JOIN ".$this->db->dbprefix."multipaste m ON m.multipaste_id = mfm.multipaste_id WHERE m.url_id = ? ORDER BY mfm.sort_order ", array($url_id))->result_array(); foreach ($query as $row) { $filedata = $this->mfile->get_filedata($row["file_url_id"]); $ret[] = $filedata; } return $ret; } public function get_multipaste_id($url_id) { $query = $this->db->query(" SELECT multipaste_id FROM ".$this->db->dbprefix."multipaste WHERE url_id = ? ", array($url_id)); if ($query->num_rows() > 0) { return $query->row_array()["multipaste_id"]; } return false; } }