diff --git a/.gitignore b/.gitignore index 0495d7d..b0b0131 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ pile.db vendor +files diff --git a/www/_templates/admin_doc_edit.php b/www/_templates/admin_doc_edit.php new file mode 100644 index 0000000..d084e79 --- /dev/null +++ b/www/_templates/admin_doc_edit.php @@ -0,0 +1,26 @@ +
+
" enctype="multipart/form-data"> + Title: ">
+ Author: ">
+ Date published: ">
+ Description:
+
+ File:
+ URL: ">
+ Tags: ">
+ " > + +
+
diff --git a/www/_templates/admin_doc_listing.php b/www/_templates/admin_doc_listing.php new file mode 100644 index 0000000..a3c4102 --- /dev/null +++ b/www/_templates/admin_doc_listing.php @@ -0,0 +1,30 @@ + +
+

+

+ ">[edit tag] +
+ + + +
+ "> +
+

Upload a new document

+
+
+
+ + + +
+ ">[X] + "> +
+

+

+
+
+
+ diff --git a/www/_templates/admin_doc_remove.php b/www/_templates/admin_doc_remove.php new file mode 100644 index 0000000..4f3da75 --- /dev/null +++ b/www/_templates/admin_doc_remove.php @@ -0,0 +1,4 @@ +
+

Confirm deletion of "":

+ &ret=" class="button">Remove from database (and drive) +
diff --git a/www/_templates/admin_intro.php b/www/_templates/admin_intro.php new file mode 100644 index 0000000..c180cc9 --- /dev/null +++ b/www/_templates/admin_intro.php @@ -0,0 +1,3 @@ +
+

Handle with care.

+
\ No newline at end of file diff --git a/www/_templates/admin_wrap.php b/www/_templates/admin_wrap.php new file mode 100644 index 0000000..c949513 --- /dev/null +++ b/www/_templates/admin_wrap.php @@ -0,0 +1,44 @@ + + + + + + + + pile ADMIN INTERFACE + + + + + + + +
+ +
+ +
+
+ + +
+
+ + diff --git a/www/_templates/front_doc_listing.php b/www/_templates/front_doc_listing.php index dbdefc4..b3351ef 100644 --- a/www/_templates/front_doc_listing.php +++ b/www/_templates/front_doc_listing.php @@ -1,7 +1,9 @@ +

+
diff --git a/www/_templates/front_doc_overview.php b/www/_templates/front_doc_overview.php index aa2001e..90eeba7 100644 --- a/www/_templates/front_doc_overview.php +++ b/www/_templates/front_doc_overview.php @@ -1,14 +1,16 @@

+

Published:

+

