Changeset 8955


Ignore:
Timestamp:
09/07/10 13:55:28 (21 months ago)
Author:
CrawfordCurrie
Message:

Item3499: Item9601: support different domain for access control, for example, ALLOWTOPICCOMMENT instead of ALLOWTOPICCHANGE. Item4423: Item9591: Item9592: add AJAX example Item9568: Item9569: eliminate commonSlagsHandler, convert to REST handler instead of piggybacking save and using beforeSaveHandler. This gives us a lot more control over the return value and access control checking, and manages the interaction with other plugins much better.

Location:
trunk/CommentPlugin
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/CommentPlugin/data/System/CommentPlugin.txt

    r8843 r8955  
    1717   * signed or unsigned, dated or undated (as defined by a template), 
    1818   * in other topics, or other positions within the current topic. 
     19 
     20Supports the definition of custom templates for prompts and for formatting 
     21what is placed into topics. 
     22 
     23Supports custom access controls, allowing you to use it to add content to 
     24topics where the commenting user doesn't have CHANGE permissions. 
    1925 
    2026---++ Syntax 
     
    8288   * some familiarity with the [[%SYSTEMWEB%.SkinTemplates][Skin Templates]]. 
    8389 
    84 To define a comment type, you have to provide two simple template definitions in the template file; one for the prompt box, and one for the generated output. If we have a template type "mytype", these are named =PROMPT:mytype= and =OUTPUT:mytype= respectively. See =comments.tmpl= in the templates directory for examples. 
     90To define a comment type, you have to provide at least two simple template definitions in the template file; one for the prompt box, and one for the generated output. If we have a template type "mytype", these are named =PROMPT:mytype= and =OUTPUT:mytype= respectively. See =comments.tmpl= in the templates directory for examples. 
    8591 
    8692The plugin picks up these template definitions from a standard template file, =templates/comments.tmpl=. This allows different templates to be defined for different Foswiki skins. 
     
    130136The =PROMPT= template defines the contents of an HTML form that is used to capture the comment. This form invokes the comment generator when submitted. Parameters to the comment generator are defined using standard HTML input fields, such as =input=, =textarea= and =select=. The user enters values for these parameters, and these are then available when the =OUTPUT= template is expanded, in the form of <code>%<nop>URLPARAM%</code>s. 
    131137 
    132 Only the input fields of the form need be defined. The plugin automatically generates the <code>&lt;form&gt;</code> and <code>&lt;/form&gt;</code> tags, unless you specify =noform="on"=, in which case you have to provide them yourself. *Note* that you must define a "submit" button if you want the form to work! 
     138---+++ The =FORM= template 
     139The =FORM= template can optionally be provided if you want to explicitly 
     140define the form (the <code>&lt;form&gt;</code> and <code>&lt;/form&gt;</code> tHTML ags) that wraps around the =PROMPT= template. If you don't define 
     141a =FORM=template, one is automatically generated for you (unless the =noform="on"= parameter is given). 
    133142 
    134143#MoreAttrs 
     
    152161    | =%<nop>DISABLED%= | Set to 'disabled' when you cannot comment (e.g. in preview mode). | 
    153162    | =%<nop>MESSAGE%= | The text specified by =default=. This may be overridden by a helpful message when the prompt is DISABLED. | 
     163 
     164Within a =FORM= definition, the body of the prompt is expanded to replace 
     165the =%<nop>COMMENTPROMPT%= macro. 
    154166 
    155167*EXPERT* Note that when a comment is saved, the =save= script is invoked on the target topic, with a number of parameters provided by the comment form. Normally the CommentPlugin will provide these fields in the form, but experts can also provide the fields themselves in order to get finer control over what is submitted, or you might want to define your own HTML forms that do comment submission. The parameters that the CommentPlugin recognises are as follows: 
     
    193205<verbatim class="tml"> 
    194206%COMMENT{ 
    195    noform="on" 
    196207   type="example" 
    197208   templatetopic="Sandbox.CommentPluginTemplateExample" 
     
    215226     
    216227All the [[TemplateTopics#TemplateTopicsVars][usual macros]] that can be used in a topic template can also be used in an =OUTPUT= template. 
     228 
     229---+++ Custom access controls 
     230Using =configure=, the plugin can be configured to use a different access control domain than the default CHANGE. This allows you to use the plugin to add content to topics where the commenting user does not have CHANGE (or even VIEW) access. 
    217231 
    218232---++ Settings 
     
    228242 
    229243#Installation 
    230 ---++ Plugin Installation Instructions 
    231    * This plugin is pre-installed in most releases. However if you need to upgrade the plugin for any reason: 
    232    * Download the archive file from the Extensions web (see below) 
    233    * Unpack the archive in your Foswiki installation directory. 
    234       * You may need to correct file permissions 
    235    * Run ==%TOPIC%_installer== to automatically check and install other modules that this module depends on, and enable the plugin. 
    236    * Alternatively, 
    237       * Manually resolve the dependencies listed below. 
    238       %$DEPENDENCIES% 
    239    * Use =configure= to enable the plugin 
     244---++ Installation Instructions 
     245%$INSTALL_INSTRUCTIONS% 
    240246 
    241247Note that if you want to use the =action= template then you must also: 
     
    243249   1 Put the !CommentPlugin *before* the !ActionTrackerPlugin in the ={PluginsOrder}= configuration option (in =configure=) 
    244250 
    245 ---++ Plugin Info 
     251---++ Info 
    246252 
    247253Another great extension from the <a style="text-decoration:none" href="http://wikiring.com"><img src="%ATTACHURLPATH%/wikiringlogo20x20.png" alt="" /> *WikiRing* </a> - working together to improve your wiki experience! 
     
    253259|  Version: | %$VERSION% | 
    254260|  Change History: | | 
     261|  31 Aug 2010 | Foswikitask:Item3499: support COMMENT (and other) ACL preferences. Foswikitask:Item9592: added AJAX example. | 
    255262|  31 Jul 2010 | Foswikitask:Item9415 - Documentation updates | 
    256263|  27 May 2010 | Moved example topic Sandbox.CommentPluginExamples to Sandbox web. |  
     
    265272|  Support: | http://foswiki.org/Support/%TOPIC% | 
    266273 
    267 *Related Topics:* %USERSWEB%.SitePreferences, [[%SYSTEMWEB%.Plugins][Plugins]] 
    268  
    269274%META:FILEATTACHMENT{name="wikiringlogo20x20.png" attr="h" comment="" version="1"}% 
  • trunk/CommentPlugin/data/System/CommentPluginTemplate.txt

    r8843 r8955  
    11%META:TOPICINFO{author="ProjectContributor" date="1166310108" format="1.1" version="$Rev$"}% 
    22%META:TOPICPARENT{name="CommentPlugin"}% 
     3 
     4<!-- %JQREQUIRE{"chili"}% --> 
    35 
    46---+!! Templates for CommentPlugin 
     
    371373</verbatim> 
    372374 
     375---++++ ajax 
     376Post to the current topic using AJAX. This template is paired with 
     377comment_src.js (in the pub area for 
     378the plugin). The template is very similar to 'above', except that it uses an 
     379asynchronous save and the topic is not refreshed, instead the Javascript 
     380inserts a "temporary" comment in the DOM. It is intended as an example 
     381which you can copy to create your own wowie-zowie jquery comment box. And 
     382contribute it back to the community, of course! 
     383 
     384<verbatim class="tml"> 
     385%TMPL:DEF{FORM:ajax}%%TMPL:P{"LIBJS" id="COMMENTPLUGIN_AJAX" id="CommentPlugin/comment"}%<form class="commentPluginForm" action="%SCRIPTURL{rest}%/CommentPlugin/comment"> 
     386<input type="hidden" name="topic" value="%WEB%.%TOPIC%"/> 
     387<input type="hidden" name="comment_ajax" value="1"/> 
     388%COMMENTPROMPT%</form>%TMPL:END% 
     389%TMPL:DEF{PROMPT:ajax}% 
     390<div class="commentPlugin commentPluginPromptBox"> 
     391 <table border="0" cellpadding="0" cellspacing="0"> 
     392  <tr valign="middle"> 
     393    <td> 
     394      <textarea %DISABLED% rows="%rows|3%" cols="%cols|70%"\ 
     395        name="comment" class="commentPluginAjax foswikiInputField"\ 
     396        wrap="soft" title="%MESSAGE%">%MESSAGE%</textarea> 
     397    </td> 
     398    <td>&nbsp;<input %DISABLED% type="button"\ 
     399      value="%button|Add comment%" class="commentPluginAjax foswikiButton" /> 
     400      <br/><small class="commentPluginStatusResponse"></small> 
     401    </td> 
     402  </tr> 
     403 </table> 
     404</div><!--/commentPlugin-->%TMPL:END% 
     405</verbatim> 
     406<verbatim class="tml"> 
     407%TMPL:DEF{OUTPUT:ajax}%%POS:BEFORE%%TMPL:P{OUTPUT:threadmode}%%TMPL:END% 
     408</verbatim> 
     409 
    373410%ICON{"hand"}% See rendered template [[Sandbox.CommentPluginExamples#return][return]] 
    374411 
    375412 
    376  
    377  
    378413---++ Include !UserComments 
    379414 
     
    381416 
    382417<verbatim class="tml">%TMPL:INCLUDE{"UserComments"}%</verbatim> 
    383 <!-- %JQREQUIRE{"chili"}% --> 
     418 
  • trunk/CommentPlugin/data/System/VarCOMMENT.txt

    r8843 r8955  
    88     | *Name* | *Description* | *Default* | 
    99     | =type= | This is the name of the template to use for this comment. Comment templates are defined in a Foswiki template - see [[CommentPlugin#TemPlates][Customisation]], below. If this attribute is not defined, the type is whatever is defined by COMMENTPLUGIN_DEFAULT_TYPE, either in this topic or in your WebPreferences. | =below= | 
    10      | =default= | Default text to put into the textarea of the prompt. | | 
     10     | =default= | Default text to put into the prompt. | | 
    1111     | =target= | Name of the topic to add the comment to | the current topic | 
    1212     | =location= | Regular expression specifying the comment location in the target topic. Read _carefully_ the CommentPlugin documentation! | | 
    1313     | =mode= | For compatibility with older versions only, synonymous with =type= | | 
    1414     | =nonotify= | Set to "on" to disable change notification for target topics | =off= | 
    15      | =noform= | Set to "on" to disable the automatic form that encloses your comment block - _remember_ to insert =&lt;form&gt;= tags yourself! See [[Sandbox.CommentPluginExamples#noform][CommentPluginExamples:noform]] for an example. | =off= | 
     15     | =noform= | Set to "on" to disable the automatic form that is generated around your comment prompt if you don't provide a =FORM= template. See [[Sandbox.CommentPluginExamples#noform][CommentPluginExamples:noform]] for an example. | =off= | 
    1616     | =nopost= | Set to "on" to disable insertion of the posted text into the topic. | =off= | 
    1717     | =remove= | Set to "on" to remove the comment prompt after the first time it is clicked. | =off= | 
  • trunk/CommentPlugin/lib/Foswiki/Plugins/CommentPlugin.pm

    r8843 r8955  
    77use strict; 
    88use warnings; 
     9use Assert; 
     10use Error ':try'; 
    911 
    1012use Foswiki::Func    (); 
     
    1214 
    1315our $VERSION = '$Rev$'; 
    14 our $RELEASE = '31 Jul 2010'; 
     16our $RELEASE = '31 Aug 2010'; 
    1517our $SHORTDESCRIPTION = 
    1618  'Quickly post comments to a page without an edit/save cycle'; 
    1719our $NO_PREFS_IN_TOPIC = 1; 
    1820 
     21# Reset when the plugin is reset, this counter counts the instances of the 
     22# %COMMENT macro and indexes them. 
     23our $commentIndex; 
     24 
    1925sub initPlugin { 
    2026 
    21     #my ( $topic, $web, $user, $installWeb ) = @_; 
     27    my ( $topic, $web, $user, $installWeb ) = @_; 
     28    $commentIndex = 0; 
     29 
     30    Foswiki::Func::registerTagHandler('COMMENT', \&_COMMENT); 
     31    Foswiki::Func::registerRESTHandler('comment', \&_restSave); 
     32 
     33    if ((DEBUG) && $web eq $Foswiki::cfg{SystemWebName} 
     34          && $topic eq 'InstalledPlugins') { 
     35        # Compilation check 
     36        require Foswiki::Plugins::CommentPlugin::Comment; 
     37    } 
    2238    return 1; 
    2339} 
    2440 
    25 sub commonTagsHandler { 
    26     my ( $text, $topic, $web, $meta ) = @_; 
    27  
     41sub _COMMENT { 
     42    my ( $session, $params, $topic, $web ) = @_; 
     43     
     44    # Indexing each macro instance 
     45    $params->{comment_index} = $commentIndex++; 
     46     
     47    # Check the context has 'view' script 
     48    my $context = Foswiki::Func::getContext(); 
     49    my $disabled = ''; 
     50    if ($context->{command_line}) { 
     51        $disabled = Foswiki::Func::expandCommonVariables( 
     52            '%MAKETEXT{"Commenting is disabled while running from the command line"}%'); 
     53    } elsif (!$context->{view}) { 
     54        $disabled =  Foswiki::Func::expandCommonVariables( 
     55            '%MAKETEXT{"Commenting is disabled when not in view context"}%'); 
     56    } elsif (!($Foswiki::cfg{Plugins}{CommentPlugin}{GuestCanComment} 
     57                 || $context->{authenticated})) { 
     58        $disabled =  Foswiki::Func::expandCommonVariables( 
     59            '%MAKETEXT{"Commenting is disabled while not logged in"}%'); 
     60    } 
     61     
    2862    require Foswiki::Plugins::CommentPlugin::Comment; 
    29  
    30     my $query = Foswiki::Func::getCgiQuery(); 
    31     return unless ( defined($query) ); 
    32  
    33     return unless $_[0] =~ m/%COMMENT({.*?})?%/o; 
    34  
    35     # SMELL: Nasty, tacky way to find out where we were invoked from 
    36     my $scriptname = $ENV{'SCRIPT_NAME'} || ''; 
    37  
    38     # SMELL: unreliable 
    39     my $previewing = ( $scriptname =~ /\/(preview|gnusave|rdiff|compare)/ ); 
    40     Foswiki::Plugins::CommentPlugin::Comment::prompt( $previewing, $_[0], $web, 
    41         $topic ); 
     63     
     64    Foswiki::Plugins::CommentPlugin::Comment::prompt( 
     65        $params, $web, $topic, $disabled ); 
    4266} 
    4367 
    44 sub beforeSaveHandler { 
     68# REST handler for save operator. We use a REST handler because we need 
     69# to be able to bypass the permissions checking that the save script 
     70# would do. We handle the return in several different ways; first, if 
     71# everything is OK, we set a 200 status and drop back to allow any 
     72# endPoint to be handled. Second, if we get an exception, and the 
     73# 'comment_ajax' parameter is set, we return a 500 status. If the 
     74# parameter is not set, we pass the exception on to the UI package. 
    4575 
    46     #my ( $text, $topic, $web ) = @_; 
     76sub _restSave { 
     77    my $session = shift; 
     78    my $response = $session->{response}; 
     79    my $query = Foswiki::Func::getCgiQuery(); 
     80    my ($web, $topic) = Foswiki::Func::normalizeWebTopicName( 
     81        undef, $query->param('topic')); 
     82     
     83    try { 
     84        require Foswiki::Plugins::CommentPlugin::Comment; 
    4785 
    48     require Foswiki::Plugins::CommentPlugin::Comment; 
     86        my ($meta, $text) = Foswiki::Func::readTopic($web, $topic); 
    4987 
    50     my $query = Foswiki::Func::getCgiQuery(); 
    51     return unless $query; 
    52  
    53     my $action = $query->param('comment_action'); 
    54  
    55     return unless ( defined($action) && $action eq 'save' ); 
    56  
    57     # Stop it being applied again 
    58     $query->delete('comment_action'); 
    59  
    60     Foswiki::Plugins::CommentPlugin::Comment::save(@_); 
     88        # The save function does access control checking 
     89        $text = Foswiki::Plugins::CommentPlugin::Comment::save( 
     90            $text, $web, $topic); 
     91         
     92        Foswiki::Func::saveTopic($web, $topic, $meta, $text, 
     93                                 { ignorepermissions => 1 }); 
     94         
     95        $response->header(-status => 200); 
     96        $response->body("$web.$topic"); 
     97    } catch Foswiki::AccessControlException with { 
     98        if ($query->param('comment_ajax')) { 
     99            $response->header(-status => 404); 
     100            $response->body(shift); 
     101        } else { 
     102            shift->throw; 
     103        } 
     104    } otherwise { 
     105        if ($query->param('comment_ajax')) { 
     106            $response->header(-status => 500); 
     107            $response->body(shift); 
     108        } else { 
     109            shift->throw; 
     110        } 
     111    }; 
     112    return undef; 
    61113} 
    62114 
  • trunk/CommentPlugin/lib/Foswiki/Plugins/CommentPlugin/Comment.pm

    r8843 r8955  
    55use strict; 
    66use warnings; 
     7use Assert; 
     8use Error ':try'; 
    79 
    810use Foswiki; 
    911use Foswiki::Plugins; 
    1012use Foswiki::Store; 
    11 use Foswiki::Attrs; 
     13 
    1214use CGI qw( -any ); 
    1315 
    1416package Foswiki::Plugins::CommentPlugin::Comment; 
    15  
    16 # PUBLIC save the given comment. 
    17 sub save { 
    18  
    19     #my ( $text, $topic, $web ) = @_; 
    20  
    21     my $wikiName = Foswiki::Func::getWikiName(); 
    22     if ( 
    23         !Foswiki::Func::checkAccessPermission( 
    24             'change', $wikiName, '', $_[1], $_[2] 
    25         ) 
    26       ) 
    27     { 
    28  
    29         # user has no permission to change the topic 
    30         throw Foswiki::OopsException( 
    31             'accessdenied', 
    32             def   => 'topic_access', 
    33             web   => $_[2], 
    34             topic => $_[1] 
    35         ); 
    36     } 
    37     else { 
    38         _buildNewTopic(@_); 
    39     } 
    40 } 
    4117 
    4218# PUBLIC STATIC convert COMMENT statements to form prompts 
    4319sub prompt { 
    44  
    45     #my ( $previewing, $text, $web, $topic ) = @_; 
    46  
    47     my $defaultType = 
    48       Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE') 
    49       || 'above'; 
    50  
    51     my $message = ''; 
    52  
    53     # Is commenting disabled? 
    54     my $disable = ''; 
    55     if ( $_[0] ) { 
    56  
    57         # We are in Preview mode 
    58         $message = "(Edit - Preview)"; 
    59         $disable = 'disabled'; 
    60     } 
    61  
    62     my $idx = 0; 
    63     $_[1] =~ 
    64 s/%COMMENT({.*?})?%/_handleInput($1,$_[2],$_[3],\$idx,$message,$disable,$defaultType)/eg; 
    65 } 
    66  
    67 =pod 
    68  
    69 Parses a templatetopic attribute and returns a "Web.Topic" string. 
    70  
    71 =cut 
    72  
    73 sub _getTemplateLocation { 
    74     my ( $attrtemplatetopic, $web ) = @_; 
    75  
    76     my $templatetopic = ''; 
    77     my $templateweb = $web || ''; 
    78     if ($attrtemplatetopic) { 
     20    my ( $attrs, $web, $topic, $disabled ) = @_; 
     21 
     22    my $type = $attrs->{type} || $attrs->{mode} 
     23      || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE') 
     24        || 'above'; 
     25 
     26    my $templatetopic; 
     27    if ($attrs->{templatetopic}) { 
    7928        my ( $templocweb, $temploctopic ) = 
    80           Foswiki::Func::normalizeWebTopicName( $templateweb, 
    81             $attrtemplatetopic ); 
     29          Foswiki::Func::normalizeWebTopicName( 
     30              $web, $attrs->{templatetopic} ); 
    8231        $templatetopic = "$templocweb.$temploctopic"; 
    8332    } 
    84     return $templatetopic; 
    85 } 
    86  
    87 # PRIVATE generate an input form for a %COMMENT tag 
    88 sub _handleInput { 
    89     my ( $attributes, $web, $topic, $pidx, $message, $disable, $defaultType ) = 
    90       @_; 
    91  
    92     $attributes =~ s/^{(.*)}$/$1/ if ($attributes); 
    93  
    94     my $attrs = new Foswiki::Attrs( $attributes, 1 ); 
    95     my $type = $attrs->remove('type') || $attrs->remove('mode') || $defaultType; 
    96     my $silent            = $attrs->remove('nonotify'); 
    97     my $location          = $attrs->remove('location'); 
    98     my $remove            = $attrs->remove('remove'); 
    99     my $nopost            = $attrs->remove('nopost'); 
    100     my $default           = $attrs->remove('default'); 
    101     my $attrtemplatetopic = $attrs->remove('templatetopic') || ''; 
    102     my $templatetopic     = _getTemplateLocation( $attrtemplatetopic, $web ); 
    103  
    104     $message ||= $default || ''; 
    105     $message ||= $default || ''; 
    106     $disable ||= ''; 
     33 
     34    # Get the templates. 
     35    my $templateFile = 
     36      $templatetopic 
     37        || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_TEMPLATES') 
     38          || 'comments'; 
     39     
     40    unless( Foswiki::Func::loadTemplate($templateFile) ) { 
     41        Foswiki::Func::writeWarning( 
     42            "Could not read template file '$templateFile'"); 
     43        return _alert("Could not read templates from '$templateFile'"); 
     44    } 
     45 
     46    my $message = $attrs->{default} || ''; 
     47    $message = $disabled if $disabled; 
    10748 
    10849    # clean off whitespace 
    109     $type =~ m/(\S*)/; 
    110     $type = $1; 
     50    $type =~ s/\s+//; 
    11151 
    11252    # Expand the template in the context of the web where the comment 
    11353    # box is (not the target of the comment!) 
    114     my $input = _getTemplate( "PROMPT:$type", $web, $topic, $templatetopic ) 
    115       || ''; 
    116     return $input if $input =~ m/^%RED%/so; 
     54    my $input = Foswiki::Func::expandTemplate("PROMPT:$type"); 
     55    return _alert("No such template def 'PROMPT:$type'") 
     56      unless ( defined($input) && $input ne '' ); 
    11757 
    11858    # Expand special attributes as required 
    11959    $input =~ s/%([a-z]\w+)\|(.*?)%/_expandPromptParams($1, $2, $attrs)/ieg; 
     60 
     61    # Build the endpoint before we munge the web and topic 
     62    my $endPoint = "$web.$topic"; 
    12063 
    12164    # see if this comment is targeted at a different topic, and 
    12265    # change the url if it is. 
    12366    my $anchor = undef; 
    124     my $target = $attrs->remove('target'); 
     67    my $target = $attrs->{target}; 
    12568    if ($target) { 
    12669 
     
    13780    } 
    13881 
    139     my $url = ''; 
    140     if ( $disable eq '' ) { 
    141         $url = Foswiki::Func::getScriptUrl( $web, $topic, 'save' ); 
    142     } 
    143  
    144     my $noform = $attrs->remove('noform') || ''; 
     82    # See if a save url has been defined in the template 
     83    my $url = Foswiki::Func::expandTemplate('save_url'); 
     84 
     85    # Default it to a rest url if not 
     86    $url ||= Foswiki::Func::getScriptUrl('CommentPlugin', 'comment', 'rest' ); 
     87 
     88    $url = '' if $disabled; 
     89 
     90    my $noform = $attrs->{noform} || ''; 
    14591    if ( $input !~ m/^%RED%/ ) { 
    146         $input =~ s/%DISABLED%/$disable/g; 
     92        $input =~ s/%DISABLED%/$disabled ? 'disabled' : '' /ge; 
    14793        $input =~ s/%MESSAGE%/$message/g; 
    148         my $n = $$pidx + 0; 
    149  
    150         if ( $disable eq '' ) { 
     94        my $idx = $attrs->{comment_index}; 
     95 
     96        unless( $disabled ) { 
    15197            my $hiddenFields = ""; 
    15298            $hiddenFields .= 
    153               "\n" . CGI::hidden( -name => 'comment_action', -value => 'save' ); 
     99              CGI::hidden( -name => 'topic', -value => "$web.$topic"); 
     100 
    154101            $hiddenFields .= 
    155               "\n" . CGI::hidden( -name => 'comment_type', -value => $type ); 
    156             if ( defined($silent) ) { 
    157                 $hiddenFields .= 
    158                   "\n" . CGI::hidden( -name => 'comment_nonotify', value => 1 ); 
     102              CGI::hidden( -name => 'comment_action', -value => 'save' ); 
     103 
     104            $hiddenFields .= 
     105              CGI::hidden( -name => 'endPoint', -value => $endPoint ); 
     106 
     107            $hiddenFields .= 
     108              CGI::hidden( -name => 'comment_type', -value => $type ); 
     109 
     110            if ( defined($attrs->{nonotify}) ) { 
     111                $hiddenFields .= 
     112                  CGI::hidden( -name => 'comment_nonotify', value => 1 ); 
    159113            } 
    160114            if ($templatetopic) { 
    161                 $hiddenFields .= "\n" 
    162                   . CGI::hidden( 
    163                     -name  => 'comment_templatetopic', 
    164                     -value => $templatetopic 
    165                   ); 
    166             } 
    167             if ($location) { 
    168                 $hiddenFields .= "\n" 
    169                   . CGI::hidden( 
    170                     -name  => 'comment_location', 
    171                     -value => $location 
    172                   ); 
     115                $hiddenFields .=  
     116                  CGI::hidden( 
     117                      -name  => 'comment_templatetopic', 
     118                      -value => $templatetopic 
     119                     ); 
     120            } 
     121            if ($attrs->{location}) { 
     122                $hiddenFields .= 
     123                  CGI::hidden( 
     124                      -name  => 'comment_location', 
     125                      -value => $attrs->{location} 
     126                     ); 
    173127            } 
    174128            elsif ($anchor) { 
    175                 $hiddenFields .= "\n" 
    176                   . CGI::hidden( -name => 'comment_anchor', -value => $anchor ); 
     129                $hiddenFields .= 
     130                  CGI::hidden( -name => 'comment_anchor', -value => $anchor ); 
    177131            } 
    178132            else { 
    179                 $hiddenFields .= "\n" 
    180                   . CGI::hidden( -name => 'comment_index', -value => $$pidx ); 
    181             } 
    182             if ($nopost) { 
    183                 $hiddenFields .= "\n" 
    184                   . CGI::hidden( -name => 'comment_nopost', -value => $nopost ); 
    185             } 
    186             if ($remove) { 
    187                 $hiddenFields .= "\n" 
    188                   . CGI::hidden( -name => 'comment_remove', -value => $$pidx ); 
     133                $hiddenFields .= 
     134                  CGI::hidden( -name => 'comment_index', -value => $idx ); 
     135            } 
     136            if ($attrs->{nopost}) { 
     137                $hiddenFields .= 
     138                  CGI::hidden( -name => 'comment_nopost', 
     139                               -value => $attrs->{nopost} ); 
     140            } 
     141            if ($attrs->{remove}) { 
     142                $hiddenFields .= 
     143                  CGI::hidden( -name => 'comment_remove', -value => $idx ); 
    189144            } 
    190145            $input .= $hiddenFields; 
    191146        } 
    192         if ($noform) { 
    193             my $form = 
    194               _getTemplate( "FORM:$type", $topic, $web, $templatetopic, 'off' ) 
    195               || ''; 
     147 
     148        # SMELL: would have been more elegant to split this into 
     149        # FORM:head:type and FORM:tail:type. Too late now :-( 
     150        my $form = Foswiki::Func::expandTemplate("FORM:$type"); 
     151 
     152        if ( $noform || $form) { 
    196153            if ($form) { 
    197154                $form =~ s/%COMMENTPROMPT%/$input/; 
    198155                $input = $form; 
    199             } 
    200         } 
    201         unless ( $noform eq 'on' ) { 
     156            } else { 
     157                $input = "NOFORM $form $input"; 
     158            } 
     159        } else { 
    202160            $input = CGI::start_form( 
    203                 -name   => $type . $n, 
    204                 -id     => $type . $n, 
     161                -name   => $type . $idx, 
     162                -id     => $type . $idx, 
    205163                -action => $url, 
    206164                -method => 'post' 
    207               ) 
     165               ) 
    208166              . $input 
    209               . CGI::end_form(); 
    210         } 
    211     } 
    212     $$pidx++; 
     167                . CGI::end_form(); 
     168        } 
     169    } 
    213170    return $input; 
    214171} 
    215172 
    216 # PRIVATE get the given template and do standard expansions 
    217 sub _getTemplate { 
    218     my ( $name, $topic, $web, $templatetopic, $warn ) = @_; 
    219  
    220     $warn ||= ''; 
    221  
    222     # Get the templates. 
    223     my $templateFile = 
    224          $templatetopic 
    225       || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_TEMPLATES') 
    226       || 'comments'; 
    227  
    228     my $templates = Foswiki::Func::loadTemplate($templateFile); 
    229     if ( !$templates ) { 
    230         Foswiki::Func::writeWarning( 
    231             "Could not read template file '$templateFile'"); 
    232         return; 
    233     } 
    234  
    235     my $t = Foswiki::Func::expandTemplate($name); 
    236     return "%RED%No such template def TMPL:DEF{$name}%ENDCOLOR%" 
    237       unless ( defined($t) && $t ne '' ) || $warn eq 'off'; 
    238  
    239     return $t; 
     173sub _alert { 
     174    my $mess = shift; 
     175    return "<span class='foswikiAlert'> $mess </span>"; 
    240176} 
    241177 
     
    249185} 
    250186 
    251 # PRIVATE STATIC Performs comment insertion in the topic. 
    252 sub _buildNewTopic { 
    253  
    254     #my ( $text, $topic, $web ) = @_; 
    255     my ( $topic, $web ) = ( $_[1], $_[2] ); 
     187# PUBLIC build new topic text 
     188sub save { 
     189 
     190    my ( $text, $web, $topic ) = @_; 
     191 
     192    my $wikiName = Foswiki::Func::getWikiName(); 
     193    my $mode = $Foswiki::cfg{Plugins}{CommentPlugin}{RequiredForSave} 
     194      || 'change'; 
     195    my $access = Foswiki::Func::checkAccessPermission( 
     196        $mode, $wikiName, $text, $topic, $web); 
     197    unless ($access) { 
     198        # user has no permission to change the topic 
     199        throw Foswiki::AccessControlException( 
     200            $mode, 
     201            $wikiName, 
     202            web   => $web, 
     203            topic => $topic, 
     204            '' ); 
     205    } 
    256206 
    257207    my $query = Foswiki::Func::getCgiQuery(); 
    258208    return unless $query; 
    259209 
     210    # The type of the comment dictates where in the target topic it 
     211    # will be saved. 
    260212    my $type = 
    261          $query->param('comment_type') 
    262       || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE') 
    263       || 'above'; 
     213      $query->param('comment_type') 
     214        || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_DEFAULT_TYPE') 
     215          || 'above'; 
     216 
     217    # Indexing comment instances depends on macro expansion  
     218    # inside-out-left-right order and INCLUDE and SECTION expansion 
     219    # being correctly handled. Only relevant if the comment is being 
     220    # inserted relative to the instance, of course. 
    264221    my $index         = $query->param('comment_index') || 0; 
     222 
    265223    my $anchor        = $query->param('comment_anchor'); 
    266224    my $location      = $query->param('comment_location'); 
    267225    my $remove        = $query->param('comment_remove'); 
    268226    my $nopost        = $query->param('comment_nopost'); 
    269     my $templatetopic = $query->param('comment_templatetopic') || ''; 
    270  
    271     my $output = _getTemplate( "OUTPUT:$type", $topic, $web, $templatetopic ); 
    272     if ( $output =~ m/^%RED%/ ) { 
    273         die $output; 
    274     } 
     227    my $templatetopic = $query->param('comment_templatetopic'); 
     228 
     229    if ($templatetopic) { 
     230        my ( $templocweb, $temploctopic ) = 
     231          Foswiki::Func::normalizeWebTopicName( 
     232              $web, $templatetopic ); 
     233        $templatetopic = "$templocweb.$temploctopic"; 
     234    } 
     235 
     236    # Get the templates. 
     237    my $templateFile = 
     238      $templatetopic 
     239        || Foswiki::Func::getPreferencesValue('COMMENTPLUGIN_TEMPLATES') 
     240          || 'comments'; 
     241 
     242    Foswiki::Func::loadTemplate($templateFile); 
     243 
     244    my $output = Foswiki::Func::expandTemplate("OUTPUT:$type"); 
     245    die _alert("No such template def 'OUTPUT:$type'") unless $output; 
    275246 
    276247    # Expand the template 
     
    290261    # methods in the core. Fortunately this will work even if there is 
    291262    # no embedded meta-data. 
    292     # Note: because this is Dakar, and has sensible semantics for handling 
    293     # the =text= parameter to =save=, there is no longer any need to re-read 
    294     # the topic. The text is automatically defaulted to the existing topic 
    295     # text if the =text= parameter isn't specified - which for comments, 
    296     # it isn't. 
    297263    my $premeta  = ''; 
    298264    my $postmeta = ''; 
    299265    my $inpost   = 0; 
    300     my $text     = ''; 
    301     foreach my $line ( split( /\r?\n/, $_[0] ) ) { 
    302         if ( $line =~ /^%META:[A-Z]+{[^}]*}%/ ) { 
     266    my $innerText     = ''; 
     267    foreach my $line ( split( /\r?\n/, $text ) ) { 
     268        if ( $line =~ /^%META:[A-Z]+{[^}]*}%$/ ) { 
    303269            if ($inpost) { 
    304270                $postmeta .= $line . "\n"; 
     
    309275        } 
    310276        else { 
    311             $text .= $line . "\n"; 
     277            $innerText .= $line . "\n"; 
    312278            $inpost = 1; 
    313279        } 
    314280    } 
     281    $text = $innerText; 
    315282 
    316283    #make sure the anchor or location exits 
     
    390357    } 
    391358 
    392     $_[0] = $premeta . $text . $postmeta; 
     359    return $premeta . $text . $postmeta; 
    393360} 
    394361 
  • trunk/CommentPlugin/lib/Foswiki/Plugins/CommentPlugin/Config.spec

    r8837 r8955  
    1616# a comment is saved. 
    1717$Foswiki::cfg{Plugins}{CommentPlugin}{GuestCanComment} = 1; 
     18# ---+ Extensions 
     19# ---++ CommentPlugin 
     20# **SELECT CHANGE,COMMENT** 
     21# Access control permissions that are required to be able to add a comment 
     22# to a topic. CHANGE is the default, the same as for an adit, but you can 
     23# also select COMMENT which will check e.g. ALLOWTOPICCOMMENT. This lets you 
     24# grant users COMMENT access without giving them open access to edit the 
     25# topic. <strong>Note</strong>Foswiki 1.1 and later only. This feature is 
     26# not supported when the plugin is installed in earlier releases. These 
     27# releases require CHANGE permission on all writable topics. 
     28$Foswiki::cfg{Plugins}{CommentPlugin}{RequiredForSave} = 'CHANGE'; 
     29# **BOOLEAN** 
     30# If this option is disabled, the guest user will not be offered the 
     31# comment prompt *even if access controls permit them to save*. Note that 
     32# even if this option is true, access controls will still be checked when 
     33# a comment is saved. 
     34$Foswiki::cfg{Plugins}{CommentPlugin}{GuestCanComment} = 1; 
  • trunk/CommentPlugin/lib/Foswiki/Plugins/CommentPlugin/MANIFEST

    r8843 r8955  
     1!noci 
    12data/System/CommentPlugin.txt 0644 Plugin doc page 
    23data/System/VarCOMMENT.txt 0644 Comment tag doc page 
     
    89lib/Foswiki/Plugins/CommentPlugin.pm 0444 Plugin Perl module  
    910lib/Foswiki/Plugins/CommentPlugin/Comment.pm 0444 Plugin Perl module  
    10  
     11lib/Foswiki/Plugins/CommentPlugin/Config.spec 0444 Configuration module 
    1112pub/System/CommentPlugin/wikiringlogo20x20.png 0660 
     13pub/System/CommentPlugin/comment_src.js 0660 
  • trunk/CommentPlugin/pub/System/CommentPlugin/comment_src.js

    r8837 r8955  
     1/* 
     2Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 
     3 
     4Copyright (C) 2010 Foswiki Contributors. Foswiki Contributors 
     5are listed in the AUTHORS file in the root of this distribution. 
     6NOTE: Please extend that file, not this notice. 
     7 
     8This program is free software; you can redistribute it and/or 
     9modify it under the terms of the GNU General Public License 
     10as published by the Free Software Foundation; either version 2 
     11of the License, or (at your option) any later version. For 
     12more details read LICENSE in the root of this distribution. 
     13 
     14This program is distributed in the hope that it will be useful, 
     15but WITHOUT ANY WARRANTY; without even the implied warranty of 
     16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
     17 
     18As per the GPL, removal of this notice is prohibited. 
     19 
     20This is an example of a simple AJAX comment submission. 
     21 
     22*/ 
     23(function($) { 
     24    $(document).ready( 
     25        function() { 
     26            $("textarea.commentPluginAjax") 
     27                .blur( 
     28                    function() { 
     29                        if (this.value == '') 
     30                            this.value = this.title; 
     31                    }) 
     32                .focus( 
     33                    function() { 
     34                        if (this.value == this.title) 
     35                            this.value = ''; 
     36                    }) 
     37                .keypress( 
     38                    function() { 
     39                        var form = $(this).parents("form")[0]; 
     40                        $(form).find(".commentPluginStatusResponse").html(''); 
     41                    }); 
     42            $("input.commentPluginAjax").click( 
     43                function(e) { 
     44                    var form = $(this).parents("form")[0]; 
     45                    // Remove the endpoint; we want a status report 
     46                    $(form).find("input[name='endPoint']").remove(); 
     47                    $.post(form.action, $(form).serialize(), 
     48                           function() { 
     49                               // Fake the format of the comment that was 
     50                               // added to the topic 
     51                               $(form).before( 
     52                                   "<p/>" + $(form).find( 
     53                                       "textarea.commentPluginAjax").text() 
     54                                   + "<p />-- " 
     55                                   + foswiki.getPreference("WIKINAME")); 
     56                           }); 
     57                }); 
     58        }); 
     59})(jQuery); 
    160/* 
    261Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 
  • trunk/CommentPlugin/test/unit/CommentPlugin/CommentPluginTests.pm

    r8843 r8955  
    77use FoswikiFnTestCase; 
    88our @ISA = qw( FoswikiFnTestCase ); 
     9use Error ':try'; 
    910 
    1011use Unit::Request; 
     
    2728    $webObject->populateNewWeb(); 
    2829 
     30    Foswiki::Func::getContext()->{view} = 1; 
     31    $Foswiki::cfg{Plugins}{CommentPlugin}{RequiredForSave} = 'CHANGE'; 
     32    $Foswiki::cfg{Plugins}{CommentPlugin}{GuestCanComment} = 1; 
     33 
    2934    return; 
    3035} 
     
    6469    my ( $this, $type, $web, $topic, $anchor, $location ) = @_; 
    6570 
    66     my $eidx   = 1; 
     71    my $eidx   = $Foswiki::Plugins::CommentPlugin::commentIndex; 
    6772    my $sattrs = ""; 
    6873 
     
    7075    $topic ||= $this->{test_topic}; 
    7176 
    72     if ( $web ne $this->{test_web} || $topic ne $this->{test_topic} || $anchor ) 
     77    if ( $web ne $this->{test_web} || $topic ne $this->{test_topic} 
     78           || $anchor ) 
    7379    { 
    7480 
     
    8591    } 
    8692 
    87     my $url = Foswiki::Func::getScriptUrl( $web, $topic, 'save' ); 
     93    my $url = Foswiki::Func::getScriptUrl( 'CommentPlugin', 'comment', 'rest' ); 
    8894 
    8995    if ($location) { 
     
    94100    $sattrs .= 'type="' . $type . '" '; 
    95101 
    96     my $commentref = '%COMMENT{' . $sattrs . ' refmark="here"}%'; 
     102    my $commentref = '%COMMENT{' . $sattrs . 
     103      ' refmark="here" default="The Message"}%'; 
    97104 
    98105    # Build the target topic 
    99106    my $sample = <<"HERE"; 
    100107TopOfTopic 
    101 %COMMENT{$sattrs}% 
     108$commentref 
    102109HERE 
    103110    if ($anchor) { 
     
    116123HERE 
    117124 
    118     $this->writeTopic( $web, $topic, $sample ); 
    119     my $pidx = $eidx; 
    120     my $html = 
    121       Foswiki::Plugins::CommentPlugin::Comment::_handleInput( $sattrs, 
    122         $this->{test_web}, $this->{test_topic}, \$pidx, "The Message", "", 
    123         "bottom" ); 
     125    Foswiki::Func::saveTopic( $web, $topic, undef, $sample ); 
     126 
     127    my $html = Foswiki::Func::expandCommonVariables($commentref); 
    124128 
    125129    $html = removeEscapes($html); 
    126     $this->assert( $pidx == $eidx + 1, $html ); 
    127  
    128     $this->assert( scalar( $html =~ s/^<form(.*?)>//sio ) ); 
     130 
     131    $this->assert( scalar( $html =~ s/^<form(.*?)>//sio ), $html ); 
    129132    my $dattrs = $1; 
    130133    $this->assert( scalar( $html =~ s/<\/form>\s*$//sio ) ); 
     
    137140    $dattrs =~ s#application/x-www-form-urlencoded#multipart/form-data#; 
    138141    $this->assert_str_equals( 
    139         'enctype="multipart/form-data" id="' . $type . '1"', 
     142        'enctype="multipart/form-data" id="' . $type . '0"', 
    140143        trim($dattrs) ); 
    141144 
     
    216219            'comment_type'   => $type, 
    217220            'comment'        => $comm, 
    218         } 
    219     ); 
    220     $query->path_info("/$web/$topic"); 
     221            'topic'          => "$web.$topic", 
     222        } 
     223    ); 
     224    $query->path_info("/CommentPlugin/comment"); 
    221225    if ($anchor) { 
    222226        $query->param( -name => 'comment_anchor', -value => $anchor ); 
     
    229233    } 
    230234 
    231     my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLoginName}, $query ); 
     235    my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
    232236    my $text = "Ignore this text"; 
    233237 
    234238    # invoke the save handler 
    235     $this->captureWithKey( save => $this->getUIFn('save'), $session ); 
     239    $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
    236240 
    237241    $text = Foswiki::Func::readTopicText( $web, $topic ); 
     
    340344# id: This gives a unique name for a COMMENT, in case you have more than one COMMENT tag in a topic (mandatory with > 1 COMMENT) 
    341345 
    342     my $pidx = 0; 
    343     my $html = Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 
    344         "rows=99 cols=104 mode=after button=HoHo id=sausage", 
    345         , $this->{test_topic}, $this->{test_web}, \$pidx, "The Message", "", 
    346         "bottom" ); 
     346    my $comment = '%COMMENT{type="after" rows="99" cols="104" mode="after" button="HoHo" id="sausage"}%'; 
     347    my $html = Foswiki::Func::expandCommonVariables( $comment ); 
    347348    $html = removeEscapes($html); 
    348349    $this->assert_matches( qr/form [^>]*name=\"after0\"/,        $html ); 
     
    356357sub test_locationOverridesAnchor { 
    357358    my $this = shift; 
    358     my $pidx = 0; 
    359     my $html = Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 
    360         "target=\"$this->{test_web}.ATopic#AAnchor\" location=\"AnRE\"", 
    361         $this->{test_topic}, 
    362         $this->{test_web}, 
    363         \$pidx, 
    364         "The Message", 
    365         "", 
    366         "bottom" 
    367     ); 
     359    my $html = Foswiki::Func::expandCommonVariables("%COMMENT{type=\"bottom\" target=\"$this->{test_web}.ATopic#AAnchor\" location=\"AnRE\"}%"); 
     360 
    368361    $this->assert_matches( qr/<input ([^>]*name="comment_location".*?)\s*\/>/, 
    369362        $html ); 
     
    380373after 
    381374HERE 
    382     $this->writeTopic( $this->{test_web}, $this->{test_topic}, $sample ); 
    383     my $pidx = 0; 
     375    Foswiki::Func::saveTopic( 
     376        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
    384377    my $html = 
    385       Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 'nopost="on"', 
    386         $this->{test_web}, $this->{test_topic}, \$pidx, "The Message", "", 
    387         "bottom" ); 
     378      Foswiki::Func::expandCommonVariables( '%COMMENT{nopost="on"}%'); 
     379 
    388380    $this->assert_matches( 
    389381        qr/<input type="hidden" name="comment_nopost" value="on"/, $html ); 
     
    397389            'comment'        => $comm, 
    398390            'comment_nopost' => 'on', 
    399         } 
    400     ); 
    401     $query->path_info("/$this->{test_web}/$this->{test_topic}"); 
    402  
    403     my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLoginName}, $query ); 
     391            'topic'          => "$this->{test_web}.$this->{test_topic}" 
     392        } 
     393    ); 
     394    $query->path_info("/CommentPlugin/comment"); 
     395 
     396    my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
    404397    my $text = "Ignore this text"; 
    405398 
    406399    # invoke the save handler 
    407     $this->captureWithKey( save => $this->getUIFn('save'), $session ); 
     400    $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
    408401 
    409402    $text = 
     
    425418after 
    426419HERE 
    427     $this->writeTopic( $this->{test_web}, $this->{test_topic}, $sample ); 
    428     my $pidx = 99; 
     420    Foswiki::Func::saveTopic( 
     421        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
    429422    my $html = 
    430       Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 'remove="on"', 
    431         $this->{test_web}, $this->{test_topic}, \$pidx, "The Message", "", 
    432         "bottom" ); 
     423      Foswiki::Func::expandCommonVariables( '%COMMENT{remove="on"}%'); 
     424 
    433425    $this->assert_matches( 
    434         qr/<input type="hidden" name="comment_remove" value="99"/, $html ); 
     426        qr/<input type="hidden" name="comment_remove" value="0"/, $html ); 
    435427 
    436428    # Compose the query 
     
    443435            'comment_remove' => '0', 
    444436            'comment_index'  => '99', 
    445         } 
    446     ); 
    447     $query->path_info("/$this->{test_web}/$this->{test_topic}"); 
    448  
    449     my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLoginName}, $query ); 
     437            'topic'          => "$this->{test_web}/$this->{test_topic}", 
     438        } 
     439    ); 
     440    $query->path_info("/CommentPlugin/comment"); 
     441 
     442    my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
    450443    my $text = "Ignore this text"; 
    451444 
    452445    # invoke the save handler 
    453     $this->captureWithKey( save => $this->getUIFn('save'), $session ); 
     446    $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
    454447 
    455448    $text = 
     
    477470after 
    478471HERE 
    479     $this->writeTopic( $this->{test_web}, $this->{test_topic}, $sample ); 
    480     my $pidx = 99; 
    481     my $html = Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 
    482         'default="wibble"', $this->{test_web}, $this->{test_topic}, \$pidx, 
    483         undef, "", "bottom" ); 
     472    Foswiki::Func::saveTopic( 
     473        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
     474    my $html = Foswiki::Func::expandCommonVariables('%COMMENT{default="wibble"}%'); 
     475 
    484476    $this->assert_matches( qr#>wibble</textarea>#, $html ); 
    485477 
     
    495487after 
    496488HERE 
    497     $this->writeTopic( $this->{test_web}, $this->{test_topic}, $sample ); 
    498     my $pidx = 99; 
     489    Foswiki::Func::saveTopic( 
     490        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
    499491    my $html = 
    500       Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 'remove="on"', 
    501         $this->{test_web}, $this->{test_topic}, \$pidx, "The Message", "", 
    502         "bottom" ); 
     492      Foswiki::Func::expandCommonVariables( '%COMMENT{remove="on"}%'); 
     493 
    503494    $this->assert_matches( 
    504         qr/<input type="hidden" name="comment_remove" value="99"/, $html ); 
     495        qr/<input type="hidden" name="comment_remove" value="0"/, $html ); 
    505496 
    506497    # Compose the query 
     
    512503            'comment'        => $comm, 
    513504            'comment_anchor' => '#LatestComment', 
    514         } 
    515     ); 
    516     $query->path_info("/$this->{test_web}/$this->{test_topic}"); 
    517  
    518     my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLoginName}, $query ); 
     505            'topic'          => "$this->{test_web}.$this->{test_topic}", 
     506        } 
     507    ); 
     508    $query->path_info("/CommentPlugin/comment"); 
     509 
     510    my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
    519511    my $text = "Ignore this text"; 
    520512 
    521513    # invoke the save handler 
    522     $this->captureWithKey( save => $this->getUIFn('save'), $session ); 
     514    $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
    523515 
    524516    $text = 
     
    551543after 
    552544HERE 
    553     $this->writeTopic( $this->{test_web}, $this->{test_topic}, $sample ); 
    554     my $pidx = 99; 
     545    Foswiki::Func::saveTopic( 
     546        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
    555547    my $html = 
    556       Foswiki::Plugins::CommentPlugin::Comment::_handleInput( 'remove="on"', 
    557         $this->{test_web}, $this->{test_topic}, \$pidx, "The Message", "", 
    558         "bottom" ); 
     548      Foswiki::Func::expandCommonVariables( '%COMMENT{remove="on"}%'); 
     549 
    559550    $html = removeEscapes($html); 
    560551    $this->assert_matches( 
    561         qr/<input type="hidden" name="comment_remove" value="99"/, $html ); 
     552        qr/<input type="hidden" name="comment_remove" value="0"/, $html ); 
    562553 
    563554    # Compose the query 
     
    569560            'comment'        => $comm, 
    570561            'comment_anchor' => '#LatestComment', 
    571  
    572         } 
    573     ); 
    574     $query->path_info("/$this->{test_web}/$this->{test_topic}"); 
    575  
    576     my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLoginName}, $query ); 
     562            'topic'          => "$this->{test_web}.$this->{test_topic}", 
     563        } 
     564    ); 
     565    $query->path_info("/CommentPlugin/comment"); 
     566 
     567    my $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
    577568    my $text = "Ignore this text"; 
    578569 
    579570    # invoke the save handler 
    580     $this->captureWithKey( save => $this->getUIFn('save'), $session ); 
     571    $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
    581572 
    582573    $text = 
     
    600591} 
    601592 
     593sub test_acl_COMMENT { 
     594    my $this = shift; 
     595 
     596    my $sample = <<HERE; 
     597   * Set DENYTOPICCHANGE = $Foswiki::cfg{DefaultUserWikiName} 
     598   * Set DENYTOPICVIEW = $Foswiki::cfg{DefaultUserWikiName} 
     599   * Set ALLOWTOPICCOMMENT = $Foswiki::cfg{DefaultUserWikiName} 
     600%COMMENT% 
     601HERE 
     602    Foswiki::Func::saveTopic( 
     603        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
     604 
     605    # Compose the query 
     606    my $comm  = "This is the comment"; 
     607    my $query = Unit::Request->new( 
     608        { 
     609            'comment_action' => 'save', 
     610            'comment_type'   => 'above', 
     611            'comment'        => $comm, 
     612            topic => "$this->{test_web}.$this->{test_topic}", 
     613        } 
     614    ); 
     615    $query->path_info("/CommentPlugin/comment"); 
     616 
     617    $Foswiki::cfg{Plugins}{CommentPlugin}{RequiredForSave} = 'CHANGE'; 
     618 
     619    my ($responseText, $result, $stdout, $stderr, $session); 
     620    # First make sure we can't *change* it 
     621    $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
     622 
     623    # invoke the save handler 
     624 
     625    eval { 
     626        ($responseText, $result, $stdout, $stderr) = 
     627          $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
     628    }; 
     629 
     630    $this->assert($@); 
     631    $this->assert_matches(qr"OopsException\(accessdenied/topic_access", $@); 
     632 
     633    # Now make sure we *can* change it, given COMMENT access 
     634    $Foswiki::cfg{Plugins}{CommentPlugin}{RequiredForSave} = 'COMMENT'; 
     635 
     636    $session = Foswiki->new( $Foswiki::cfg{DefaultUserLogin}, $query ); 
     637 
     638    # invoke the save handler 
     639    ($responseText, $result, $stdout, $stderr) = 
     640      $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
     641    $this->assert_matches(qr/Status: 200/, $responseText); 
     642 
     643    my ( $meta, $text ) = 
     644      Foswiki::Func::readTopic( $this->{test_web}, $this->{test_topic} ); 
     645    $text =~ s/- \d\d [A-Z][a-z]{2} \d{4}/- DATE/; 
     646    $this->assert_str_equals(<<HERE, $text); 
     647   * Set DENYTOPICCHANGE = WikiGuest 
     648   * Set DENYTOPICVIEW = $Foswiki::cfg{DefaultUserWikiName} 
     649   * Set ALLOWTOPICCOMMENT = WikiGuest 
     650 
     651 
     652This is the comment 
     653 
     654-- TemporaryCommentPluginTestsUsersWeb.WikiGuest - DATE 
     655%COMMENT% 
     656HERE 
     657} 
     658 
     659sub test_rest_control_modes { 
     660    my $this = shift; 
     661    my $sample = <<HERE; 
     662   * Set DENYTOPICCHANGE = $Foswiki::cfg{DefaultUserWikiName} 
     663%COMMENT% 
     664HERE 
     665    Foswiki::Func::saveTopic( 
     666        $this->{test_web}, $this->{test_topic}, undef, $sample ); 
     667 
     668    # other tests have already covered the non-ajax, no endpoint mode 
     669    my $query = Unit::Request->new( 
     670        { 
     671            'comment_action' => 'save', 
     672            'comment_type'   => 'above', 
     673            'comment'        => "Arfle barfle gloop", 
     674            'comment_ajax'   => 1, 
     675            topic => "$this->{test_web}.$this->{test_topic}", 
     676        } 
     677    ); 
     678    $query->path_info("/CommentPlugin/comment"); 
     679    my ($responseText, $result, $stdout, $stderr); 
     680    my $session = new Foswiki(undef, $query); 
     681    eval { 
     682        ($responseText, $result, $stdout, $stderr) = 
     683          $this->captureWithKey( rest => $this->getUIFn('rest'), $session ); 
     684    }; 
     685    $this->assert_matches(qr/Status: 404/, $responseText); 
     686 
     687} 
     688 
    6026891; 
    603690__END__ 
Note: See TracChangeset for help on using the changeset viewer.