>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
include_once('config.php');
if(isset($_COOKIE['PHPSESSID'])){session_start();}
if(!isset($_SESSION['id'])){header('Location: '.BASEURL.'/login?returnto='.urlencode($_SERVER['REQUEST_URI']));}
include_once('db.php');
include_once('nonce.php');
include_once('files.php');
$id=$path[2];
$error='';
function insertfile($thingid, $name, $hash, $preview)
{
global $db;
$res=mysqli_query($db, 'select id from files where thing='.$thingid.', name="'.$name.'"');
if($id=mysqli_fetch_row($res)) // Handle name collisions (overwrite DB entry by updating the hash)
{
$id=(int)$id[0];
mysqli_query($db, 'update files set hash="'.$hash.'", preview='.($preview?'true':'false').' where id='.$id);
}else{
mysqli_query($db, 'insert into files(thing, name, hash, preview) values('.$thingid.', "'.$name.'", "'.$hash.'", '.($preview?'true':'false').')');
}
}
if(isset($_POST['name']) && isset($_POST['description']) && checknonce())
{
// TODO: Also do as many of these checks as possible in javascript onsubmit to avoid losing file selections (and wasting time and bandwidth uploading files only to get errors)
// Checks
if($id!='new') // Make sure $id belongs to us (or is 'new')
{
$res=mysqli_query($db, 'select user, removed from things where id='.(int)$id);
$res=mysqli_fetch_row($res);
if($res[0]!=$_SESSION['id']){$error=_('Ownership error');}
if($res[1]){$error=_('No such thing');}
}
if($_POST['name']==''){$error=_('A thing needs a name');}
$filecount=0;
foreach($_FILES['files']['error'] as $i=>$file)
{
if($_FILES['files']['error'][$i]!=0){continue;}
if(db_getmimetype($_FILES['files']['name'][$i])===false)
{
$list=Array();
$res=mysqli_query($db, 'select extension from filetypes order by extension');
while($row=mysqli_fetch_row($res)){$list[]=$row[0];}
$error=$_FILES['files']['name'][$i].': '._('File type not allowed. Allowed file types: ').implode(', ', $list);
continue;
}
++$filecount;
}
if($filecount==0 && count($_POST['oldfiles'])<1){$error=_('A thing is not a thing without any files');}
if($error=='') // No errors, commit to database
{
if($id!='new')
{
mysqli_query($db, 'update things set latest=false where thingid='.(int)$id);
}
$name=mysqli_real_escape_string($db, $_POST['name']);
$description=mysqli_real_escape_string($db, $_POST['description']);
$license=mysqli_real_escape_string($db, $_POST['license']);
$timestamp=date('Y-m-d H:i:s');
mysqli_query($db, 'insert into things(thingid, user, name, description, posted, latest, removed, license) values('.(int)$id.', '.(int)$_SESSION['id'].', "'.$name.'", "'.$description.'", "'.$timestamp.'", true, false, "'.$license.'")');
$thingid=(int)mysqli_insert_id($db);
if($id=='new')
{
mysqli_query($db, 'update things set thingid=LAST_INSERT_ID() where id=LAST_INSERT_ID()');
$id=$thingid;
}
// Handle old files
foreach($_POST['oldfiles'] as $i=>$file)
{
$name=mysqli_real_escape_string($db, $_POST['oldfilenames'][$i]);
$hash=mysqli_real_escape_string($db, $_POST['oldfiles'][$i]);
$filepath=getfilepath($_POST['oldfiles'][$i], true);
if(substr_count($hash, '.')){die('Misformed hash detected');}
if(substr_count($hash, '/')){die('Misformed hash detected');}
if(!file_exists($filepath)){die('Misformed hash detected');}
insertfile($thingid, $name, $hash, $_POST['previewfile']=='old'.$i);
}
// Save the files
foreach($_FILES['files']['name'] as $i=>$name)
{
if($_FILES['files']['error'][$i]!=0)
{
if($_FILES['files']['error'][$i]!=UPLOAD_ERR_NO_FILE){print('Failed to upload '.$_FILES['files']['name'][$i].', error code '.$_FILES['files']['error'][$i]." \n");}
continue;
}
$hash=HASH.':'.hash_file(HASH, $_FILES['files']['tmp_name'][$i]);
$filepath=getfilepath($hash, true);
mkdir(dirname($filepath), 0755, true); // Make sure the directories exist
if(!move_uploaded_file($_FILES['files']['tmp_name'][$i], $filepath)){print('Failed to upload '.$_FILES['files']['name'][$i].", move_uploaded_file failed \n"); continue;}
$name=mysqli_real_escape_string($db, $_FILES['files']['name'][$i]);
insertfile($thingid, $name, $hash, $_POST['previewfile']==$i);
}
header('Location: '.BASEURL.'/thing/'.$id.'@'.DOMAIN);
system('php genpreviews.php > /dev/null &'); // Launch preview generation in the background
exit();
}
}
include_once('head.php');
$name='';
$description='';
$files='';
$license='';
if($id!='new') // Load from DB when editing a preexisting thing
{
$res=mysqli_query($db, 'select id, name, description, license from things where thingid='.(int)$id.' and latest');
$res=mysqli_fetch_assoc($res);
$name=$res['name'];
$description=$res['description'];
$thingid=$res['id'];
$license=$res['license'];
// Gather files
$res=mysqli_query($db, 'select hash, name, preview from files where thing='.(int)$thingid);
$i=0;
while($row=mysqli_fetch_assoc($res))
{
$preview=($row['preview']?' checked':'');
$files.='
';
$files.='';
$files.='
'."\n";
++$i;
}
}
// If saving was attempted, retain changes
if(isset($_POST['name'])){$name=$_POST['name'];}
if(isset($_POST['description'])){$description=$_POST['description'];}
if(isset($_POST['license'])){$license=$_POST['license'];}
// Gather license options
$licenses='';
$res=mysqli_query($db, 'select name, simple, defaultlicense from licenses where !removed');
while($row=mysqli_fetch_assoc($res))
{
$lname=htmlentities($row['name']);
$simple=htmlentities($row['simple']);
if($license=='' && $row['defaultlicense']){$license=$lname;}
$selected=(($lname==$license)?' selected':'');
$licenses.='';
}
$selected=(($license=='other')?' selected':'');
$licenses.='';
$maxsize=-1;
for(Array('upload_max_filesize','post_max_size') as $name)
{
$size=ini_get($name);
// Translate to bytes for the MAX_FILE_SIZE input
switch(strtoupper(substr($size,-1)))
{
case 'Y': $size=(int)$size*1024;
case 'Z': $size=(int)$size*1024;
case 'E': $size=(int)$size*1024;
case 'P': $size=(int)$size*1024;
case 'T': $size=(int)$size*1024;
case 'G': $size=(int)$size*1024;
case 'M': $size=(int)$size*1024;
case 'K': $size=(int)$size*1024;
}
if($maxsize<0){$maxsize=$size;}
$maxsize=min($maxsize, $size);
}
if($error!=''){$error='