[interchange] captcha refresh

Mark Johnson interchange-cvs at icdevgroup.org
Mon Dec 10 19:15:44 UTC 2012


commit 5a1ba34afdfb5623c83aacd1e4ed116421a4bd54
Author: Mark Johnson <mark at endpoint.com>
Date:   Mon Dec 10 14:12:31 2012 -0500

    captcha refresh
    
    Optional global config to pull in that creates the
    [captcha-refresh] tag to ask for a new captcha image
    if it can't be read.

 code/SystemTag/captcha.coretag |    3 +
 eg/captcha_refresh.cfg         |  171 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 174 insertions(+), 0 deletions(-)
---
diff --git a/code/SystemTag/captcha.coretag b/code/SystemTag/captcha.coretag
index 8d7f459..47807fb 100644
--- a/code/SystemTag/captcha.coretag
+++ b/code/SystemTag/captcha.coretag
@@ -96,6 +96,9 @@ sub {
 		}
 	}
 	else {
+		# Used for [captcha-refresh] if requested
+		$::Instance->{last_captcha_build_opt} = { %$opt };
+
 	    my $save_u = umask($::Variable->{CAPTCHA_UMASK} || 2);
 
 		if($opt->{reset}) {
diff --git a/eg/captcha_refresh.cfg b/eg/captcha_refresh.cfg
new file mode 100644
index 0000000..f3cb318
--- /dev/null
+++ b/eg/captcha_refresh.cfg
@@ -0,0 +1,171 @@
+# captcha refresh: Provide a refresh feature to use in conjunction with the
+# stock [captcha] tag by Mark Johnson <mark(at)endpoint(dot)com>
+#
+# To use:
+#
+# 1. Put this in, or include from, interchange.cfg and restart.
+#
+# 2. Place call to [captcha-refresh] where you would like to see the
+# refresh link appear. See documentation within usertag defintion below.
+#
+# 3. The captcha-refresh process couples tag and actionmap definitions.
+# Ensure there is no conflict with the actionmap name and any existing
+# custom maps for your implementation.
+
+UserTag  captcha-refresh  addAttr
+UserTag  captcha-refresh  Routine <<EOR
+use 5.10.0;
+sub {
+    my $opt = shift;
+    my %cache = %{
+        delete ($opt->{use_last}) && $::Instance->{last_captcha_build_opt} || {}
+    };
+
+    my $anc = delete ($opt->{anchor}) || 'refresh image';
+    my $img_id = delete $opt->{img_id};
+    my $js_func_name = delete ($opt->{js_func_name}) || 'captcha_refresh';
+
+    my @uri = (delete ($opt->{am}) || 'captcha-refresh');
+
+    my %unq_keys;
+    @unq_keys{ keys %cache, keys %$opt } = ();
+    push (@uri,
+        join (
+            '=',
+            ($_, $::Tag->filter(urlencode => ($opt->{$_} // $cache{$_} // '')))
+        )
+    )
+        for keys %unq_keys;
+
+    my $url = $::Tag->area({ href => join ('/', @uri) });
+
+    my $script = qq{
+        <a href="#captcha" onclick="$js_func_name()">$anc</a>
+        <script>
+        function $js_func_name() {
+            var ajax = new XMLHttpRequest();
+
+            ajax.onreadystatechange = function() {
+                if (ajax.readyState == 4 && ajax.status == 200) {
+                    document.getElementById('$img_id').src = ajax.responseText;
+                }
+            }
+
+            ajax.open('GET','$url',true);
+            ajax.send();
+            return;
+        }
+        </script>
+    };
+
+    return $script;
+}
+EOR
+
+CodeDef  captcha-refresh  ActionMap
+CodeDef  captcha-refresh  Routine  <<EOR
+sub {
+    my (undef, %opt) = split (m{[/=]+}, shift);
+    $_ = $::Tag->filter(urldecode => $_)
+        for values %opt;
+
+    # Always name_only since we're updating the img's src param
+    $opt{name_only} = 1;
+
+    my $doc = Vend::Document->new;
+    $doc->hot(1);
+    $doc->write($::Tag->captcha(\%opt));
+    return 0;
+}
+EOR
+
+UserTag  captcha-refresh  Documentation <<EOD
+=head1 NAME
+
+Captcha refresh
+
+=head1 DESCRIPTION
+
+Given a call to [captcha] to generate a check image, place a subsequent call
+to [captcha-refresh] where you would like to insert a hyperlink to refresh the
+image. The call will bundle the necessary parameters to duplicate the
+appropriate call to [captcha] into an AJAX GET back to the complementary
+captcha-refresh actionmap. The actionmap will build the new image and return
+the new URL to the image, to which the original <img> tag's src field will be
+set.
+
+As long as the [captcha-refresh] call is processed after the most recent call
+to [captcha] itself, the calling parameters for the latter call can be easily
+tied to the refresh request and not need to be duplicated. The calling order
+can always be enforced via the use of [output] or, if simpler, using scratch
+to store the [captcha] results and display later in the page.
+
+=over 4
+
+=item B<img_id> (required)
+
+The refresh code needs to be able to reference the original image so that the
+newly formed captcha image can overwrite the previous, discarded one. Thus,
+your captcha image must include an "id" attribute in the <img> tag, and that
+value must be included in this param.
+
+=item B<use_last>
+
+When true, the code will pull in the attribute list of the last non-check call
+to [captcha]. In order to refresh the image under the same terms as the
+original, the code needs access to the calling params used. These can either
+be duplicated in the call to [captcha-refresh] or referenced via B<use_last>
+
+=item B<anchor>
+
+Value to use for the link itself. Defaults to 'refresh image'. To use an
+image, supply the entire <img> tag.
+
+=item B<am>
+
+Alternate actionmap name to use to refresh the captcha image. Default is
+'captcha-refresh' and is included in the .cfg build file for this tag.
+
+=item B<js_func_name>
+
+Name of javascript function built from this tag to handle the refresh request
+and image update. Default is 'captcha_refresh'. Should only need to change if
+there is a conflict with an existing JS function.
+
+=back
+
+You can also provide any of the options defined for [captcha] itself, which
+will be necessary without use of the B<use_last> option. If B<use_last> and
+explicit [captcha] options are combined, options set in [captcha-refresh] will
+override those derived from the B<use_last> call.
+
+=head1 EXAMPLE
+
+ <form action="[area @@MV_PAGE@@]" method="post">
+ ...
+ <input name="mv_captcha_guess" size="6" autocomplete="off" />
+ <img
+    id="captcha_image"
+    style="vertical-align: middle"
+    src="[captcha
+            function=image
+            length=6
+            image_location=captcha
+            image_path=/images/captcha
+            name_only=1
+    ]"
+ />
+  
+ [captcha-refresh
+        img_id=captcha_image
+        use_last=1
+    ]
+ ...
+ <input type="submit" value="Submit" />
+
+=head1 AUTHOR
+
+Mark Johnson <mark(at)endpoint(dot)com>
+
+=cut
+EOD



More information about the interchange-cvs mailing list