Switch branches/tags
Commits on Apr 28, 2016
  1. Fix for BounceReferrals including process path

    jonjensen committed Apr 28, 2016
    Originally from an internal project:
    Author: David Christensen <>
    Date:   Wed Jan 14 01:16:40 2009 +0000
        Fix for disappearing form in the BounceReferrals codepath to correct for GA issue
  2. Avoid warning when item_price is called with a SKU rather than hashref

    jonjensen committed Apr 28, 2016
    Originally from a private repository commit:
    Author: Jeff Boes <>
    Date:   Wed Mar 24 09:20:20 2010 -0400
        This adds a minor sanity check to the code to avoid a warning when
        $item is not a reference (i.e., has been passed in as a SKU).
  3. Add support for [all-anchor] token in [more-list] template

    jonjensen committed Apr 28, 2016
    Example usage:
            More rows:
            [all-anchor]View All[/all-anchor]
  4. Respect custom BACKUP_DIRECTORY in admin table downloads

    jonjensen committed Apr 1, 2016
    This matches behavior expected by [export-database].
  5. Allow admin user to export tables upon request despite NoExportExternal

    jonjensen committed Apr 1, 2016
    NoExportExternal was intended to ensure automatic products/ exports
    don't happen, but we shouldn't stop manual exports to the download
  6. Add date-change filter "common" boolean option to output date+time wi…

    jonjensen committed Apr 1, 2016
    …thout T separator
    E.g. 2016-03-31 12:34:56 instead of 2016-03-31T12:34:56
Commits on Mar 8, 2016
  1. Fix error creating indexes in Postgres when QUOTE_IDENTIFIERS is set

    jonjensen committed Mar 8, 2016
    The problem was that Vend::Table::DBI was assembling an index name
    based on the quoted table name plus '_' plus quoted column name,
    resulting in a syntactically invalid name like "variants"_"sku",
    leading to errors like this:
    DBI: Post creation query 'CREATE  INDEX "variants"_"sku" ON "variants" ("sku")' failed: ERROR:  syntax error at or near "_"
    LINE 1: CREATE  INDEX "variants"_"sku" ON "variants" ("sku")
    Instead assemble the name unquoted, and quote the final result.
Commits on Aug 31, 2015
  1. Remove Signio module for long-defunct Payflow Pro API

    jonjensen committed Jun 10, 2015
    Use Vend::Payment::PayflowPro now instead.
Commits on Jan 13, 2015
  1. Support new DebugTemplate tokens REQUEST_METHOD, REQUEST_URI, SESSION…

    jonjensen committed Jan 13, 2015
    This makes possible a nicely detailed DebugTemplate like this:
    DebugTemplate  %F %T {CATALOG} {REMOTE_ADDR} {REQUEST_METHOD} {REQUEST_URI} {PAGE|-} {} {SESSION.username|-} | {MESSAGE}
    to track the session ID, the logged in user name, and more about the
Commits on Sep 17, 2014
  1. UserDB: log timestamps to second granularity

    jonjensen committed Sep 17, 2014
    I am not sure why this was just minute granularity before, but that is
    not sufficient for correlation with other event logs.
Commits on Apr 4, 2014
  1. Correct [log type=error|debug] final newline behavior

    jonjensen committed Apr 4, 2014
    It shouldn't quote the final newline with > since ::logError
    doesn't. (And because it makes a mess of the log.)
