$ git clone http://thingshare.ion.nu/thingshare.git
commit 7b3d3bbd5a2c4a68c7b79f8c85f1e512e624432f
Author: Alicia <...>
Date:   Wed Mar 25 21:06:03 2020 +0100

    Implemented preview selection, to pick which file preview to use for the 'thing'.

diff --git a/db.php b/db.php
index 02f47b1..40c6193 100644
--- a/db.php
+++ b/db.php
@@ -93,7 +93,8 @@ function db_create_tables()
     id integer primary key auto_increment,
     thing integer,
     name text,
-    hash text);');
+    hash text,
+    preview boolean);');
   mysqli_query($db, 'create table options(name text, value text);');
   mysqli_query($db, 'create table peers(domain text, blacklist boolean);');
   mysqli_query($db, 'create table cooldown(domain text, end datetime);');
diff --git a/editthing.php b/editthing.php
index a23e145..53e031d 100644
--- a/editthing.php
+++ b/editthing.php
@@ -25,16 +25,16 @@ include_once('nonce.php');
 include_once('files.php');
 $id=$path[2];
 $error='';
-function insertfile($thingid, $name, $hash)
+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.'" where id='.$id);
+    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) values('.$thingid.', "'.$name.'", "'.$hash.'")');
+    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())
@@ -50,7 +50,7 @@ if(isset($_POST['name']) && isset($_POST['description']) && checknonce())
   }
   if($_POST['name']==''){$error=_('A thing needs a name');}
   $filecount=0;
-  for($i=0; $i<count($_FILES['files']['error']); ++$i)
+  foreach($_FILES['files']['error'] as $i=>$file)
   {
     if($_FILES['files']['error'][$i]!=0){continue;}
     if(db_getmimetype($_FILES['files']['name'][$i])===false)
@@ -82,7 +82,7 @@ if(isset($_POST['name']) && isset($_POST['description']) && checknonce())
       $id=$thingid;
     }
     // Handle old files
-    for($i=0; $i<count($_POST['oldfiles']); ++$i)
+    foreach($_POST['oldfiles'] as $i=>$file)
     {
       $name=mysqli_real_escape_string($db, $_POST['oldfilenames'][$i]);
       $hash=mysqli_real_escape_string($db, $_POST['oldfiles'][$i]);
@@ -90,10 +90,10 @@ if(isset($_POST['name']) && isset($_POST['description']) && checknonce())
       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);
+      insertfile($thingid, $name, $hash, $_POST['previewfile']=='old'.$i);
     }
     // Save the files
