Documentation for the Textpattern plugin smd_remote_file by Stef Dawson follows this short message from our sponsor ;-)
If you like my code and it soothes an otherwise unscratchable itch, feel free to show your appreciation with something from my UK Amazon wish list (or US) or donate to the Stef Dawson community coding pot, either via paypal.me/stefdawson or by following the Donate button below to PayPal. Thanks!
Offers remote and secure file management through Textpattern’s standard Files interface. This is very handy in two main situations:
- If you don’t have the bandwidth available to host media content. Third party sites such as fileden.com offer the ability to upload fairly sizeable files and then freely hotlink to them (within quite generous bandwidth limits) so they can be shared and thus used within your Txp site
- If you want to lock down some files so they are not freely downloadable. While .htaccess can clamp down an entire directory or requires special rules for locking certain files, this plugin offers a more natural way to manage them by permitting access to only those people who have the authority to do so
- Manage links to cloud-based files directly from the Txp Files tab, as if they were native
- Multiple sources for the same remote file are supported, for load balancing / bandwidth saving
- Manage files in non-web-accessible (i.e. secure) locations on your host server as if they were native files
- Files can optionally be served to logged-in users using Hidden / Pending status
- Integrates with smd_user_manager’s privs system
- No modifications to Txp core / database required
Installation / uninstallation
Requires Textpattern 4.5.2+
Download the plugin from either textpattern.org, or the software page, paste the code into the Txp Admin->Plugins panel, install and enable the plugin. Visit the forum thread for more info or to report on the success or otherwise of the plugin.
To remove the plugin, simply delete it from the Admin->Plugins panel.
For the remote file capability, choose any third party file hoster that offers free downloads of your stuff. Create an account, upload files to it, and make sure you know how to get Direct Link URLs from their interface (it’s usually fairly obvious). You’ll need these to paste into Textpattern.
For secure files you need to nominate a directory either a) outside of your web host’s document root, or b) in a directory with an .htaccess file that forbids web access to any file. Configure the path to this location from the plugin preferences and then hop over to the Files panel to upload your files.
On the Extensions->Remote file panel are the following options to govern how the plugin behaves:
- Allow downloads from
- Determines which interface elements you see. Choose from:
- The Internet to allow remote URLs
- Secure location to allow files to be stored in your nominated non-web-acessible folder
- Secure file path
- Absolute file path to the place you want to store secure files. Ignore this option if you have elected not to use secure files.
- Permitted download statuses
- List of status numbers (not names) for which you are going to permit downloads. Choose from:
- 2 for Hidden files
- 3 for Pending files
- Limit downloads to this priv level
- The privilege level of users who can download hidden/pending files (providing you have enbled this feature using the Permitted download statuses pref). If you are using smd_user_manager this setting is ignored.
The Files tab: remote files
The plugin adds one input form field to the Files tab labelled URL. From your third party site(s) of choice, simply copy a web-friendly (i.e. url-encoded) hotlink and paste it into the URL box. You can usually tell if the link is url-encoded because it’ll probably have
%20 in place of any spaces in the filename. The directory part is, however, not usually encoded: characters such as forward slashes and colons remain.
A typical file might look like this:
The link must be an absolute URL, beginning
http://. Once you have pasted it in, hit Upload next to the box and a new special
.link file will be created in Txp. It takes on the filename exactly as it appears in your URL (with
.link added). So in the example above, a new file called
Here is some music.mp3.link will be made in your standard Textpattern files directory.
The new “file” will appear in the list just like any real file in Txp. You can edit it to add a title, description, category, set its status: everything you can do with a conventional file. Just don’t rename it!
Third party sites don’t give you something for nothing; they normally have a bandwidth cap, just like your web hoster might enforce. If you want to distribute your music or latest video, a few thousand hits per month will eat all your available bandwidth.
So spread the load around the Internet. Get accounts at various third party sites and upload exactly the same file (make sure the filenames are identical — including caSe SensITivItY). Then just paste the URLs into the upload box: smd_remote_file will only maintain one physical file within Txp but will hold details of your other copies for you. Alternatively, click to edit the
.link file from the Files panel and paste the other URLs inside the Remote URLs text area; one URL per line. Using either the standard file_download_link tag or the new smd_file_download_link tag will randomly pick one of your download locations associated with each file every time the page loads, spreading your bandwidth usage.
The Files tab: secure files
The plugin adds two checkboxes alongside the create / upload boxes, both labelled
Secure. When you create a Txp file from an already uploaded physical file, or upload a new file, just check the checkbox to store the file in your nominated secure location. A corresponding
.safe file will be created in the regular
files directory containing meta data about the file. At the moment this meta data just houses some placeholder text and if you click a .safe file to edit it you will see a box labelled Secure options into which you can write whatever you like. Just be aware that this area is reserved for future use.
When editing either a
.safe or regular file you may replace it with another using the upload box at the bottom of the File edit panel. It is automatically ticked if the file you are editing is secure, but you may uncheck it to convert the new uploaded file to a regular file, and vice versa. Note that even if the uploaded file has a different filename to the one already uploaded, Txp will maintain the original filename just as it does for regular files.
The Files tab: hidden/pending files
The plugin allows a third method of delivering files utilising the status bits. By default, Txp forbids downloads of any files that are not Live (status=4). But if you nominate a status of 2 (Hidden) or 3 (Pending) in the plugin preference Permitted download statuses you can then upload regular files to Txp’s interface and set their status to one of the other options.
<txp:file_download_link> tag will skip non-live files, but you can add the
status attribute to display the hidden content. Clicking on such a link will still, however fail to download the file unless you are logged in and one of the following conditions is met:
- You are the author (uploader) of the file
- Your privilege level matches that given by the Limit downloads to this priv level preference
- smd_user_manager is installed and the
file.downloadpriv area includes the privilege level of your account
- smd_user_manager is installed and the
file.download.status_numberpriv area includes the privilege level of your account
This is an ideal scenario where wrapping the
<txp:file_download_link> with some credentials checking plugin/tag (e.g. rvm_privileged, smd_um_has_privs, cbe_frontauth_protect, etc) can help to deliver content only to special members.
An exact drop-in replacement for the standard file_download_link tag tag, with a few extra attributes:
- The ID of the file you want to link to. If left blank, it can be supplied from whatever is between the opening and closing tag
- The filename of the file you want to link to. If left blank, it can be supplied from whatever is between the opening and closing tag. If both filename and ID are specified, ID takes precedence
- (for remote URLs only) governs how to choose which remote URL to serve. Set it to 0 to randomly pick a URL from those uploaded for this file (the standard file_download_link tag will also do this). You can also specify a higher number to pick the URL from that particular slot. So
choose="1"will always select the 1st file you uploaded and deliver that;
choose="2"the second; and so on. If you specify a number bigger than the number of URLs stored against a file, it picks the first one you uploaded.
- Whether to display the
.safesuffix in the link. Choose from:
- 0 to hide the suffix
- 1 to show the suffix (in other words, make the tag behave like the built-in
- Default: 0
- (for remote URLs only) hide the filename portion of the linkand replace it with a random string of characters. Specify the length of the string, e.g.
obfuscate="8"would render a link that resembles
http://site.com/file_download/42/3e9845ac. This is handy to keep the filename partly secret, but it’s not foolproof. As soon as someone starts downloading the file the full remote URL is known.
An exact drop-in replacement for the standard file_download_name tag, but with one attribute:
- Whether to display the
.safeon the end of file name. Choose from:
- 0 to hide the suffix
- 1 to display it (thus behaving like the built-in
When linking to external content (especially media files) it is often useful to make a mini image to go with it, such as a still from a movie or some artwork for an mp3 track. You can of course embed a
<txp:image> tag in your download form, but that will give a static image for each file. This tag can be used to display images that vary with the filename of the remote, secure or regular file.
To use it, just upload an image (by default a jpg) via Txp’s Images panel and give it the exact same filename as the remote file it represents, plus its normal image file extension. i.e. if your remote file was
Man and boy.mpg you would upload an image and name it
Man and boy.mpg.jpg. Do this for each file and then use this tag to display them.
By default, if any image doesn’t exist, the tag outputs the image filename instead (if using the
filename) or the id (if using the
id). This behaviour can be overridden with the
- The ID of an image to display
- The filename of an image to display. If both filename and ID are specified, ID takes precedence. Note that in this and
idmodes, the tag is essentially the same as
<txp:image>. The exception is that you do not have to specify the image file
extension, as it does that for you by default if you use JPGs and you can specify thumbnails instead using the
- Saves you having to specify the file extension in the
filenameparameter. Enter it here without the dot.
- Display full size image or thumbnail. Choose from:
- 0 for the full size image
- 1 if you have created thumbnails and wish to use them
- Default: 0
- Governs what to do in the event an image is missing. Use
ifmissing=""to output nothing in the event of a missing image. Other alternatives:
?refto display either the image filename or its ID if it was used as an attribute.
?image:ID_or_name"to display the given Txp image (e.g.
some_textto display the given text, e.g.
ifmissing="No image yet"
- The HTML tag to wrap around the outside of the image. Specify it with no angle brackets, e.g.
- The CSS class name to apply to the image. If using
wraptagthe class is applied to the surrounding tag. If it is omitted the class is applied directly to the image.
How it works
For the curious, the plugin just creates a placeholder text file with the name of your file plus the special suffix
.safe to distinguish it from a standard file. The contents of the file determine which URLs to consider when downloading, or the special options that apply to this secure file (to be decided in a future version).
For remote files, shuffling the order of URLs alters the effect of the
choose attribute. Just make sure you have one URL per line that must begin with
http and must have the same base filename as the corresponding
Incidentally, the real file size is fetched every time the local file is edited because otherwise Txp overwrites it with the size of the placeholder text file. In the case of remote files, it reads the file size of the first URL. This has potential ramifications when downloading because the plugin checks that the remote file size matches the one in the Txp interface before serving the file. If one of your uploaded files is a different size it will refuse to download.
The reason for this is to try to maintain download count integrity. Instead of dishing out a standard 404 message, some servers will redirect to an image or HTML file to tell you that a file is missing. This returns a status code of ’200 OK’ to indicate that the download of the replacement content went ok, but in this case we do not want to increment the counter; the file’s still missing after all! Under rare circumstances you might find that the provider returns content exactly the same length as the file itself and the count would then be wrongly incremented. Practically, your file is going to be larger than their replacement so it won’t matter, but if it causes problems, shuffle the order of the URLs so a provider you trust not to use such tactics is first in the list.
Note that the ‘download’ link next to each file on the Files tab of the admin interface always chooses a random file from those uploaded with that name.
Example 1: standard download
<txp:file_download_link> <txp:smd_file_download_name /> [<txp:file_download_size format="auto" decimals="2" />] </txp:file_download_link>
Example 2: specific download
<txp:smd_file_download_link choose="2" show_suffix="1" />
Will always select the 2nd URL from those uploaded for each file. Shows the
.link on the end of each remote file.
Example 3: using an image to download file
<txp:smd_file_download_link> <txp:smd_file_download_image ifmissing="Sorry, no image found" wraptag="span" class="dload" /> </txp:smd_file_download_link>
Displays an image with the same name (plus .jpg) as the remote file. The image is clickable to allow the file to be downloaded but if the image is not found, the text “Sorry, no image found” will be displayed instead (the text is also clickable). Wraps the img or text in
<span> tags with a class of
Example 4: hidden downloads
Author and credits
I cannot possibly claim all the credit for this hunk of code. The plugin would not have existed if it weren’t for the amazing mind of Ruud van Melick. He suggested a very clever solution to my remote file predicament. I built on that, extended it, refined it, pluginised it and gave it to you. Many thanks to Ruud for the awesome support he offers the community, and also to Wet for his assistance with helping me understand the core.
- 12 Nov 2007 | 0.10 | Initial release
- 04 Dec 2007 | 0.20 | Added download counter and some better status messages
- 04 Dec 2007 | 0.30 | Removed .link when using
show_linkattribute ; improved error handling code ; download count only increases if file sizes match
- 05 Dec 2007 | 0.31 | File is checked for error condition prior to download in line with core changeset r2720 (thanks Mary) – can be removed when 4.0.6 is released
- 12 Dec 2007 | 0.32 | Enhanced ifmissing to include image support; changed the ?file attribute to ?ref (it’s a better name)
- 03 Feb 2008 | 0.40 | Requires TXP 4.0.6 ; removed error check from v0.31 ; added/improved replace remote file ; reduced timeout for accessing remote URL to try and prevent ugly warnings
- 02 Apr 2008 | 0.41 | Added smd_file_download_name (thanks aswihart)
- 09 Apr 2008 | 0.42 | Fixed minor edge case bug in smd_file_download_link
- 10 Jun 2008 | 0.43 | Fixed spurious characters in the single tag version of smd_file_download_link (thanks iblastoff)
obfuscateattribute ; renamed
If you’d rather dive in and out of functions, you’ll need to step into the view source page.
If, for some inexplicable reason, you need the un-current version of a plugin, it can probably be found on the plugin archive page.
If you’re feeling brave, or fancy chucking your keys in the bowl, you can test out some of my beta code. It can be found on the plugin beta page.