Solution
index.php
<?php
function printForm() {
echo <<<__HTML__
<form method="POST" enctype="multipart/form-data" action="?">
<fieldset>
<input type="hidden" name="form" value="reprint">
<legend>Create a New Reprint</legend>
<table>
<tr>
<td colspan="2"><p>
<label for="title">Title</label><br>
<input type="text" id="title" class="required hilightable" name="info[title]">
</p></td>
</tr>
<tr>
<td><p>
<label for="artist">Artist</label><br>
<input type="text" id="artist" class="required hilightable" name="info[artist]">
</p></td>
<td><p>
<label for="year">Year</label><br>
<input type="year" id="year" class="required hilightable" name="info[year]">
</p></td>
</tr>
<tr>
<td colspan="2"><p>
<label for="desc">Description</label><br>
<textarea id="desc" class="required hilightable" name="info[desc]"></textarea>
</p></td>
</tr>
<tr class="variation">
<td><p>
<label for="var-1">Variation Name</label><br>
<input type="text" id="var-1" class="required hilightable" name="info[variations][]">
</p></td>
<td>
<p>
<label for="price-1">Price</label><br>
<input type="number" id="price-1" step="1" min="1" class="required hilightable" name="info[prices][]">
</p>
</td>
</tr>
<tr id="addVariation">
<td colspan="2"><p>
<input type="button" class="btn" value="Add Variation">
</p></td>
</tr>
<tr>
<td><p>
<label for="file">Reprint Image</label><br>
<input type="file" id="file" accept="image/*" name="reprint">
</p></td>
<td><img id="file_preview" style="display:none;"></td>
</tr>
<tr>
<td colspan="2">
<div class="rectangle centered">
<input type="submit" class="btn"> <input type="reset" value="Clear Form" class="btn">
</div>
</td>
</tr>
</table>
<template id="variation">
<tr class="variation">
<td class="var"><p>
<label>Variation Name</label><br>
<input type="text" class="required hilightable" name="info[variations][]">
</p></td>
<td class="price">
<p>
<label>Price</label><br>
<input type="number" step="1" min="1" class="required hilightable" name="info[prices][]">
</p>
<div class="remove">X</div>
</td>
</tr>
</template>
</fieldset>
</form>
__HTML__;
}
function printAnswers() {
$reprints = scandir('./data/');
foreach ($reprints as $rp) {
if ($rp == '.' || $rp == '..') { continue; }
$DATA=[];
include('./data/'.$rp);
$variations = '';
foreach ($DATA['variations'] as $info) {
$variations .= '<li>'.$info['name'].' - $'.$info['price'].'</li>';
}
echo <<<__HTML__
<div class="entry">
<img src="{$DATA['file']}">
<div class="info">
<h2>{$DATA['name']}</h2>
<h3>by {$DATA['artist']} (c.{$DATA['date']})</h3>
<p>{$DATA['desc']}</p>
<h4>Variations</h4>
{$variations}
</div>
</div>
__HTML__;
}
}
echo <<<__HTML__
<!DOCTYPE html>
<html>
<head>
<title>Lab #4 - Forms</title>
<style>
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
@import url(https://fonts.googleapis.com/css?family=Merriweather);
/* general text formatting */
h1, h2, h3, legend {
font-family: 'Merriweather', serif; }
body {
font-family: 'Open Sans', Arial, sans-serif;
font-size: 16px;
}
table {
width: 90%;
margin: 0 auto;
}
table tbody td{
vertical-align: top;
}
legend {
background-color: #616161 ;
color: white;
margin: 0 auto;
width: 90%;
padding: 0.25em;
text-align: center;
font-weight: bold;
font-size: 24px;
}
fieldset {
margin: 1em auto;
background-color: #F5F5F5;
width: 70%;
}
form p {
margin-top: 0.5em;
}
form input, form select {
font-size: 16px;
height: 24px;
padding: 3px;
}
form select {
height: 30px;
}
form textarea {
height: 5em;
}
#title, #desc { width: 100% }
#artist { width: 90%; }
#year { width: 40%; }
.variation input[type=text] { width: 90%; }
.variation input[type=number] { width: 40%; }
td img { max-width: 90%; }
.variation td { position: relative; }
.remove {
position: absolute;
top: 18px;
font-size: 2em;
left: 40%;
margin-left: 20px;
background-color: #ff9100a6;
border-radius: 5px;
border: solid 1px black;
padding: 5px;
}
.box {
border: 1pt solid #9E9E9E;
padding: 0.5em;
margin-bottom: 0.4em;
}
.rectangle {
background-color: #BDBDBD;
padding: 0.5em;
margin-bottom: 5px;
}
.centered {
text-align: center;
}
.highlight {
background-color: #FFE0B2;
}
.error {
background: #FFCDD2 url(http://74.208.52.43/resources/csci2005/lab10/error.png) no-repeat 98% center;
box-shadow: 0 0 5px #FF5252;
border-color: #FF1744;
}
.btn {
-webkit-border-radius: 3;
-moz-border-radius: 3;
border-radius: 3px;
height: 32px;
color: black;
font-size: 14px;
background: #FF9100;
padding: 5px 20px 5px 20px;
text-decoration: none;
}
.btn:hover {
background: #FFAB40;
text-decoration: none;
}
.info {
max-width: 50%;
display: inline-block;
vertical-align: top;
}
.entry {
border: 1px solid black;
border-radius: 5px;
padding: 10px;
}
.entry img {
max-width:45%;
display: inline;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var varCount = 1;
document.querySelector("form").addEventListener("focusin",(e) => {
if (e.target.classList.contains("hilightable")) {
e.target.classList.add("highlight");
e.target.classList.remove("error");
}
});
document.querySelector("form").addEventListener("focusout",(e) => {
e.target.classList.remove("highlight");
if (e.target.classList.contains("required") && e.target.value == "") {
e.target.classList.add("error");
}
});
document.querySelector("form").addEventListener("submit",(e) => {
document.querySelectorAll(".required").forEach((elem) => {
if (elem.value == "") {
e.preventDefault();
elem.classList.add("error");
}
});
});
document.querySelector("#addVariation input").addEventListener("click",(e) => {
var template = document.querySelector("#variation").content.cloneNode(true);
varCount++;
template.querySelector(".var label").setAttribute("for","var-"+varCount);
template.querySelector(".var input").setAttribute("id", "var-"+varCount);
template.querySelector(".price label").setAttribute("for","price-"+varCount);
template.querySelector(".price input").setAttribute("id", "price-"+varCount);
var ref = document.querySelector("#addVariation");
ref.parentElement.insertBefore(template,ref);
});
document.querySelector("form").addEventListener("click",(e) => {
if (e.target.classList.contains("remove")) {
e.target.closest("tr").remove();
}
});
document.querySelector("#file").addEventListener("change",(e) => {
var prev = document.querySelector("#file_preview");
prev.style.display="block";
const [file] = e.target.files;
prev.src = URL.createObjectURL(file);
});
});
</script>
</head>
<body>
__HTML__;
$msg = 'Uploads Disabled';
if (isset($_POST['form']) && $_POST['form'] == 'reprint') {
$reprint = [
'name'=>$_POST['info']['title'],
'artist'=>$_POST['info']['artist'],
'date'=>intval($_POST['info']['year']),
'desc'=>$_POST['info']['desc'],
'variations'=>[],
'file'=>'',
];
foreach ($_POST['info']['variations'] as $k=>$v) {
$reprint['variations'][] = [
'name'=>$v,
'price'=>intval($_POST['info']['prices'][$k]),
];
}
/* is the files array formatted as expected */
if (!isset($_FILES['reprint']['error']) || is_array($_FILES['reprint']['error'])) {
$msg = 'Invalid Parameter';
}
/* What is the error status */
if (strlen($msg) == 0) {
switch ($_FILES['reprint']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
$msg = 'No file sent';
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
$msg = 'Exceeded filesize limit';
break;
default:
$msg = 'Unknown error';
break;
}
}
/* Is the file the correct size */
if (strlen($msg) == 0) {
if ($_FILES['reprint']['size'] > 1000000) {
$msg = 'Exceeded filesize limit';
}
}
/* Check the file type */
$ext = '';
if (strlen($msg) == 0) {
$finfo = new finfo(FILEINFO_MIME_TYPE);
$ext = array_search($finfo->file($_FILES['reprint']['tmp_name']), [
'jpg'=>'image/jpeg',
'png'=>'image/png',
],true);
if ($ext === false) {
$msg = 'Invalid file format';
}
}
$name = '';
do {
$name = sprintf("reprint_%d",time());
} while (file_exists('./data/'.$name.'.php'));
if (strlen($msg) == 0) {
/* Determine a name for the file */
$reprint['file'] = sprintf('./images/%s.%s',$name,$ext);
if (!move_uploaded_file($_FILES['reprint']['tmp_name'],$reprint['file'])) {
$msg = 'Failed to move uploaded file';
}
}
if (strlen($msg) == 0) {
/* We have passed all of the checks */
file_put_contents(
sprintf('./data/%s.php',$name),
'<?php $DATA='.var_export($reprint,true).'; ?>'
);
}
}
if ($msg != '') {
echo '<h2>ERROR: '.$msg.'</h2>';
}
printForm();
printAnswers();
echo <<<__HTML__
</body>
</html>
__HTML__;
?>
Due to the nature of this exercise including file uploads, there is not a full demonstration of the target goal. The following script demo-page will do all of the same actions as your goal, but it will not display your images (it will display a placeholder instead)Go To Live Site