Archived
1
0

Automatically crop uploaded profile pictures (fix #10) and migrate profile editing page to Bootstrap 4 (fix #8). General improvements to the process of profile editing

This commit is contained in:
KingOfDog 2018-10-23 22:22:22 +02:00
parent 2b5632fe95
commit 0ea56d1292
5 changed files with 1805 additions and 1757 deletions

View File

@ -14,7 +14,7 @@ class File extends MY_Controller
if ($title == null) { if ($title == null) {
redirect(base_url()); redirect(base_url());
} else { } else {
$file = $this->db->query('SELECT name, type, path FROM files WHERE name = ?', [urldecode($title)])->result_array(); $file = $this->db->query('SELECT name, type, path, isUserData FROM files WHERE name = ?', [urldecode($title)])->result_array();
if (!empty($file)) { if (!empty($file)) {
$file = $file[0]; $file = $file[0];
@ -25,7 +25,7 @@ class File extends MY_Controller
header("Content-Disposition: attachment; filename=" . $file['name'] . '.' . explode('/', $file['type'])[1]); header("Content-Disposition: attachment; filename=" . $file['name'] . '.' . explode('/', $file['type'])[1]);
} }
$imagePath = 'files/' . (isset($_GET['w']) || isset($_GET['h']) ? 'thumbs/' : '') . $file['name'] . (isset($_GET['w']) ? '_w' . $_GET['w'] : '') . (isset($_GET['h']) ? '_h' . $_GET['h'] : '') . '.' . explode('.', $file['path'])[1]; $imagePath = 'files/' . ($file['isUserData'] ? 'userContent/' : '') . (isset($_GET['w']) || isset($_GET['h']) ? 'thumbs/' : '') . $file['name'] . (isset($_GET['w']) ? '_w' . $_GET['w'] : '') . (isset($_GET['h']) ? '_h' . $_GET['h'] : '') . '.' . explode('.', $file['path'])[1];
if (!file_exists($imagePath)) { if (!file_exists($imagePath)) {
$config['image_library'] = 'gd2'; $config['image_library'] = 'gd2';

View File

@ -221,7 +221,8 @@
if (strlen($content) >= 10000) { if (strlen($content) >= 10000) {
?> ?>
<div class="alert alert-warning" role="alert"> <div class="alert alert-warning" role="alert">
<b>Veröffentlichung des Posts fehlgeschlagen!</b> Dein Post ist leider zu lang. Er darf maximal 10.000 Zeichen umfassen. <b>Veröffentlichung des Posts fehlgeschlagen!</b> Dein Post ist leider zu lang. Er darf maximal 10.000
Zeichen umfassen.
</div> </div>
<?php <?php
exit; exit;
@ -231,7 +232,8 @@
if ($replyTo !== "-1" && !$this->PostsModel->isUUIDValid($replyTo)) { if ($replyTo !== "-1" && !$this->PostsModel->isUUIDValid($replyTo)) {
?> ?>
<div class="alert alert-warning" role="alert"> <div class="alert alert-warning" role="alert">
<b>Veröffentlichung des Posts fehlgeschlagen!</b> Der Post, an den du deine Antwort richten willst, existiert nicht (mehr).<br> <b>Veröffentlichung des Posts fehlgeschlagen!</b> Der Post, an den du deine Antwort richten willst,
existiert nicht (mehr).<br>
Solltest du dies für einen Fehler halten, versuche es später erneut oder kontaktiere uns. Solltest du dies für einen Fehler halten, versuche es später erneut oder kontaktiere uns.
</div> </div>
<?php <?php
@ -261,7 +263,8 @@
<div class="alert alert-success" role="alert"> <div class="alert alert-success" role="alert">
<b>Dein Post wurde erfolgreich veröffentlicht!</b> Möchtest du nun deine Posts ansehen? <br> <b>Dein Post wurde erfolgreich veröffentlicht!</b> Möchtest du nun deine Posts ansehen? <br>
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal">Nein</button> <button type="button" class="btn btn-sm btn-default" data-dismiss="modal">Nein</button>
<a href='<?= base_url('user/' . $_SESSION['user']['username'] . '/posts') ?>' class='btn btn-sm btn-primary'>Ja</a> <a href='<?= base_url('user/' . $_SESSION['user']['username'] . '/posts') ?>'
class='btn btn-sm btn-primary'>Ja</a>
</div> </div>
<?php <?php
} }
@ -446,16 +449,14 @@
} }
// Avatar // Avatar
if (isset($_FILES['avatar'])) { if (isset($_FILES['avatar'])) {
$image = $this->FileModel->uploadImage('avatar', 4096, $_FILES['avatar']['name'], 200); $image = $this->FileModel->uploadCroppedImage('avatar', 4096, $_FILES['avatar']['name'], 500, 500);
if ($image != null) if ($image != null)
$newData['profile_picture'] = $image; $newData['profile_picture'] = $image;
unset($_FILES['avatar']); unset($_FILES['avatar']);
} }
// Header // Header
if (isset($_FILES['header'])) { if (isset($_FILES['header'])) {
// var_dump($_FILES['header']);
$image = $this->FileModel->uploadImage('header', 4096, $_FILES['header']['name'], 1920); $image = $this->FileModel->uploadImage('header', 4096, $_FILES['header']['name'], 1920);
// var_dump($image);
if ($image != null) if ($image != null)
$newData['header_image'] = $image; $newData['header_image'] = $image;
unset($_FILES['header']); unset($_FILES['header']);
@ -543,10 +544,16 @@
} }
if (!empty($newData)) { if (!empty($newData)) {
// Add entry to history // Add entry to history
unset($user_data['rankName']);
unset($_SESSION['user']);
$this->UserModel->insertIntoHistory($user_data); $this->UserModel->insertIntoHistory($user_data);
// Update profile // Update profile
$this->UserModel->updateProfile($newData, $user_data['ID']); $this->UserModel->updateProfile($newData, $user_data['ID']);
// redirect(base_url(uri_string())); $this->db->cache_delete('user', $user_data['username']);
$this->LoginModel->reloadLoginSession($user_data);
redirect(base_url(uri_string()));
} }
$user_stats = $this->UserModel->getUserStats($user_data['ID']); $user_stats = $this->UserModel->getUserStats($user_data['ID']);

View File

@ -11,9 +11,13 @@ class FileModel extends CI_Model
parent::__construct(); parent::__construct();
} }
public function uploadFile($original_name, $tmpname, $size, $type) private function getPath($fileName, $userContent) {
return 'files/' . ($userContent ? 'userContent/' : '') . $fileName;
}
public function uploadFile($original_name, $tmpname, $size, $type, $userContent = true)
{ {
$target_dir = "files" . DIRECTORY_SEPARATOR; $target_dir = "files" . DIRECTORY_SEPARATOR . ($userContent ? 'userContent' . DIRECTORY_SEPARATOR : '');
$filetype = pathinfo(basename($original_name), PATHINFO_EXTENSION); $filetype = pathinfo(basename($original_name), PATHINFO_EXTENSION);
$target_file = $target_dir . $this->generateName() . '.' . $filetype; $target_file = $target_dir . $this->generateName() . '.' . $filetype;
$name = explode('.' . $filetype, explode(DIRECTORY_SEPARATOR, $target_file)[1])[0]; $name = explode('.' . $filetype, explode(DIRECTORY_SEPARATOR, $target_file)[1])[0];
@ -22,13 +26,13 @@ class FileModel extends CI_Model
die('File couldn\'t be uploaded!'); die('File couldn\'t be uploaded!');
} }
$this->db->query('INSERT INTO files (name, original_name, type, size, path) VALUES (?, ?, ?, ?, ?)', [$name, $original_name, $type, $size, $target_file]); $this->db->query('INSERT INTO files (name, original_name, type, size, path, isUserData) VALUES (?, ?, ?, ?, ?, ?)', [$name, $original_name, $type, $size, $target_file, $userContent]);
return "/file/open/" . $name; return "/f/" . $name;
} }
public function uploadImage($name, $max_size, $originalname, $max_width) { public function uploadImage($name, $max_size, $originalname, $max_width, $userContent = true) {
$config['upload_path'] = './files/'; $config['upload_path'] = '.' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . ($userContent ? 'userContent' . DIRECTORY_SEPARATOR : '');
$config['allowed_types'] = 'gif|jpg|png'; $config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = $max_size; $config['max_size'] = $max_size;
$config['file_name'] = $this->generateName() . "." . pathinfo(basename($originalname), PATHINFO_EXTENSION); $config['file_name'] = $this->generateName() . "." . pathinfo(basename($originalname), PATHINFO_EXTENSION);
@ -50,13 +54,65 @@ class FileModel extends CI_Model
$this->image_lib->resize(); $this->image_lib->resize();
$this->db->query('INSERT INTO files (name, original_name, type, size, path) VALUES (?, ?, ?, ?, ?)', [$data['raw_name'], $originalname, $data['file_type'], $data['file_size'] * 1024, 'files/' . $data['file_name']]); $this->db->query('INSERT INTO files (name, original_name, type, size, path, isUserData) VALUES (?, ?, ?, ?, ?, ?)', [$data['raw_name'], $originalname, $data['file_type'], $data['file_size'] * 1024, $this->getPath($data['file_name'], $userContent), $userContent]);
return '/f/' . $data['raw_name']; return '/f/' . $data['raw_name'];
} }
} }
public function uploadFileByContent($content, $original_name, $fullType, $fileSize) { public function uploadCroppedImage($name, $max_size, $originalname, $width, $height, $userContent = true) {
$target_dir = "files" . DIRECTORY_SEPARATOR; $config['upload_path'] = '.' . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . ($userContent ? 'userContent' . DIRECTORY_SEPARATOR : '');
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = $max_size;
$config['file_name'] = $this->generateName() . "." . pathinfo(basename($originalname), PATHINFO_EXTENSION);
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload($name)) {
return null;
} else {
$data = $this->upload->data();
// Resize
$config['image_library'] = 'gd2';
$config['source_image'] = $data['full_path'];
$config['maintain_ratio'] = TRUE;
$size = getimagesize($data['full_path']);
if($size[0] > $size[1]) {
$config['height'] = $height;
} else {
$config['width'] = $width;
}
$this->load->library('image_lib');
$this->image_lib->initialize($config);
$this->image_lib->resize();
$config['source_image'] = $config['upload_path'] . $config['file_name'];
$config['maintain_ratio'] = FALSE;
$config['height'] = $height;
$config['width'] = $width;
$size = getimagesize($config['source_image']);
if($size[0] > $size[1]) {
$config['x_axis'] = ($size[0] - $width) / 2;
} else {
$config['y_axis'] = ($size[1] - $height) / 2;
}
$this->image_lib->clear();
$this->image_lib->initialize($config);
$this->image_lib->crop();
$this->db->query('INSERT INTO files (name, original_name, type, size, path, isUserData) VALUES (?, ?, ?, ?, ?, ?)', [$data['raw_name'], $originalname, $data['file_type'], $data['file_size'] * 1024, $this->getPath($data['file_name'], $userContent), $userContent]);
return '/f/' . $data['raw_name'];
}
}
public function uploadFileByContent($content, $original_name, $fullType, $fileSize, $userContent = true) {
$target_dir = "files" . DIRECTORY_SEPARATOR . ($userContent ? 'userContent' . DIRECTORY_SEPARATOR : '');
$filetype = pathinfo(basename($original_name), PATHINFO_EXTENSION); $filetype = pathinfo(basename($original_name), PATHINFO_EXTENSION);
$target_file = $target_dir . $this->generateName() . '.' . $filetype; $target_file = $target_dir . $this->generateName() . '.' . $filetype;
$name = explode('.' . $filetype, explode(DIRECTORY_SEPARATOR, $target_file)[1])[0]; $name = explode('.' . $filetype, explode(DIRECTORY_SEPARATOR, $target_file)[1])[0];
@ -65,7 +121,7 @@ class FileModel extends CI_Model
fwrite($fp, $content); fwrite($fp, $content);
fclose($fp); fclose($fp);
$this->db->query('INSERT INTO files (name, original_name, type, size, path) VALUES (?, ?, ?, ?, ?)', [$name, $original_name, $fullType, $fileSize, $target_file]); $this->db->query('INSERT INTO files (name, original_name, type, size, path, isUserData) VALUES (?, ?, ?, ?, ?, ?)', [$name, $original_name, $fullType, $fileSize, $target_file, $userContent]);
return '/f/' . $name; return '/f/' . $name;
} }