Commits on Oct 31, 2013
  1. Bump version to 5.8.1

    jonjensen committed Oct 31, 2013
  2. Update manifest

    jonjensen committed Oct 31, 2013
  3. Add new full-page caching features

    jonjensen committed Oct 31, 2013
    These features make it much easier to emit pages that are fully cacheable
    and can be served to any user, along with the HTTP Cache-Control response
    header to inform intermediate proxies and browser caches about the
    cacheability and cache lifetime.
    To start using the new features:
    Add to catalog.cfg:
    SuppressCachedCookies yes
    Add to pages or templates you'd like to cache (for 2 hours, in this
    example), maybe starting just with pages/index.html:
    [if-not-volatile][tag pragma cache_control]max-age=7200[/tag][/if-not-volatile]
    That's all you really need for a basic setup.
    If you'd like to have a cookie contain the current cart or login
    state, you can write a catalog Sub or a GlobalSub (named, say,
    cookie_state_update) and have it run after every relevant event. Add
    to catalog.cfg:
    OutputCookieHook cookie_state_update
    A detailed write-up of all these features is here:
    Mark Johnson's talk at the Ecommerce Innovation 2013 conference is
    reported here in slides and video:
    Documentation in the xmldocs system is still needed.
    Modified squashed commit of the following:
    commit ec7147fdc8126e59df482911c7d242221e8b7720
    Author: David Christensen <>
    Date:   Tue May 7 14:44:12 2013 -0500
        add if_not_volatile usertag to conditionally return data if the current request is not Volatile
    commit b02a76d058362f805585c811203572ddc3b75f07
    Author: David Christensen <>
    Date:   Fri Apr 26 16:12:22 2013 -0500
        Suppress cookies for 400-level errors
    commit a2e646528c5b6a1945229ed62bb77d67af24b10b
    Author: David Christensen <>
    Date:   Wed Jun 8 14:48:27 2011 -0500
        clear the cookie jar when suppressing cookies
    commit c54f02b2c4aa619821a9009e3922f7147d60d76f
    Author: David Christensen <>
    Date:   Fri Apr 26 16:09:59 2013 -0500
        Mark specific routines as always Volatile
    commit c0161345066a2f042f808037cf9391a1dbbfff89
    Author: David Christensen <>
    Date:   Thu Jun 2 00:00:02 2011 -0500
        suppress session write when cookies are suppressed
    commit 487511ce0627cd96e3469148603f82ce2a09d970
    Author: David Christensen <>
    Date:   Fri Apr 26 16:04:53 2013 -0500
        add an OutputCookieHook sub to be run when cookies are being created
    commit f0d10bd7b7f4d477c8d71c56277c13b65ced2e35
    Author: David Christensen <>
    Date:   Mon Apr 4 15:30:51 2011 -0500
        Do not set cookies on pages marked as cacheable
        This applies to all cookies currently, with particular attention placed on the MV_SESSION_ID.  This
        change is intended to alleviate the "first page hit" cache issue which leads to IC assigning a session
        id even for pages which would be fully cacheable and then never actually generating the cacheable
        content in question until a subsequent hit from a UA with the provided MV_SESSION_ID.
        This is of particular concern when considering the case of a DDoS in which a huge number of connections
        are made from unique instances.  Since the intent of the nginx cache is to prevent such traffic from
        ever reaching the backend, the existing behavior would result in a counter-intuitive effect of all bot
        traffic being passed directly to the "protected" backend when there was no document already in the nginx
        cache, with the result that each backend-handled request would be itself uncacheable, having a Set-Cookie
        header returned with the response.
        Currently this fix will affect all cookies being generated from interchange on a page which is marked
        cacheable (specifically one which has a Pragma cache_control value set to something other than no-cache).
        We consider this acceptable as we are also moving the setting of the existing cookies to client-side code
        where possible; if this ends up being untenable, we will see about changing this specific code to just
        affect the MV_SESSION_ID cookie.
Commits on Oct 30, 2013
Commits on Jul 17, 2013
Commits on Jul 15, 2013
Commits on Jul 12, 2013
  1. Fix broken ContentEditor references to missing lexical $table

    jonjensen committed Jul 12, 2013
    Shockingly, this has been broken since this commit:
    commit 13dcf43
    Author: Mike Heins <>
    Date:   Fri Sep 13 20:46:21 2002 +0000
    But Perl didn't notice it until version 5.18.0, where it throws many
    errors like this at Interchange startup time:
    Calling UI...UserTag 'content_modify' subroutine failed compilation:
            Global symbol "$table" requires explicit package name at [...]
Commits on Jan 24, 2013
  1. Add simple tag to generate user-friendly passwords

    jonjensen committed Jan 24, 2013
    Takes no options at all.
    Could profitably have options to control length, characters used,
    etc., but this has been useful to some of us for years and is simple
    and has no external dependencies, so might as well get it in here.