-    for($i=0; $i<count($_FILES['files']['name']); ++$i)
+    foreach($_FILES['files']['name'] as $i=>$name)
     {
       if($_FILES['files']['error'][$i]!=0)
       {
@@ -105,7 +105,7 @@ if(isset($_POST['name']) && isset($_POST['description']) && checknonce())
       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<br />\n"); continue;}
       $name=mysqli_real_escape_string($db, $_FILES['files']['name'][$i]);
-      insertfile($thingid, $name, $hash);
+      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
@@ -126,10 +126,15 @@ if($id!='new') // Load from DB when editing a preexisting thing
   $thingid=$res['id'];
   $license=$res['license'];
   // Gather files
-  $res=mysqli_query($db, 'select hash, name from files where thing='.(int)$thingid);
+  $res=mysqli_query($db, 'select hash, name, preview from files where thing='.(int)$thingid);
+  $i=0;
   while($row=mysqli_fetch_assoc($res))
   {
-    $files.='<div class="fileinput"><input type="hidden" name="oldfiles[]" value="'.$row['hash'].'" /><input type="text" name="oldfilenames[]" value="'.htmlentities($row['name']).'" /><button onclick="this.parentNode.remove(); return false;">X</button></div>'."\n";
+    $preview=($row['preview']?' checked':'');
+    $files.='<div class="fileinput"><input type="hidden" name="oldfiles['.$i.']" value="'.$row['hash'].'" /><input type="text" name="oldfilenames['.$i.']" value="'.htmlentities($row['name']).'" />';
+    $files.='<label><input type="radio" name="previewfile" value="old'.$i.'"'.$preview.' /> '._('Use as thing preview').'</label>';
+    $files.='<button onclick="this.parentNode.remove(); return false;">X</button></div>'."\n";
+    ++$i;
   }
 }
 // If saving was attempted, retain changes
@@ -169,25 +174,37 @@ if($error!=''){$error='<div class="error">'.$error.'</div>';}
 <script src="<?=BASEURL?>/mdjs/mdjs.js"></script>
 <script>
 <!--
+var filenum=0;
 function morefiles(prev)
 {
   var oldentry=prev.parentNode;
   var list=oldentry.parentNode;
+  // Radio button for preview selection
+  var label=document.createElement('label');
+  var radio=document.createElement('input');
+  radio.type='radio';
+  radio.name='previewfile';
+  radio.value=filenum;
+  label.appendChild(radio);
+  label.appendChild(document.createTextNode(' <?=_('Use as thing preview')?>'));
+  oldentry.appendChild(label);
+  prev.onchange=false; // Don't add more fields when changing file selection on an old entry
+  // Add 'remove' button
+  var button=document.createElement('button');
+  button.appendChild(document.createTextNode('X'));
+  button.onclick=function(){this.parentNode.remove(); return false;};
+  oldentry.appendChild(button);
+  // Add new file entry
+  ++filenum;
   var entry=document.createElement('div');
   entry.className='fileinput';
   var file=document.createElement('input');
   file.type='file';
-  file.name='files[]';
+  file.name='files['+filenum+']';
   file.onchange=function(){morefiles(this);};
   entry.appendChild(file);
   list.appendChild(entry);
-  prev.onchange=false; // Don't add more fields when changing file selection on an old entry
 // TODO: Rename button? Order, etc.
-  // Add 'remove' button
-  var button=document.createElement('button');
-  button.appendChild(document.createTextNode('X'));
-  button.onclick=function(){this.parentNode.remove(); return false;};
-  oldentry.appendChild(button);
 }
 // -->
 </script>
@@ -208,12 +225,12 @@ function morefiles(prev)
   <div class="paragraph">
     <?=_('Files:')?><br />
     <?=$files?>
-    <div class="fileinput"><input type="file" name="files[]" onchange="morefiles(this);" /></div>
+    <div class="fileinput"><input type="file" name="files[0]" onchange="morefiles(this);" /></div>
     <noscript>
-      <div class="fileinput"><input type="file" name="files[]" onchange="morefiles(this);" /></div>
-      <div class="fileinput"><input type="file" name="files[]" onchange="morefiles(this);" /></div>
-      <div class="fileinput"><input type="file" name="files[]" onchange="morefiles(this);" /></div>
-      <div class="fileinput"><input type="file" name="files[]" onchange="morefiles(this);" /></div>
+      <div class="fileinput"><input type="file" name="files[1]" onchange="morefiles(this);" /></div>
+      <div class="fileinput"><input type="file" name="files[2]" onchange="morefiles(this);" /></div>
+      <div class="fileinput"><input type="file" name="files[3]" onchange="morefiles(this);" /></div>
+      <div class="fileinput"><input type="file" name="files[4]" onchange="morefiles(this);" /></div>
     </noscript>
   </div>
   <button><?=_('Save')?></button>
diff --git a/rpc_search.php b/rpc_search.php
index 6ff317f..57b0a3f 100644
--- a/rpc_search.php
+++ b/rpc_search.php
@@ -82,9 +82,8 @@ while($row=mysqli_fetch_assoc($res))
                'description'=>$row['description'],
                'date'=>$row['posted']);
   $user=$row['user'];
-  // Grab preview from the first file
-// TODO: Figure out file ordering so we get the first one (chosen preview)
-  $res2=mysqli_query($db, 'select name, hash from files where thing='.(int)$row['id'].' limit 1');
+  // Grab preview from the chosen file, or the first file if none is chosen for preview
+  $res2=mysqli_query($db, 'select name, hash from files where thing='.(int)$row['id'].' order by preview desc limit 1');
   $row=mysqli_fetch_assoc($res2);
   $thing['preview']=getpreview($row['name'], $row['hash']);
   // Designer
diff --git a/rpc_user.php b/rpc_user.php
index eeafd75..db7756e 100644
--- a/rpc_user.php
+++ b/rpc_user.php
@@ -39,9 +39,8 @@ while($row=mysqli_fetch_assoc($res))
                'name'=>$row['name'],
                'description'=>$row['description'],
                'date'=>$row['posted']);
-  // Grab preview from the first file
-// TODO: Figure out sorting so we get the first one (chosen preview)
-  $res2=mysqli_query($db, 'select name, hash from files where thing='.(int)$row['id'].' limit 1');
+  // Grab preview from the chosen file, or the first file if none is chosen for preview
+  $res2=mysqli_query($db, 'select name, hash from files where thing='.(int)$row['id'].' order by preview desc limit 1');
   $row=mysqli_fetch_assoc($res2);
   $thing['preview']=getpreview($row['name'], $row['hash']);
   $obj['things'][]=$thing;