View File

@ -69,6 +69,20 @@ class LoginModel extends CI_Model
} }
} }
public function reloadLoginSession($logindata) {
$_SESSION['user']['displayname'] = $logindata['displayname'];
$_SESSION['user']['username'] = $logindata['username'];
$_SESSION['user']['rank'] = $logindata['rank'];
$_SESSION['user']['ID'] = $logindata['ID'];
$_SESSION['user']['ads'] = $logindata['showAds'];
$profilePic = $logindata['profile_picture'];
if (empty($profilePic)) {
$_SESSION['user']['profilePic'] = '/assets/images/steam.jpg';
} else {
$_SESSION['user']['profilePic'] = $profilePic;
}
}
public function getUserHash($username, $password, $email, $id) public function getUserHash($username, $password, $email, $id)
{ {
$hash = hash('sha256', $id . '//' . $username . '//' . substr($password, 0, 5) . '//' . substr($email, 0, 5)); $hash = hash('sha256', $id . '//' . $username . '//' . substr($password, 0, 5) . '//' . substr($email, 0, 5));

View File

@ -10,32 +10,33 @@ $this->load->view('network/user/profile_page_header');
<?= $message ?> <?= $message ?>
<h1>Profil bearbeiten</h1> <h1>Profil bearbeiten</h1>
<div class="row"> <div class="row">
<div class="col-xs-3 vertical-tab-menu"> <div class="col-3">
<div class="list-group"> <div class="nav nav-pills flex-column" role="tablist" aria-orientation="vertical">
<a href="#" class="list-group-item active text-center" id="general"> <a href="#general" class="nav-link active text-center" role="tab" data-toggle="pill" id="general-pill" aria-controls="general" aria-selected="true">
<i class="fa fa-tasks"></i> <i class="fa fa-tasks"></i>
<br> <br>
Allgemein Allgemein
</a> </a>
<a href="#" class="list-group-item text-center" id="email"> <a href="#email" class="nav-link text-center" role="tab" data-toggle="pill" id="email-pill" aria-controls="email" aria-selected="false">
<i class="fa fa-envelope"></i> <i class="fa fa-envelope"></i>
<br> <br>
E-Mail E-Mail
</a> </a>
<a href="#" class="list-group-item text-center" id="password"> <a href="#password" class="nav-link text-center" role="tab" data-toggle="pill" id="password-pill" aria-controls="password" aria-selected="false">
<i class="fa fa-lock"></i> <i class="fa fa-lock"></i>
<br> <br>
Passwort & Sicherheit Passwort & Sicherheit
</a> </a>
<a href="#" class="list-group-item text-center" id="premium"> <a href="#premium" class="nav-link text-center" role="tab" data-toggle="pill" id="premium-pill" aria-controls="premium" aria-selected="false">
<i class="fa fa-star"></i> <i class="fa fa-star"></i>
<br> <br>
Premium Premium
</a> </a>
</div> </div>
</div> </div>
<div class="col-xs-9 vertical-tabs"> <div class="col-9">
<div class="vertical-tab-content active" id="general"> <div class="tab-content" id="tabContent">
<div class="tab-pane fade show active" id="general" role="tabpanel" aria-labelledby="general-pill">
<form method="post" enctype="multipart/form-data"> <form method="post" enctype="multipart/form-data">
<!-- Username --> <!-- Username -->
<div class="form-group"> <div class="form-group">
@ -69,7 +70,7 @@ $this->load->view('network/user/profile_page_header');
<div class="form-group"> <div class="form-group">
<label for="birthdate">Geburtsdatum</label> <label for="birthdate">Geburtsdatum</label>
<div class="row"> <div class="row">
<div class="col-xs-6"> <div class="col-6">
<select name="birthdate-month" id="birthdate-month" class="form-control" <select name="birthdate-month" id="birthdate-month" class="form-control"
data-default="<?= isset($data['birthdate']) ? explode('.', $data['birthdate'])[1] : '' ?>"> data-default="<?= isset($data['birthdate']) ? explode('.', $data['birthdate'])[1] : '' ?>">
<option value="">-- Monat --</option> <option value="">-- Monat --</option>
@ -87,7 +88,7 @@ $this->load->view('network/user/profile_page_header');
<option value="12">Dezember</option> <option value="12">Dezember</option>
</select> </select>
</div> </div>
<div class="col-xs-6"> <div class="col-6">
<select name="birthdate-day" id="birthdate-day" class="form-control" <select name="birthdate-day" id="birthdate-day" class="form-control"
data-default="<?= isset($data['birthdate']) ? explode('.', $data['birthdate'])[0] : '' ?>"> data-default="<?= isset($data['birthdate']) ? explode('.', $data['birthdate'])[0] : '' ?>">
<option value="">-- Tag --</option> <option value="">-- Tag --</option>
@ -95,7 +96,7 @@ $this->load->view('network/user/profile_page_header');
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-xs-offset-3"> <div class="col-6 col-offset-3">
<select name="birthdate-year" id="birthdate-year" class="form-control"> <select name="birthdate-year" id="birthdate-year" class="form-control">
<option value="">-- Jahr --</option> <option value="">-- Jahr --</option>
</select> </select>
@ -1092,7 +1093,7 @@ $this->load->view('network/user/profile_page_header');
<div class="form-group"> <div class="form-group">
<label for="avatar">Avatar</label> <label for="avatar">Avatar</label>
<?php if (isset($data['profile_picture']) || $data['profile_picture'] != ""): ?> <?php if (isset($data['profile_picture']) || $data['profile_picture'] != ""): ?>
<img class="img-fluid thumbnail picture-preview" <img class="img-fluid img-thumbnail picture-preview d-block"
src="<?= $data['profile_picture'] ?>"> src="<?= $data['profile_picture'] ?>">
<?php endif; ?> <?php endif; ?>
<input type="file" name="avatar"> <input type="file" name="avatar">
@ -1101,7 +1102,7 @@ $this->load->view('network/user/profile_page_header');
<div class="form-group"> <div class="form-group">
<label for="header">Header</label> <label for="header">Header</label>
<?php if (isset($data['header_image']) || $data['header_image'] != ""): ?> <?php if (isset($data['header_image']) || $data['header_image'] != ""): ?>
<img class="img-fluid thumbnail picture-preview" <img class="img-fluid img-thumbnail picture-preview d-block"
src="<?= $data['header_image'] ?>"> src="<?= $data['header_image'] ?>">
<?php endif; ?> <?php endif; ?>
<input type="file" name="header"> <input type="file" name="header">
@ -1113,7 +1114,7 @@ $this->load->view('network/user/profile_page_header');
<input type="submit" class="btn btn-primary" value="Speichern"> <input type="submit" class="btn btn-primary" value="Speichern">
</form> </form>
</div> </div>
<div class="vertical-tab-content" id="email"> <div class="tab-pane fade" id="email" role="tabpanel" aria-labelledby="email-pill">
<form method="post"> <form method="post">
<div class="form-group"> <div class="form-group">
<label for="email">E-Mail-Adresse</label> <label for="email">E-Mail-Adresse</label>
@ -1138,7 +1139,7 @@ $this->load->view('network/user/profile_page_header');
<input type="submit" class="btn btn-primary" value="Speichern"> <input type="submit" class="btn btn-primary" value="Speichern">
</form> </form>
</div> </div>
<div class="vertical-tab-content" id="password"> <div class="tab-pane fade" id="password" role="tabpanel" aria-labelledby="password-pill">
<form method="post"> <form method="post">
<div class="form-group"> <div class="form-group">
<label for="passwordOld">Altes Passwort</label> <label for="passwordOld">Altes Passwort</label>
@ -1155,7 +1156,7 @@ $this->load->view('network/user/profile_page_header');
<input type="submit" class="btn btn-primary" value="Speichern"> <input type="submit" class="btn btn-primary" value="Speichern">
</form> </form>
</div> </div>
<div class="vertical-tab-content" id="premium"> <div class="tab-pane fade" id="premium" role="tabpanel" aria-labelledby="premium-pill">
<form method="post"> <form method="post">
<?php if (isset($_SESSION['user']['rank']) && $_SESSION['user']['rank'] >= 2): ?> <?php if (isset($_SESSION['user']['rank']) && $_SESSION['user']['rank'] >= 2): ?>
<div class="form-group"> <div class="form-group">
@ -1173,7 +1174,8 @@ $this->load->view('network/user/profile_page_header');
Services und gleichzeitig erhälst du die Möglichkeit, den Dienst ohne Werbung zu Services und gleichzeitig erhälst du die Möglichkeit, den Dienst ohne Werbung zu
erleben.</p> erleben.</p>
<p>Plus-Nutzer oder Team-Mitglied kannst du nur auf persönliche Einladung eines <p>Plus-Nutzer oder Team-Mitglied kannst du nur auf persönliche Einladung eines
hochrangigen Team-Mitgliedes werden. Der Plus-Rang wird beispielsweise an YouTuber, hochrangigen Team-Mitgliedes werden. Der Plus-Rang wird beispielsweise an
YouTuber,
bekannte Persönlichkeiten, sehr aktive Nutzer, sehr großzügige Spender, aktive bekannte Persönlichkeiten, sehr aktive Nutzer, sehr großzügige Spender, aktive
Abonnenten des Kanals <a href="https://youtube.com/KingOfDog" target="_blank">KingOfDog</a> Abonnenten des Kanals <a href="https://youtube.com/KingOfDog" target="_blank">KingOfDog</a>
oder Freunde und Bekannte vergeben.</p> oder Freunde und Bekannte vergeben.</p>
@ -1186,51 +1188,15 @@ $this->load->view('network/user/profile_page_header');
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
<style> <style>
#profile-content-container { .nav-pills .nav-link {
min-height: 375px; position: relative;
transition: color .2s, background-color .2s;
} }
.vertical-tab-menu { .nav-pills .nav-link:after {
padding-right: 0;
padding-left: 0;
padding-bottom: 0;
}
.vertical-tab-menu .list-group {
margin-bottom: 0;
}
.vertical-tab-menu .list-group > a {
margin-bottom: 0;
border: 0;
}
.vertical-tab-menu .list-group > a .fa {
color: #2272FF;
}
.vertical-tab-menu .list-group > a:first-child {
border-top-right-radius: 0;
-moz-border-top-right-radius: 0;
}
.vertical-tab-menu .list-group > a:last-child {
border-bottom-right-radius: 0;
-moz-border-bottom-right-radius: 0;
}
.vertical-tab-menu .list-group > a.active {
background-color: #2272FF;
color: #ffffff;
}
.vertical-tab-menu .list-group > a.active .fa {
color: #ffffff;
}
.vertical-tab-menu .list-group > a.active:after {
content: ''; content: '';
position: absolute; position: absolute;
left: 100%; left: 100%;
@ -1239,21 +1205,26 @@ $this->load->view('network/user/profile_page_header');
border-left: 0; border-left: 0;
border-bottom: 13px solid transparent; border-bottom: 13px solid transparent;
border-top: 13px solid transparent; border-top: 13px solid transparent;
border-left: 10px solid #2272FF; border-left: 10px solid transparent;
transition: border-left-color .2s;
} }
.vertical-tabs { .nav-pills .nav-link:not(.active):hover,
margin-left: -15px; .nav-pills .nav-link:not(.active):focus {
color: #2272ff !important;
} }
.vertical-tab-content { .nav-pills .nav-link.active {
background-color: #ffffff; color: #fff !important;
padding: 10px 25px; background-color: #2272ff;
min-height: 285px;
} }
.vertical-tabs .vertical-tab-content:not(.active) { .nav-pills .nav-link.active:after {
display: none; border-left-color: #2272ff;
}
#profile-content-container {
min-height: 375px;
} }
.picture-preview { .picture-preview {