First steps in PHP - uploading a tiddler

On a request in another thread, I will share here some hints to get started with PHP.
I may not be he best guide in this territory, but there is still rather few TW-specific information on this.

If you are used to the fantastic foolproofness of TW, with PHP you should know what you are doing because on your server a harmless sounding command like unlink can be a planetary killer. The other danger is that you want to allow people to put files on your server, which always was a little spooky to me.

So as a start, I will share the sources with which I started and comprehensible easy files.

You will start to build an input-form and then a backend that treats the input of that form.
My starting point was w3schools: forms

The aim of what you see in the following code ist to post the tiddler you just edited. By the tag $:/tags/TiddlerInfo it can be accessed as a new tab in the tiddlerinfo. It changes the name of the Tiddler to avoidoverwriting your own tiddlers when importing. Compared to the instruction above you use a textarea to input the text of the body. The target is necessary to avoid a reload when hitting the button - it will show answer of the php.

\define UserTitle() {{$:/status/UserName}}_<<storyTiddler>>
Username:<$edit-text tiddler="$:/status/UserName" default="" tag="input"/><br>
<$reveal type="nomatch" state="$:/status/UserName" text="" default="show">
<$wikify name="UTitle"  text=<<UserTitle>>>
<form action="post.php" method="post" target="tester">
<input type="hidden" name="title" value=<<UTitle>>>
<textarea name="content" hidden><$tiddler tiddler=<<storyTiddler>>><$fields exclude='text bag title' template='$name$: $value$
'></$fields>`
`title: {{$:/status/UserName}}_<$view field="title" format="text" />

`
`<$view field="text" format="text" />
</$tiddler></textarea><br/>
<input type="submit" value="Hochladen">
</form>
</$wikify>
<iframe name="tester" style="height:30px;width:90%;border-width:0px;overflow: hidden;"></iframe>
</$reveal>

The content of the file is created in the textarea. Here it is a .tid file but you can also decide to upload a .json file of a tiddler or even a nested .json containing multiple tiddlers. If you do so you have to choose a different ending in the folowing code.
The basic command the backend uses to write the file is explained here:

As a backend I started with the following code, which has to be in the file post.php which is addressed in the form, the folder post has to be created manually because it is not automatically built for now, both in the same directory as your wiki:

<?php
$title = $_POST['title'];
$content = $_POST['content'];
$content = str_replace('&#10;', '
', $content);
$postfile = fopen('post/'.$title.'.tid', "w") or die("Unable to open file!");
fwrite($postfile, $content);
fclose($postfile);
echo "Your input was stored. It will be manually checked and imported so be patient";
echo "$title";
?>

You will soon want to add further mechanisms such as password-check for the users but this here is a good point to start from.

5 Likes

Creating a directory - if it does not exist yet

In the code above the directory has to be created manually If you insert this before the first $postfile, it will be created automatically
    if (!file_exists('post')) { mkdir('post', 0705, true); }

and you have build your first if-expression

1 Like

PHP files have to be carefully designed, because they perform actions on your server. Therefore it is usefull to use an authetification. The store.php-file defines a password-array. If you want to use a password and authentification for multiple php-actions it is usefull to extract this passage out of the file and store it in a seperated file which then will be imported at the same line where the original code was. This file passwordfile builds an array with usernames and passwords, you should give it an individual name to make this more secure.

Open a document in an editor. Insert the following text and change name and password and save it as “mypasswordfile.php” next to the store.php

<?php
$USERS = array('Name'=>'Password'); // set usernames and strong passwords
?>

Next step:
Open store.php
replace the line that starts with $USERS = array( until the semicolon)

with the line:
include 'mypasswordfile.php';

and save.
Now you will be able to use the same authetiication mechanism in other php-files.

Hi @jeremyruston,
whenever I am working with authentification, I ask myself whether it could be a good idea to add an optional hash-mechanism to store the password in the browserstorage and send it to the server in a hashed way.

Do you mean as an enhancement to the standard client-server configuration?

If somebody wanted to use a more sophisticated challenge-response authentication system then I think that would be best done as a layer above TiddlyWiki (eg putting it behind nginx).

Hi @jeremyruston ,
I rather would like TW to be able to hash the password before writing it to the browserstorage.
Parallel I only would store the hashed version of the password on the server.
Then the authentification could work by directly comparing the hashed versions.

I think those two changes wouldn’t really have much impact on security. Hashing the password in local storage hides it from casual eyes, but it’s still accessible with sufficient determination. Hashing the password on the server again just protects the passwords from somebody with access to the server file system; it’s already game over if an attacker has that level of access.

Securely exposing an authenticated server to the internet is outside the scope of the TiddlyWiki core. If that functionality did exist as part of TW, it would need extensive auditing and testing before users could trust it. That’s hard to achieve with a small project like this. In contrast, using off the shelf external middleware tools to implement authentication gives us a high level of trust from the beginning.

2 Likes

Until @JanJo did this, I have only used tw-reciever. In my previous research on tiddlywiki on php, its seemed to me we need a portable solution not unlike tiddlyhost which includes an interactive security and setup layer allowing user and wiki management. I have scoured the internet for examples of similar solutions for user file and folder management without success.

Most of such a solution is outside tiddlywiki although, of course, an instance of tiddlywiki could be a knowledgebase with instructions and php code source for building such a solution.

I believe php on apache and cpanel accounts is possibly one of the most common platforms for internet facing servers and would be an ideal platform to expand tiddlywiki use, given its not a node server it needs to be based on single file wikis. Thus we need to add;

  • Admin features for setting up tiddlywiki’s on the php platform
  • Support for checkin/out serial editing
  • Support for visitors to submit content

Eventually with the right solution tiddlywiki can grow and prosper on PHP, perhaps eventually packaged as a script into softaliciouse or other PHP script database.

1 Like