Tags: " . $tag["Name"] . ""; + foreach($doc["tags"] as $tag){ + echo '
  • " . $tag["Name"] . "
  • "; } ?>

    Description:

    -
    \ No newline at end of file +
    diff --git a/www/_templates/front_wrap.php b/www/_templates/front_wrap.php index b28cbfe..49086a4 100644 --- a/www/_templates/front_wrap.php +++ b/www/_templates/front_wrap.php @@ -33,10 +33,10 @@
    -
    + + + +
    + +
    - - -
    -
    + + + + + - \ No newline at end of file + diff --git a/www/_templates/full_text.php b/www/_templates/full_text.php new file mode 100644 index 0000000..eb257ba --- /dev/null +++ b/www/_templates/full_text.php @@ -0,0 +1,40 @@ + + + + + + + + + The /-\ pile + + + + + +
    +

    + +

    +
    + + \ No newline at end of file diff --git a/www/_templates/intro.php b/www/_templates/intro.php new file mode 100644 index 0000000..74853a5 --- /dev/null +++ b/www/_templates/intro.php @@ -0,0 +1,5 @@ +
    +

    This site is the sdbs pile, where we upload the stuff we consider important to the larger conceptual and thematic landscape of what we do: "confronting apathy", inter-subjectivity, the human right to self-determination, counter-culture and such...

    +

    Tohle je hromádka zajímavýho materiálu co něco znamená v kontextu sdbs - budeme sem postupně dávat ty nejdůležitější nebo nejzajímavější věci, zatim se o tom ale nikde moc nešiřte.

    +

    /-\

    +
    \ No newline at end of file diff --git a/www/_util/.htaccess b/www/_util/.htaccess new file mode 100644 index 0000000..14249c5 --- /dev/null +++ b/www/_util/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/www/_util/PileDB.php b/www/_util/PileDB.php new file mode 100644 index 0000000..661180a --- /dev/null +++ b/www/_util/PileDB.php @@ -0,0 +1,199 @@ +db = new SQLite3("pile.db"); + } + + function prepare($statement){ + return $this->db->prepare($statement); + } + + function query($statement){ + return $this->db->query($statement); + } + + public function getDocCount(){ + $ret_count = $this->db->query("SELECT count(ID) FROM Documents")->fetchArray(SQLITE3_NUM); + return $ret_count[0]; + } + + public function getTags(){ + $tag_query = "SELECT + ID, Name, count(Document) + FROM + Tags t + LEFT OUTER JOIN + DocumentstoTags d ON t.ID = d.Tag + GROUP BY Name + ORDER BY count(Document) DESC, Name"; + $tags_ret = $this->db->query($tag_query); + $tags = []; + while ($row = $tags_ret->fetchArray(SQLITE3_NUM)) { + array_push($tags, array( + 'href' => $row[0], + 'name' => $row[1], + 'count' => $row[2] + )); + } + return $tags; + } + + public function fetchDoc($id){ + $stmt_doc = $this->db->prepare("SELECT * FROM Documents WHERE ID = :id"); + $stmt_doc->bindValue(":id", $id, SQLITE3_INTEGER); + $doc = $stmt_doc->execute()->fetchArray(SQLITE3_ASSOC); + + $stmt_tags = $this->db->prepare("SELECT t.ID, t.Name FROM Tags t + JOIN DocumentsToTags dt ON t.ID = dt.Tag + JOIN Documents d on d.ID = dt.Document + WHERE d.ID = :id"); + $stmt_tags->bindValue(":id", $id, SQLITE3_INTEGER); + $ret = $stmt_tags->execute(); + $doc["tags"] = []; + while ($tag = $ret->fetchArray(SQLITE3_ASSOC)) { + array_push($doc["tags"], $tag); + } + return $doc; + } + + public function listDocs(){ + if (func_num_args() > 0){ + $tag = func_get_arg(0); + if ($tag > 0 ) { + $stmt = $this->db->prepare("SELECT + ID, Title, Author, Published, URL + FROM + Documents d + LEFT OUTER JOIN + DocumentsToTags dt ON d.ID = dt.Document + WHERE Tag == :tag"); + $stmt->bindValue(":tag", $tag, SQLITE3_INTEGER); + } else { + $stmt = $this->db->prepare("SELECT + ID, Title, Author, Published, URL + FROM + Documents d + LEFT OUTER JOIN + DocumentsToTags dt ON d.ID = dt.Document + WHERE dt.Document IS NULL"); + } + $doc_ret = $stmt->execute(); + } else { + $query = "SELECT ID, Title, Author, Published, URL FROM Documents"; + $doc_ret = $this->db->query($query); + } + $docs = []; + while ($doc = $doc_ret->fetchArray(SQLITE3_ASSOC)) { + $doc['date'] = empty($doc["Published"]) ? "" : "(" . $doc["Published"] . ")"; + array_push($docs, $doc); + } + return $docs; + } + + public function updateDoc($id, $title, $author, $description, $published, $url, $tag_ids){ + if ( empty($id) ){ + $stmt = $this->db->prepare("INSERT INTO Documents + (ID, Title, Author, Description, Published, URL) + VALUES + (NULL, :title, :author, :description, :published, :url)"); + } else { + $stmt = $this->db->prepare("UPDATE Documents SET + Title=:title, + Author=:author, + Description=:description, + Published=:published, + URL=:url + WHERE ID = :id"); + $stmt->bindValue(":id", $id, SQLITE3_INTEGER); + } + $stmt->bindValue(":title", $title, SQLITE3_TEXT); + $stmt->bindValue(":author", $author, SQLITE3_TEXT); + $stmt->bindValue(":description", $description, SQLITE3_TEXT); + $stmt->bindValue(":published", $published, SQLITE3_TEXT); + $stmt->bindValue(":url", $url, SQLITE3_TEXT); + $stmt->execute(); + if ( empty($id) ){ + $id = $this->db->lastInsertRowid(); + } + + if ( ! empty($id) ){ + $delete_stmt = $this->db->prepare("DELETE FROM DocumentsToTags + WHERE Document = :id"); + $delete_stmt->bindValue(":id", $id, SQLITE3_INTEGER); + $delete_stmt->execute(); + } + + foreach ($tag_ids as $tag){ + $tag_stmt = $this->db->prepare("INSERT INTO DocumentsToTags ('Document', 'Tag') + VALUES (:doc, :tag)"); + $tag_stmt->bindValue("doc", $id, SQLITE3_INTEGER); + $tag_stmt->bindValue("tag", $tag, SQLITE3_INTEGER); + $tag_stmt->execute(); + } + } + + public function removeDoc($id){ + $doc_stmt = $this->db->prepare("DELETE FROM Documents + WHERE ID = :id"); + $doc_stmt->bindValue("id", $id, SQLITE3_INTEGER); + $doc_stmt->execute(); + + $tag_stmt = $this->db->prepare("DELETE FROM DocumentsToTags + WHERE Document = :id"); + $tag_stmt->bindValue("id", $id, SQLITE3_INTEGER); + $tag_stmt->execute(); + } + + public function findTag($name){ + $stmt = $this->db->prepare("SELECT * FROM Tags WHERE Name == :name"); + $stmt->bindValue(":name", $name, SQLITE3_TEXT); + return $stmt->execute()->fetchArray(SQLITE3_ASSOC); + } + + public function fetchTag($tag){ + $stmt = $this->db->prepare("SELECT * FROM Tags WHERE ID == :tag"); + $stmt->bindValue(":tag", $tag, SQLITE3_INTEGER); + return $stmt->execute()->fetchArray(SQLITE3_ASSOC); + } + + public function updateTag($id, $name, $description, $parent){ + if (empty($id)){ + $stmt = $this->db->prepare("INSERT INTO Tags + (ID, Name, Description, Parent) + VALUES + (NULL, :name, :description, :parent"); + } else { + $stmt = $this->db->prepare("UPDATE Tags SET + Name=:name, + Description=:description, + Parent=:Parent + WHERE ID = :id"); + $stmt->bindValue(":id", $id, SQLITE3_INTEGER); + } + $stmt->bindValue(":name", $name, SQLITE3_TEXT); + $stmt->bindValue(":description", $description, SQLITE3_TEXT); + $stmt->bindValue(":parent", $parent, SQLITE3_INTEGER); + return $stmt->execute(); + } + + public function authenticate($username, $password){ + $stmt = $this->db->prepare("SELECT + * + FROM + Users + WHERE + Username = :username"); + $stmt->bindValue(":username", $username, SQLITE3_TEXT); + $auth_ret = $stmt->execute(); + $auth = $auth_ret->fetchArray(SQLITE3_ASSOC); + + if (password_verify($password, $auth["Password"])){ + return $auth["ID"]; + } else { + return -1; + } + } +} +?> diff --git a/www/_util/Uploader.php b/www/_util/Uploader.php new file mode 100644 index 0000000..5c9a874 --- /dev/null +++ b/www/_util/Uploader.php @@ -0,0 +1,49 @@ +file($files['upfile']['tmp_name']), + array( + 'pdf' => 'application/pdf', + 'zip' => 'application/zip', + 'rar' => 'application/rar' + ), + true + )) { + throw new RuntimeException('Invalid file format.'); + } + + $name = basename($files['upfile']['name']); + $name = preg_replace('/[^\x20-\x7E]/','', $name); + if ($name != ".htaccess"){ + if (!move_uploaded_file( + $files['upfile']['tmp_name'], + $dir . $name)) { + throw new RuntimeException('Failed to move uploaded file.'); + } + } else { + throw new RuntimeException('Invalid filename.'); + } + + return $name; + } +} +?> diff --git a/www/admin.php b/www/admin.php new file mode 100644 index 0000000..2ee93e5 --- /dev/null +++ b/www/admin.php @@ -0,0 +1,139 @@ +render("admin_doc_edit.php"); + break; + case "edit_tag": + $content = $page->render("admin_doc_edit.php"); + break; + case "new_item": + $content = $page->render("admin_doc_edit.php"); + break; + case "edit_item": + if (isset($_POST["Title"])){ + if ( !empty($_FILES['upfile']['name']) ){ + try { + $url = "http://pile.sdbs.cz/files/" . rawurlencode($uploader->handle($_FILES, "files/")); + } catch (RuntimeException $ex){ + $page->text = $ex->getMessage(); + echo $page->render('full_text.php'); + return; + } + } else { + $url = $_POST["URL"]; + } + + $doc_tags = []; + foreach (explode(",", $_POST["Tags"]) as $tagName){ + $tagName = trim($tagName); + $tag = $db->findTag($tagName); + if (!in_array($tag["ID"], $doc_tags)){ + array_push($doc_tags, $tag["ID"]); + } + } + + $db->updateDoc( + $_POST["ID"], + $_POST["Title"], + $_POST["Author"], + $_POST["Description"], + $_POST["Published"], + $url, + $doc_tags + ); + } + if ( !empty($_GET["item"]) ) { + $page->doc = $db->fetchDoc($_GET["item"]); + $content = $page->render("admin_doc_edit.php"); + } + break; + case "remove": + if ( ! empty($_GET["confirm"]) && $_GET["confirm"] == "yes"){ + $db->removeDoc($_GET["item"]); + $page->text = "Document deleted."; + $page->redirect = $_GET["ret"]; + echo $page->render("full_text.php"); + return; + } else { + $page->doc = $db->fetchDoc($_GET["item"]); + $content = $page->render("admin_doc_remove.php"); + } + break; + case "logout": + unset($_SESSION["ID"]); + $page->text = "See you."; + $page->redirect = "/"; + echo $page->render("full_text.php"); + return; + } + } elseif (isset($_GET["tag"])) { + $doc_list_template = new Template(); + if ($_GET["tag"] == "*"){ + $docs = $db->listDocs(); + } elseif ($_GET["tag"] == "_") { + $docs = $db->listDocs(-1); + } else { + $tag = $db->findTag($_GET["tag"]); + $docs = $db->listDocs($tag["ID"]); + $doc_list_template->tag = $db->fetchTag($tag["ID"]); + } + $doc_list_template->docs = $docs; + $content = $doc_list_template->render('admin_doc_listing.php'); + } else { + $intro_template = new Template(); + $content = $intro_template->render('admin_intro.php'); + } + + $all_count = $db->getDocCount(); + + $ret_count = $db->query("SELECT + count(ID) + FROM + Documents d + LEFT OUTER JOIN + DocumentstoTags dt ON dt.Document = d.ID + WHERE dt.Document IS NULL")->fetchArray(SQLITE3_NUM); + $none_count = $ret_count[0]; + + $tags = $db->getTags(); + + $page->all_count = $all_count; + $page->none_count = $none_count; + $page->tags = $tags; + $page->content = $content; + echo $page->render('admin_wrap.php'); +} else { + $page = new Template(); + + if (isset($_POST['username']) && isset($_POST['password'])){ + $ret_id = $db->authenticate($_POST["username"], $_POST["password"]); + if ($ret_id > 0){ + $_SESSION['ID'] = $ret_id; + $page->text = "You have logged in successfully."; + $page->redirect = "admin.php"; + } else { + $page->text = "Username and/or password incorrect."; + $page->redirect = "/"; + } + } else { + $page->text = "Please log in before accessing this page."; + $page->redirect = "/"; + } + + echo $page->render('full_text.php'); +} + +?> diff --git a/www/index.php b/www/index.php index eb353f1..4084924 100644 --- a/www/index.php +++ b/www/index.php @@ -1,76 +1,25 @@ query("SELECT count(ID) FROM Documents")->fetchArray(SQLITE3_NUM); -$count = $ret_count[0]; - -$tag_query = "SELECT - ID, Name, count(Document) - FROM - Tags t - LEFT OUTER JOIN - DocumentstoTags d ON t.ID = d.Tag - GROUP BY Name - ORDER BY count(Document) DESC, Name"; -$tags_ret = $db->query($tag_query); -$tags = []; -while ($row = $tags_ret->fetchArray(SQLITE3_NUM)) { - array_push($tags, array( - 'href' => $row[0], - 'name' => $row[1], - 'count' => $row[2] - )); -} +$db = new PileDB(); +session_start(); if (isset($_GET["item"])) { - $stmt_doc = $db->prepare("SELECT * FROM Documents WHERE ID = :id"); - $stmt_doc->bindValue(":id", $_GET["item"], SQLITE3_INTEGER); - $doc = $stmt_doc->execute()->fetchArray(SQLITE3_ASSOC); - - $stmt_tags = $db->prepare("SELECT t.ID, t.Name FROM Tags t - JOIN DocumentsToTags dt ON t.ID = dt.Tag - JOIN Documents d on t.ID = dt.Document - WHERE d.ID = :id"); - $stmt_tags->bindValue(":id", $_GET["item"], SQLITE3_INTEGER); - $ret = $stmt_tags->execute(); - $doc_tags = []; - while ($tag = $ret->fetchArray(SQLITE3_ASSOC)) { - array_push($doc_tags, $tag); - } + $doc = $db->fetchDoc($_GET["item"]); $doc_template = new Template(); $doc_template->doc = $doc; - $doc_template->tags = $doc_tags; $content = $doc_template->render('front_doc_overview.php'); } elseif (isset($_GET["tag"])) { - if ($_GET["tag"] == "*"){ - $query = "SELECT ID, Title, Author, Published, URL FROM Documents"; - $doc_ret = $db->query($query); - } else { - $stmt = $db->prepare("SELECT - ID, Title, Author, Published, URL - FROM - Documents d - LEFT OUTER JOIN - DocumentsToTags t ON d.ID = t.Document - WHERE Tag == :tag"); - $stmt->bindValue(":tag", $_GET["tag"], SQLITE3_INTEGER); - $doc_ret = $stmt->execute(); - } - $docs = []; - while ($doc = $doc_ret->fetchArray(SQLITE3_ASSOC)) { - $doc['date'] = empty($doc["Published"]) ? "" : "(" . $doc["Published"] . ")"; - array_push($docs, $doc); - } - - $stmt = $db->prepare("SELECT Name, Description FROM Tags WHERE ID == :tag"); - $stmt->bindValue(":tag", $_GET["tag"], SQLITE3_INTEGER); - $doc_list_template = new Template(); - $doc_list_template->tag = $stmt->execute()->fetchArray(SQLITE3_ASSOC); + if ($_GET["tag"] == "*"){ + $docs = $db->listDocs(); + } else { + $tag = $db->findTag($_GET["tag"]); + $docs = $db->listDocs($tag["ID"]); + $doc_list_template->tag = $db->fetchTag($tag["ID"]); + } $doc_list_template->docs = $docs; $content = $doc_list_template->render('front_doc_listing.php'); } else { @@ -79,8 +28,9 @@ if (isset($_GET["item"])) { } $page = new Template(); -$page->tag_count = $count; -$page->tags = $tags; +$page->doc_count = $db->getDocCount(); +$page->tags = $db->getTags(); $page->content = $content; +$page->logged = isset($_SESSION["ID"]); echo $page->render('front_wrap.php'); -?> \ No newline at end of file +?>