From d59962443687127ea1defc2f8ac41af1c2c02fe4 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sat, 25 Oct 2014 13:55:08 +0200 Subject: first go at reworking; needs to be redesigned Signed-off-by: Florian Pritz --- application/service/files.php | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 application/service/files.php (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php new file mode 100644 index 000000000..68072e95a --- /dev/null +++ b/application/service/files.php @@ -0,0 +1,116 @@ + + * + * Licensed under AGPLv3 + * (see COPYING for full license text) + * + */ + +namespace service; + +class files { + + static public function history($user) + { + $CI =& get_instance(); + $query = array(); + + $fields = array("id", "filename", "mimetype", "date", "hash", "filesize"); + + $items = $CI->db->select(implode(',', $fields)) + ->from('files') + ->where('user', $user) + ->get()->result_array(); + + // TODO: split this and provide an array of pastes for a multipaste? + $query = $CI->db->query(" + SELECT m.url_id id, sum(f.filesize) filesize, m.date, '' hash, '' mimetype, concat(count(*), ' file(s)') filename + FROM multipaste m + JOIN multipaste_file_map mfm ON m.multipaste_id = mfm.multipaste_id + JOIN files f ON f.id = mfm.file_url_id + WHERE m.user_id = ? + GROUP BY m.url_id + ", array($user))->result_array(); + + $items = array_merge($items, $query); + + $total_size = $CI->db->query(" + SELECT sum(filesize) sum + FROM ( + SELECT DISTINCT hash, filesize + FROM files + WHERE user = ? + ) sub + ", array($user))->row_array(); + + $ret["items"] = $items; + $ret["total_size"] = $total_size["sum"]; + + return $ret; + } + + static public function add_file($id, $file, $filename) + { + $CI =& get_instance(); + $hash = md5_file($file); + + $dir = $CI->mfile->folder($hash); + file_exists($dir) || mkdir ($dir); + $new_path = $CI->mfile->file($hash); + + // TODO: make this operation atomic (move to temp name, then to final) + // the source can be a different file system so this might do a copy + move_uploaded_file($file, $new_path); + $CI->mfile->add_file($hash, $id, $filename); + } + + static public function verify_uploaded_files($files) + { + $CI =& get_instance(); + $errors = array(); + + foreach ($files as $key => $file) { + $error_message = ""; + + // getNormalizedFILES() removes any file with error == 4 + if ($file['error'] !== UPLOAD_ERR_OK) { + // ERR_OK only for completeness, condition above ignores it + $error_msgs = array( + UPLOAD_ERR_OK => "There is no error, the file uploaded with success", + UPLOAD_ERR_INI_SIZE => "The uploaded file exceeds the upload_max_filesize directive in php.ini", + UPLOAD_ERR_FORM_SIZE => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form", + UPLOAD_ERR_PARTIAL => "The uploaded file was only partially uploaded", + UPLOAD_ERR_NO_FILE => "No file was uploaded", + UPLOAD_ERR_NO_TMP_DIR => "Missing a temporary folder", + UPLOAD_ERR_CANT_WRITE => "Failed to write file to disk", + UPLOAD_ERR_EXTENSION => "A PHP extension stopped the file upload", + ); + + $error_message = "Unknown error."; + + if (isset($error_msgs[$file['error']])) { + $error_message = $error_msgs[$file['error']]; + } else { + $error_message = "Unknown error code: ".$file['error'].". Please report a bug."; + } + + } + + $filesize = filesize($file['tmp_name']); + if ($filesize > $CI->config->item('upload_max_size')) { + $error_message = "File too big"; + } + + if ($error_message != "") { + $errors[] = array( + "filename" => $file["name"], + "formfield" => $file["formfield"], + "message" => $error_message, + ); + } + } + + return $errors; + } +} -- cgit v1.2.3-24-g4f1b From 7f74792c2f82aee3cd98bd6304ced55894b43683 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sun, 4 Jan 2015 17:08:51 +0100 Subject: Improve history api for multipastes Signed-off-by: Florian Pritz --- application/service/files.php | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 68072e95a..7b320078e 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -14,7 +14,8 @@ class files { static public function history($user) { $CI =& get_instance(); - $query = array(); + $multipaste_items_grouped = array(); + $multipaste_items = array(); $fields = array("id", "filename", "mimetype", "date", "hash", "filesize"); @@ -23,17 +24,25 @@ class files { ->where('user', $user) ->get()->result_array(); - // TODO: split this and provide an array of pastes for a multipaste? - $query = $CI->db->query(" - SELECT m.url_id id, sum(f.filesize) filesize, m.date, '' hash, '' mimetype, concat(count(*), ' file(s)') filename - FROM multipaste m - JOIN multipaste_file_map mfm ON m.multipaste_id = mfm.multipaste_id - JOIN files f ON f.id = mfm.file_url_id - WHERE m.user_id = ? - GROUP BY m.url_id - ", array($user))->result_array(); + $multipaste_items_query = $CI->db + ->select("m.url_id, f.filename, f.id, f.filesize, f.date, f.hash, f.mimetype") + ->from("multipaste m") + ->join("multipaste_file_map mfm", "m.multipaste_id = mfm.multipaste_id") + ->join("files f", "f.id = mfm.file_url_id") + ->where("m.user_id", $user) + ->get()->result_array(); + + foreach ($multipaste_items_query as $item) { + $key = $item["url_id"]; + unset($item["url_id"]); + $multipaste_items_grouped[$key][] = $item; + } - $items = array_merge($items, $query); + foreach ($multipaste_items_grouped as $key => $items) { + $multipaste_info = $CI->db->get_where("multipaste", array("url_id" => $key))->row_array(); + $multipaste_info["items"] = $items; + $multipaste_items[] = $multipaste_info; + } $total_size = $CI->db->query(" SELECT sum(filesize) sum @@ -45,6 +54,7 @@ class files { ", array($user))->row_array(); $ret["items"] = $items; + $ret["multipaste_items"] = $multipaste_items; $ret["total_size"] = $total_size["sum"]; return $ret; -- cgit v1.2.3-24-g4f1b From c8e5f5a20c9e558efbd5e9c152f086ab72015ba3 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sun, 11 Jan 2015 12:21:27 +0100 Subject: refactor service/file/history Signed-off-by: Florian Pritz --- application/service/files.php | 52 +++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 24 deletions(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 7b320078e..b4bf7b9ee 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -14,36 +14,13 @@ class files { static public function history($user) { $CI =& get_instance(); - $multipaste_items_grouped = array(); - $multipaste_items = array(); $fields = array("id", "filename", "mimetype", "date", "hash", "filesize"); - $items = $CI->db->select(implode(',', $fields)) ->from('files') ->where('user', $user) ->get()->result_array(); - $multipaste_items_query = $CI->db - ->select("m.url_id, f.filename, f.id, f.filesize, f.date, f.hash, f.mimetype") - ->from("multipaste m") - ->join("multipaste_file_map mfm", "m.multipaste_id = mfm.multipaste_id") - ->join("files f", "f.id = mfm.file_url_id") - ->where("m.user_id", $user) - ->get()->result_array(); - - foreach ($multipaste_items_query as $item) { - $key = $item["url_id"]; - unset($item["url_id"]); - $multipaste_items_grouped[$key][] = $item; - } - - foreach ($multipaste_items_grouped as $key => $items) { - $multipaste_info = $CI->db->get_where("multipaste", array("url_id" => $key))->row_array(); - $multipaste_info["items"] = $items; - $multipaste_items[] = $multipaste_info; - } - $total_size = $CI->db->query(" SELECT sum(filesize) sum FROM ( @@ -54,12 +31,39 @@ class files { ", array($user))->row_array(); $ret["items"] = $items; - $ret["multipaste_items"] = $multipaste_items; + $ret["multipaste_items"] = self::get_multipaste_history($user); $ret["total_size"] = $total_size["sum"]; return $ret; } + static private function get_multipaste_history($user) + { + $CI =& get_instance(); + $multipaste_items_grouped = array(); + $multipaste_items = array(); + + $query = $CI->db->get_where("multipaste", array("user_id" => $user))->result_array(); + $multipaste_info = array(); + foreach ($query as $item) { + $multipaste_info[$item["url_id"]] = $item; + } + + $multipaste_items_query = $CI->db + ->select("m.url_id, f.id") + ->from("multipaste m") + ->join("multipaste_file_map mfm", "m.multipaste_id = mfm.multipaste_id") + ->join("files f", "f.id = mfm.file_url_id") + ->where("m.user_id", $user) + ->get()->result_array(); + + foreach ($multipaste_items_query as $item) { + $multipaste_info[$item["url_id"]]["items"][$item["id"]] = array("id" => $item["id"]); + } + + return $multipaste_info; + } + static public function add_file($id, $file, $filename) { $CI =& get_instance(); -- cgit v1.2.3-24-g4f1b From 01c881fd2c0f0c701a83e135f2142c9db3052422 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sun, 11 Jan 2015 23:35:38 +0100 Subject: fix multipaste in service/history Signed-off-by: Florian Pritz --- application/service/files.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index b4bf7b9ee..8d0760b87 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -14,12 +14,16 @@ class files { static public function history($user) { $CI =& get_instance(); + $items = array(); $fields = array("id", "filename", "mimetype", "date", "hash", "filesize"); - $items = $CI->db->select(implode(',', $fields)) + $query = $CI->db->select(implode(',', $fields)) ->from('files') ->where('user', $user) ->get()->result_array(); + foreach ($query as $key => $item) { + $items[$item["id"]] = $item; + } $total_size = $CI->db->query(" SELECT sum(filesize) sum -- cgit v1.2.3-24-g4f1b From 0bed4fd5c9f67b60173df6638dc524d7b833c4e1 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sun, 11 Jan 2015 23:35:46 +0100 Subject: add some TODOs Signed-off-by: Florian Pritz --- application/service/files.php | 1 + 1 file changed, 1 insertion(+) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 8d0760b87..8d8b1d01a 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -16,6 +16,7 @@ class files { $CI =& get_instance(); $items = array(); + // TODO: thumbnail urls where available $fields = array("id", "filename", "mimetype", "date", "hash", "filesize"); $query = $CI->db->select(implode(',', $fields)) ->from('files') -- cgit v1.2.3-24-g4f1b From cb52a4cdc2daa45a61c728f5ec83603e6c6a71fa Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Tue, 3 Feb 2015 00:23:12 +0100 Subject: Rework error handling in upload validator Signed-off-by: Florian Pritz --- application/service/files.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 8d8b1d01a..c270500ef 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -89,6 +89,10 @@ class files { $CI =& get_instance(); $errors = array(); + if (empty($files)) { + throw new \exceptions\UserInputException("file/no-file", "No file was uploaded or unknown error occured."); + } + foreach ($files as $key => $file) { $error_message = ""; @@ -113,7 +117,6 @@ class files { } else { $error_message = "Unknown error code: ".$file['error'].". Please report a bug."; } - } $filesize = filesize($file['tmp_name']); @@ -127,9 +130,8 @@ class files { "formfield" => $file["formfield"], "message" => $error_message, ); + throw new \exceptions\FileUploadVerifyException("file/upload-verify", "Failed to verify uploaded file(s)", $errors); } } - - return $errors; } } -- cgit v1.2.3-24-g4f1b From a788fe55713e7c44068ee2dd8377b98037d9375f Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Tue, 3 Feb 2015 11:38:03 +0100 Subject: api: implement file/delete Signed-off-by: Florian Pritz --- application/service/files.php | 62 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index c270500ef..3fa73c5ca 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -134,4 +134,66 @@ class files { } } } + + // TODO: streamline this interface to be somewhat atomic in regards to + // wrong owner/unknown ids (verify first and throw exception) + static public function delete($ids) + { + $CI =& get_instance(); + + $userid = $CI->muser->get_userid(); + $errors = array(); + $deleted = array(); + $deleted_count = 0; + $total_count = 0; + + if (!$ids || !is_array($ids)) { + throw new \exceptions\UserInputException("file/delete/no-ids", "No IDs specified"); + } + + foreach ($ids as $id) { + $total_count++; + $next = false; + + foreach (array($CI->mfile, $CI->mmultipaste) as $model) { + if ($model->id_exists($id)) { + if ($model->get_owner($id) !== $userid) { + $errors[$id] = array( + "id" => $id, + "reason" => "wrong owner", + ); + continue; + } + if ($model->delete_id($id)) { + $deleted[$id] = array( + "id" => $id, + ); + $deleted_count++; + $next = true; + } else { + $errors[$id] = array( + "id" => $id, + "reason" => "unknown error", + ); + } + } + } + + if ($next) { + continue; + } + + $errors[$id] = array( + "id" => $id, + "reason" => "doesn't exist", + ); + } + + return array( + "errors" => $errors, + "deleted" => $deleted, + "total_count" => $total_count, + "deleted_count" => $deleted_count, + ); + } } -- cgit v1.2.3-24-g4f1b From 5816cbcad0e9c4cda4dc10b730a5a1ea2c4e419a Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Tue, 3 Feb 2015 12:11:28 +0100 Subject: api: implement file/create_multipaste Signed-off-by: Florian Pritz --- application/service/files.php | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 3fa73c5ca..b4b7759e0 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -196,4 +196,57 @@ class files { "deleted_count" => $deleted_count, ); } + + static public function create_multipaste($ids, $userid, $limits) + { + $CI =& get_instance(); + + if (!$ids || !is_array($ids)) { + throw new \exceptions\UserInputException("file/create_multipaste/no-ids", "No IDs specified"); + } + + if (count(array_unique($ids)) != count($ids)) { + throw new \exceptions\UserInputException("file/create_multipaste/duplicate_id", "Duplicate IDs are not supported"); + } + + $errors = array(); + + foreach ($ids as $id) { + if (!$CI->mfile->id_exists($id)) { + $errors[$id] = array( + "id" => $id, + "reason" => "doesn't exist", + ); + continue; + } + + $filedata = $CI->mfile->get_filedata($id); + if ($filedata["user"] != $userid) { + $errors[$id] = array( + "id" => $id, + "reason" => "not owned by you", + ); + } + } + + if (!empty($errors)) { + throw new \exceptions\VerifyException("file/create_multipaste/verify-failed", "Failed to verify ID(s)", $errors); + } + + $url_id = $CI->mmultipaste->new_id($limits[0], $limits[1]); + + $multipaste_id = $CI->mmultipaste->get_multipaste_id($url_id); + assert($multipaste_id !== false); + + foreach ($ids as $id) { + $CI->db->insert("multipaste_file_map", array( + "file_url_id" => $id, + "multipaste_id" => $multipaste_id, + )); + } + + return array( + "url_id" => $url_id, + ); + } } -- cgit v1.2.3-24-g4f1b From db8a70bbcb941fde96a0ac98919702c49814d0c5 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Thu, 5 Feb 2015 21:48:16 +0100 Subject: fixup! Support database table prefixes Signed-off-by: Florian Pritz --- application/service/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index b4b7759e0..962939c87 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -30,7 +30,7 @@ class files { SELECT sum(filesize) sum FROM ( SELECT DISTINCT hash, filesize - FROM files + FROM `".$CI->db->dbprefix."files` WHERE user = ? ) sub ", array($user))->row_array(); -- cgit v1.2.3-24-g4f1b From 03e9a7abbf2851f3f8ac4c9a1d0bc072f4a9e103 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Thu, 5 Feb 2015 21:52:43 +0100 Subject: service/files::history: Fix total_size if no results Signed-off-by: Florian Pritz --- application/service/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 962939c87..59a096d1b 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -27,7 +27,7 @@ class files { } $total_size = $CI->db->query(" - SELECT sum(filesize) sum + SELECT coalesce(sum(filesize), 0) sum FROM ( SELECT DISTINCT hash, filesize FROM `".$CI->db->dbprefix."files` -- cgit v1.2.3-24-g4f1b From f5cab9d96aec1464978b556f2ca02e79b2c4d8d8 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Fri, 6 Feb 2015 12:40:58 +0100 Subject: service/files::delete: Fix incorrect error when wrong owner Also improve the variable name for easier understanding. Signed-off-by: Florian Pritz --- application/service/files.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 59a096d1b..802ba70af 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -153,7 +153,7 @@ class files { foreach ($ids as $id) { $total_count++; - $next = false; + $nextID = false; foreach (array($CI->mfile, $CI->mmultipaste) as $model) { if ($model->id_exists($id)) { @@ -162,6 +162,7 @@ class files { "id" => $id, "reason" => "wrong owner", ); + $nextID = true; continue; } if ($model->delete_id($id)) { @@ -169,7 +170,7 @@ class files { "id" => $id, ); $deleted_count++; - $next = true; + $nextID = true; } else { $errors[$id] = array( "id" => $id, @@ -179,7 +180,7 @@ class files { } } - if ($next) { + if ($nextID) { continue; } -- cgit v1.2.3-24-g4f1b From 4f5f2f496bdc182ac9edeb2f416d12fa5e56a9ca Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sat, 14 Feb 2015 19:13:59 +0100 Subject: Use assoc array for service/files/verify_uploaded_files Signed-off-by: Florian Pritz --- application/service/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 802ba70af..922320e11 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -125,7 +125,7 @@ class files { } if ($error_message != "") { - $errors[] = array( + $errors[$file["formfield"]] = array( "filename" => $file["name"], "formfield" => $file["formfield"], "message" => $error_message, -- cgit v1.2.3-24-g4f1b From 01226a9afd760a920e9cb3377913ee296f0ab2ca Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sat, 14 Feb 2015 19:23:49 +0100 Subject: Fix consistency of error_ids Signed-off-by: Florian Pritz --- application/service/files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'application/service/files.php') diff --git a/application/service/files.php b/application/service/files.php index 922320e11..e31efacc1 100644 --- a/application/service/files.php +++ b/application/service/files.php @@ -207,7 +207,7 @@ class files { } if (count(array_unique($ids)) != count($ids)) { - throw new \exceptions\UserInputException("file/create_multipaste/duplicate_id", "Duplicate IDs are not supported"); + throw new \exceptions\UserInputException("file/create_multipaste/duplicate-id", "Duplicate IDs are not supported"); } $errors = array(); -- cgit v1.2.3-24-g4f1b