markguinn/silverstripe-shop-downloadable

Downloadable products for Silverstripe Shop module

1.1.1 2016-05-18 17:14 UTC

README

For Silverstripe Shop

Allows Products and/or ProductVariations to have files attached that the customer can download once the product has been purchased and remain available on the user's account pages.

Requirements

  • Silverstripe 3.1+ (may work with 3.0, but hasn't been tested)
  • Shop Module 1.0 or master branch
  • ZipArchive must be enabled in php for full functionality

Features

  • Can be applied to a Product or ProductVariation or both
    • If a variation is purchased, all files from both variation and main product become available for download (can be overridden from the cms).
  • Any number and type of file can be associated with a Product
  • Downloads are available immediately on receipt screen if paying by credit card
  • Downloads are available on the order history
  • All historical downloads are available from a central screen in the account area
  • Can download files individually or any combination in a zip archive
    • We should keep the zip files around for a few days so we don't recreate them all the time
    • Cron job to delete old files
  • Download links should not be guessable
  • Download links should be different for each customer/order for the same file
  • Downloads should be logged
  • Compatible with markguinn/silverstripe-cloudassets module for storing downloads on CDN

Installation

  1. composer require markguinn/silverstripe-shop-downloadable dev-master
  2. Add Downloadable extension to Product and/or ProductVariation or only to certain subclasses.
  3. Run dev/build?flush
  4. Go add some files in the CMS (each product will have a "Files" tab)

YML example:

Product:
  extensions:
    - Downloadable
ProductVariation:
  extensions:
    - Downloadable

File Download Process

  1. Once order is paid, files show up on the order screen. Links are generated by the Downloadable extension on the product.
  2. The link a user clicks is something like "http://example.com/downloads/FILE-HASH", which hits the DownloadController.
    • Hash is repeatable given an order ID and file ID (so it will work in emails too)
    • This step could also include a form submission with multiple files.
  3. DownloadController logs the download. If it's only for a single file and the file is small (default 100M, but configurable via yml) it will just output the mime type and use readfile to immediately initiate the download. If there is more than one file or if it's a large file, a temporary "Please wait" page will be displayed while the file is copied and/or zipped if more than one.
    • The temporary file will be cached in such a way that it can be re-used until it is deleted by a cron job.
    • The text of the temporary page can be taken from any page in the CMS via yml config
    • If one wants to disable the "pass through" behaviour entirely it can be easily done by setting the small_file_size to 0.
    • Supports X-Sendfile on servers that have it turned on. In such a case one could probably just set the small_file_size very very high since the file will never be in memory.
  4. If the temporary page is displayed, it will immediately redirect to another URL that will start the copy/zip task
  5. When the copy/zip task is complete it will redirect to the actual url of the temporary file

Configuration (YML options on Downloadable class)

  • tab_name: name of the tab for files in the CMS (default: Downloads)
  • source_folder: where are these files uploaded by default in the cms (default: product-files)
  • zip_folder: location of temporary zip files and large file copies (default: temp-order-files)
  • download_link_base: URL segment for links - e.g. http://example.com/downloads/filekey (default: downloads)
  • small_file_size: anything below this will be passed on directly via readfile or x-sendfile with no temp file created (default: 100M)
  • use_xsendfile: use the X-Sendfile header instead of readfile, must have mod_xsendfile (or equivalent) installed (default: false)
  • crunching_page: url segment/path of a page to display instead of the default while copying/zipping files
  • crunching_zombie_window: how many minutes before crunching is restarted on a zip file (default: 5)
  • delete_temp_files_after: how many hours before the temp files are ok to delete (default: 48)

TODO

  • Tests

Would be nice but I have no intention of doing the work myself anytime soon:

  • Translatable
  • Time limit on downloads

Developer(s)

Contributions welcome by pull request and/or bug report. Please follow Silverstripe code standards.

License (MIT)

Copyright (c) 2013 Mark Guinn

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.