This commit is contained in:
Peter Hoppe
2023-01-04 10:21:08 +01:00
14 changed files with 326 additions and 111 deletions

1
.gitignore vendored
View File

@ -13,7 +13,6 @@
# misc # misc
.DS_Store .DS_Store
.env.local
.env.development.local .env.development.local
.env.test.local .env.test.local
.env.production.local .env.production.local

13
.vscode/launch.json vendored
View File

@ -1,10 +1,15 @@
{ {
// Verwendet IntelliSense zum Ermitteln möglicher Attribute.
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen.
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": [
9003,
9000
]
},
{ {
"type": "chrome", "type": "chrome",
"request": "launch", "request": "launch",

76
docs/dogs.sql Normal file
View File

@ -0,0 +1,76 @@
-- phpMyAdmin SQL Dump
-- version 5.1.3
-- https://www.phpmyadmin.net/
--
-- Host: 10.35.232.188:3306
-- Erstellungszeit: 29. Dez 2022 um 20:55
-- Server-Version: 8.0.31
-- PHP-Version: 7.4.32
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Datenbank: `k200835_dog`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `dogs`
--
CREATE TABLE `dogs` (
`id` int NOT NULL,
`email` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL,
`qr_id` char(31) COLLATE utf8mb3_unicode_ci NOT NULL,
`name` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '',
`password` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL,
`phone` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL DEFAULT '',
`qr_code` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL,
`picture` varchar(255) COLLATE utf8mb3_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
--
-- Daten für Tabelle `dogs`
--
INSERT INTO `dogs` (`id`, `email`, `qr_id`, `name`, `password`, `phone`, `qr_code`, `picture`) VALUES
(4, 'a@q.q', 'r0hhpZ', 'ddddd', '$2y$10$kQWHhEr9m3w5BfqRMN0WauUBI.OaRR86X8lssTlOX5UnMOTdqEKOa', '', NULL, NULL),
(5, 'conny.rankl@web.de', 'm7MdMK', 'Melly', '$2y$10$2WscecdKZv73sl2E1cdg5OKNGpfDzSRyrQeu8ebZIgIiLexztgbHa', '+49 171 7328974', '/m7MdMK/7a0LA4ZlWVXYhPArDRU8.png', '/m7MdMK/eywPirFAyg9jSIvoK4KZ.jpg'),
(11, 'p.para@gmx.de', 'YQiwEB', 'Conny', '$2y$10$/W.2pZLhhxoW7j6M5KcXJ.HWDJBc98fpapTaWm9hxKXYfA5YZiinK', '+49 179 5035966', '/YQiwEB/PbygxRtUBkhQrekdIdER.png', '/YQiwEB/8w0iUcSKM0bvSmC8i6cL.png'),
(12, 'eva-maria-cat@web.de', '17dg43', 'Bonny', '$2y$10$AsTXWioe5pyMNqAPN8DoJuovIkkfZkYci2Z5VG3a9uf545jbCqUta', '+49 171 7923900', '/17dg43/0GH7skrnnzBYUDuIIybR.png', '/17dg43/GmFlF0nh7GU02wNuIFcX.jpg');
--
-- Indizes der exportierten Tabellen
--
--
-- Indizes für die Tabelle `dogs`
--
ALTER TABLE `dogs`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `index_qr_id` (`qr_id`),
ADD UNIQUE KEY `index_email` (`email`);
--
-- AUTO_INCREMENT für exportierte Tabellen
--
--
-- AUTO_INCREMENT für Tabelle `dogs`
--
ALTER TABLE `dogs`
MODIFY `id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

View File

@ -25,7 +25,10 @@
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"postbuild": "cp ./src/.htaccess ./build/ && sudo cp -r -v ./build/static/ /opt/lampp/htdocs/dog/ && sudo cp -v ./build/* /opt/lampp/htdocs/dog/" "build:local": "env-cmd -f .env.local npm run build",
"build:hope-fly": "env-cmd -f .env.hope-fly npm run build",
"postbuild:local": "cp ./src/.htaccess ./build && sudo cp -vrRT ./build/. /opt/lampp/htdocs/dog/",
"postbuild:hope-fly": "cp ./src/.htaccess ./build"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [

View File

@ -46,6 +46,23 @@ class CUser
$this->qr_id = $qr_id; $this->qr_id = $qr_id;
$this->email = $email; $this->email = $email;
} }
function jsonarray()
{
return json_encode([
'id' => $this->id,
'qr_id' => $this->qr_id,
'email' => $this->email
]);
}
function phparray()
{
return ([
'id' => $this->id,
'qr_id' => $this->qr_id,
'email' => $this->email
]);
}
} }
/** /**
@ -81,18 +98,26 @@ function random_str(
function getNewFilename($targetDir, $fileExt, $length) function getNewFilename($targetDir, $fileExt, $length)
{ {
$newFname = random_str($length); $newFname = random_str($length);
// echo "newFname " . $newFname . "\n";
$maxtries = 100000; // prevent endless loop, most unlikely $maxtries = 100000; // prevent endless loop, most unlikely
$tries = 0; $tries = 0;
// echo "file_exists " . $targetDir . '/' . $newFname . '.' . $fileExt . "\n";
// echo "file_exists " . file_exists($targetDir . '/' . $newFname . '.' . $fileExt) . "\n";
while(file_exists($targetDir . '/' . $newFname . '.' . $fileExt) && $tries < $maxtries) while(file_exists($targetDir . '/' . $newFname . '.' . $fileExt) && $tries < $maxtries)
{ {
// echo "file_exists " . $targetDir . '/' . $newFname . '.' . $fileExt . "\n";
++$tries; ++$tries;
$newFname = random_str($length); $newFname = random_str($length);
// echo "tries " . $tries . "\n";
// echo "newFname " . $newFname . "\n";
} }
if($tries < $maxtries) if($tries >= $maxtries)
{ {
$newFname = ""; $newFname = "";
} }
return $newFname; return $newFname .".".$fileExt;
} }
?> ?>

View File

@ -89,7 +89,8 @@ try
$row['qr_id'], $row['qr_id'],
$row['email'] $row['email']
); );
$_SESSION['user'] = $user; // $_SESSION['user'] = $user;
$_SESSION['user'] = $user->phparray();
$returnData = new CMsg( $returnData = new CMsg(
1, 1,

View File

@ -5,79 +5,135 @@ header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8"); header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
session_start();
require __DIR__.'/classes/Database.php'; try {
require __DIR__.'/classes/lib.php';
$result = new CMsg(0);
if(!isset($_SESSION["user"])) session_start();
{
$result = new CMsg(0, 401, "not logged in");
return $result->jsonarray();
}
$user = $_SESSION["user"]; // $resp = json_decode('
$allowTypes = array('jpg','png','jpeg','gif','pdf'); // {
// "success": 1,
// "user": {
// "__PHP_Incomplete_Class_Name": "CUser",
// "id": 11,
// "qr_id": "YQiwEB",
// "email": "p.para@gmx.de"
// }
// }');
// File upload path // $_SESSION["user"] = $resp["user"];
$targetDir = "uploads/".$user->qr_id;
if (!file_exists($targetDir))
{
mkdir($targetDir, 0755, true);
}
$fileName = basename($_FILES["file"]["name"]); require __DIR__ . '/classes/Database.php';
$fileType = pathinfo($fileName,PATHINFO_EXTENSION); require __DIR__ . '/classes/lib.php';
if(!in_array($fileType, $allowTypes)) $result = new CMsg(0);
{
$result = new CMsg(
0,
406,
'Sorry, only JPG, JPEG, PNG, GIF, & PDF files are allowed to upload.');
return $result->jsonarray();
}
$newFilename = getNewFilename($targetDir, $fileType, 20); if (!isset($_SESSION["user"]))
if(strlen($newFilename) == 0)
{
$result = new CMsg(
0,
507,
'Too many uploaded files on the server, try it again later');
return $result->jsonarray();
}
$targetFilePath = $targetDir . '/' . $fileName;
if(isset($_POST["submit"]) && !empty($_FILES["file"]["name"]))
{
// Upload file to server
if(move_uploaded_file($_FILES["file"]["tmp_name"], $targetFilePath))
{ {
// Insert image file name into database $result = new CMsg(0, 401, "not logged in");
$update = $db->query("UPDATE dogs SET picture = '".$fileName."' WHERE qr_id = ".$user->qr_id); echo $result->jsonarray();
if($update) return $result->jsonarray();
{
$result = new CMsg(1,200,"The file ".$fileName. " has been uploaded successfully.");
}
else
{
$result = new CMsg(0,500,"File upload failed, please try again.");
}
} }
$user = $_SESSION["user"];
$allowTypes = array('jpg', 'png', 'jpeg', 'gif', 'pdf');
//echo var_dump($user);
// File upload path
$targetDir = "../uploads/" . $user["qr_id"];
if (!file_exists($targetDir))
{
mkdir($targetDir, 0755, true);
}
echo "targetDir ". $targetDir . "\n";
$fileName = basename($_FILES["file"]["name"]);
$fileType = pathinfo($fileName, PATHINFO_EXTENSION);
echo "fileName ".$fileName . "\n";
echo "fileType ".$fileType . "\n";
if (!in_array($fileType, $allowTypes))
{
$result = new CMsg(
0,
406,
'Sorry, only JPG, JPEG, PNG, GIF, & PDF files are allowed to upload.'
);
echo $result->jsonarray();
return $result->jsonarray();
}
$newFilename = getNewFilename($targetDir, $fileType, 20);
echo "newFilename ".$newFilename . "\n";
if (strlen($newFilename) == 0)
{
$result = new CMsg(
0,
507,
'Too many uploaded files on the server, try it again later'
);
echo $result->jsonarray();
return $result->jsonarray();
}
$targetFilePath = $targetDir . '/' . $newFilename;
echo "targetFilePath ". $targetFilePath."\n";
if (isset($_POST["submit"]) && !empty($_FILES["file"]["name"]))
{
echo "submit file name ". $_FILES["file"]["name"]."\n";
// Upload file to server
if (move_uploaded_file($_FILES["file"]["tmp_name"], $targetFilePath))
{
echo "move ok! ". $targetFilePath."\n";
$newPathFilename = '/' . $user["qr_id"] . '/' . $newFilename;
echo "query " . "UPDATE dogs SET picture = '" . $newPathFilename . "' WHERE qr_id = '" . $user["qr_id"]."'\n";
$db_connection = new Database();
$conn = $db_connection->dbConnection();
echo var_dump($conn);
// Insert image file name into database
$statement = $conn->prepare("UPDATE dogs SET picture = :filePic WHERE qr_id = :user_qr_id");
$update = $statement->execute(array('filePic' => $newPathFilename, 'user_qr_id' => $user["qr_id"]));
echo var_dump($update);
$count = $statement->rowCount();
echo 'rowcount ' . $count . '\n';
if ($update && $count > 0)
{
$result = new CMsg(1, 200, "The file " . $newPathFilename . " has been uploaded successfully.");
echo $result->jsonarray();
}
else
{
$result = new CMsg(0, 500, "File upload failed, please try again.");
echo $result->jsonarray();
}
}
else
{
$result = new CMsg(0, 500, "Sorry, there was an error uploading your file.");
}
}
else else
{ {
$result = new CMsg(0,500,"Sorry, there was an error uploading your file."); $result = new CMsg(1, 204, 'Please select a file to upload.');
} }
}
else
{
$result = new CMsg(1,204,'Please select a file to upload.');
}
// Display status message // Display status message
echo $result->jsonarray(); echo $result->jsonarray();
?> }
catch(Exception $e)
{
$result = new CMsg(0, 500, $e->getMessage() );
echo $result->jsonarray();
}
?>

View File

@ -33,7 +33,7 @@ const App: React.FC = () =>
<Route path="/login" element={<Login/>} /> <Route path="/login" element={<Login/>} />
<Route path="/reg" element={<Register/>} /> <Route path="/reg" element={<Register/>} />
<Route path="/impressum" element={<Impressum/>} /> <Route path="/impressum" element={<Impressum/>} />
<Route path="/upload" element={<FileUpload/>} /> {user && <Route path="/upload" element={<FileUpload/>} />}
</Routes> </Routes>
<Footer/> <Footer/>
</BrowserRouter> </BrowserRouter>

View File

@ -1,13 +1,13 @@
import { useState, useEffect } from "react"; import { useState } from "react";
import UploadService from "../services/FileUploadService"; import UploadService from "../services/FileUploadService";
import IFile from "../types/File"; import IFile from "../types/File";
import PreviewUpload from "./PreviewUpload";
const FileUpload: React.FC = () => const FileUpload: React.FC = () =>
{ {
const [currentFile, setCurrentFile] = useState<File>(); const [currentFile, setCurrentFile] = useState<File>();
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const [message, setMessage] = useState(""); const [message, setMessage] = useState("");
const [fileInfos, setFileInfos] = useState([]);
const selectFile = (event: React.ChangeEvent<HTMLInputElement>) => const selectFile = (event: React.ChangeEvent<HTMLInputElement>) =>
@ -30,11 +30,7 @@ const FileUpload: React.FC = () =>
.then((response) => .then((response) =>
{ {
setMessage(response.data.message); setMessage(response.data.message);
return UploadService.getFiles(); return;
})
.then((files) =>
{
setFileInfos(files.data);
}) })
.catch((err) => .catch((err) =>
{ {
@ -53,25 +49,17 @@ const FileUpload: React.FC = () =>
}); });
}; };
useEffect(() =>
{
UploadService.getFiles().then((response) =>
{
setFileInfos(response.data);
});
}, []);
return ( return (
<div> <div>
<div className="row"> <div className="row">
<div className="col-8"> <div className="col-8">
<label className="btn btn-default p-0"> <PreviewUpload chgFile={selectFile} />
{/* <label className="btn btn-default p-0">
<input type="file" onChange={selectFile} /> <input type="file" onChange={selectFile} />
</label> </label> */}
</div> </div>
<div className="col-4"> <div className="col-4">
<button <button
className="btn btn-success btn-sm" className="btn btn-success btn-sm"
@ -104,17 +92,6 @@ const FileUpload: React.FC = () =>
</div> </div>
)} )}
<div className="card mt-3">
<div className="card-header">List of Files</div>
<ul className="list-group list-group-flush">
{fileInfos &&
fileInfos.map((file: IFile, index: number) => (
<li className="list-group-item" key={index}>
<a href={file.url}>{file.name}</a>
</li>
))}
</ul>
</div>
</div> </div>
); );

View File

@ -0,0 +1,72 @@
import React, { useState } from 'react';
function PreviewUpload({chgFile}:{chgFile: any}) {
const [file, setFile] = useState<string | undefined >(undefined);
const [dimensionWidth, setDimensionWidth] = useState(0);
const [dimensionHeight, setDimensionHeight] = useState(0);
const handleChange = async (
event: React.ChangeEvent<HTMLInputElement>
): Promise<any> => {
// const { target } = event;
// const img = new Image();
const ImageName = event.target.value.split('\\')[2];
const Image = event.target.value;
console.log('Imageon Kevel: ', Image); // Image on Kevel
console.log('ImageName on Kevel: ', ImageName); // ImageName on Kevel
console.log('ImageLink on Kevel: ', event.target.value); // ImageLink on Kevel
console.log('event current Target files: ', event.target.files![0]);
const fileLoaded = URL.createObjectURL(event.target.files![0]);
const files = event.target.files;
console.log('files: ', files);
const dimensions = await someFunction(fileLoaded);
setDimensionWidth(dimensions.width);
setDimensionHeight(dimensions.height);
console.log('dimensions: ', dimensions);
console.log('dimensions width: ', dimensions.width);
console.log('dimensions height: ', dimensions.height);
setFile(fileLoaded);
chgFile(event);
};
const getHeightAndWidthFromDataUrl = (dataURL: string) =>
new Promise<{height: number, width: number}>((resolve) => {
const img = new Image();
img.onload = () => {
resolve({
height: img.height,
width: img.width,
});
};
img.src = dataURL;
});
// Get dimensions
const someFunction = async (file: any) => {
console.log('file: ', file);
const dimensions = await getHeightAndWidthFromDataUrl(file);
return dimensions;
};
return (
<div>
<input
type="file"
onChange={handleChange}
accept="image/jpg,.gif,.png,.svg,.webp audio/wav,.mp3"
/>
<img
src={file}
style={{
display: 'flex',
border: '2px solid tomato',
maxWidth: '300px',
maxHeight: '300px',
}}
/>
{file && <p>Dimensions: {`${dimensionWidth} x ${dimensionHeight}`}</p>}
</div>
);
}
export default PreviewUpload;

View File

@ -77,8 +77,8 @@ export const UserCtx = createContext<UserCtxT | null>(null);
export const Axios = axios.create({ export const Axios = axios.create({
// baseURL: 'http://localhost/dog/php-dog/', // baseURL: 'http://localhost/dog/php-dog/',
baseURL: 'https://hope-fly.de/dog/php-dog/', // baseURL: 'https://hope-fly.de/dog/php-dog/',
// baseURL: process.env.REACT_APP_PHP_ROOT, baseURL: process.env.REACT_APP_PHP_ROOT,
}); });
export const UserCtxProvider = ({children}:TUserContextProviderProps) => { export const UserCtxProvider = ({children}:TUserContextProviderProps) => {

View File

@ -6,22 +6,23 @@ const upload = (file: File, onUploadProgress: any): Promise<any> => {
let formData = new FormData(); let formData = new FormData();
formData.append("file", file); formData.append("file", file);
formData.append("submit", "1");
return Axios.post("/upload", formData, { let uploadRes = Axios.post("upload.php", formData, {
headers: { headers: {
"Content-Type": "multipart/form-data", "Content-Type": "multipart/form-data",
}, },
onUploadProgress, onUploadProgress,
}); });
// let a: number = 1+3;
// a++;
return uploadRes;
}; };
const getFiles = () : Promise<any> => {
return Axios.get("/files");
};
const FileUploadService = { const FileUploadService = {
upload, upload
getFiles,
}; };
export default FileUploadService; export default FileUploadService;