Commits on Jan 25, 2012
  1. Increase size of socket read for much better performance

    jonjensen committed Jan 25, 2012
    ddavenport found a serious performance regression in Vend::Server, such
    that each socket read was only for 1 byte, making large uploads
    painfully slow:
    I found the regression was introduced in this commit:
    commit 2a69743
    Author: Kevin Walsh <>
    Date:   Mon Feb 4 21:42:18 2008 +0000
            * Changes in the _read() subroutine:
            -- select() returns -1 upon error, whereas sysread() returns undef,
               so we need to allow for both.
            -- Catch EAGAIN as well as EINTR as soft errors to retry on.
            -- Read the entire available amount of data in one hit instead of
               forcing the data to be read in 512-byte chunks.
    Kevin clearly intended to read as much data as was waiting, but select()
    returns the number of waiting filehandles, not # of waiting bytes.
    Rather than reverting to the original 512 bytes per read, or
    ddavenport's suggested 1024, I used 1 MiB which is still arbitrary but
    large enough to get most normal http requests in few passes, and handles
    large uploads efficiently.
    Thanks, ddavenport!
    Original patch:
    commit 2a6308d
    Author: ddavenport <>
    Date:   Fri Jul 15 20:50:54 2011 -0700
        Fixed Vend::Server so it'll read more than a single byte at a time
    (which was causing large file uploads to fail).
    diff --git a/lib/Vend/ b/lib/Vend/
    index 5baf109..4a82ce8 100644
    --- a/lib/Vend/
    +++ b/lib/Vend/
    @@ -795,7 +795,7 @@ sub _read {
         do {
        if (($r = select($rin, undef, undef, $Global::SocketReadTimeout || 1)) > 0) {
    -       $r = sysread($fh, $$in, $r, length($$in));
    +       $r = sysread($fh, $$in, 1024, length($$in));
         } while ((!defined($r) || $r == -1) && ($!{eintr} || $!{eagain}));
  2. Extend PREFIX-include to work in hash-based loops

    jonjensen committed Jan 25, 2012
    Submitted by Jeff Boes <> from a private commit as of
    2011-03-15, a copy of the same part of iterate_array_list, but original
    author/tester unknown.
Commits on Dec 27, 2011
Commits on Oct 27, 2011
  1. Fix rare error with DowncaseVarname handling of GET/POST parameter names

    jonjensen committed Oct 27, 2011
    Fixed by Josh Braegger at Thanks!
Commits on Oct 14, 2011
  1. Update credit card type detection

    jonjensen committed Oct 13, 2011
    Most important are the changes to Discover and Diners Club updates, but
    some other minor ones matter too.
    Discover's changes are documented here:
    Some code borrowed from Business::CreditCard again.
Commits on Oct 4, 2011
  1. Add new database configuration attribute PREQUERY.

    jonjensen committed Oct 4, 2011
    This allows an arbitrary query to be defined, which is run every time
    the database connection is opened. Useful for setting database timezone,
    statement timeout, query optimizer hints, etc.
    This commit took its current form on 2007-07-23, but never got committed
    upstream till now.
Commits on May 3, 2011
  1. Remove outdated CVS tags

    jonjensen committed May 3, 2011
Commits on Apr 2, 2011
  1. Enhance TrustProxy to handle multiple chained proxies

    jonjensen committed Apr 1, 2011
    This can happen if, for example, you have a first proxy at
    which proxies to which then hits your web server that passes
    control to Interchange.
    If you visit from, Interchange will see this HTTP header:
    and the request will have the source IP address
    But if you set this in interchange.cfg:
    TrustProxy,    # order irrelevant
    then Interchange will see past the two trusted proxies and set its
    standard variable $CGI::remote_addr to, so that the customer's
    IP address gets used.
  2. Add new pragma cache_control to set HTTP Cache-Control response header

    jonjensen committed Mar 28, 2011
    Can be used in a page like this:
    [tag pragma cache_control]max-age=600[/tag]
    That will send this response header:
    Cache-Control: max-age=600
    Which will tell upstream proxies and browsers to cache the page for 10 minutes.