Permalink
Browse files

Simple overview of comments, with delete option.

  • Loading branch information...
1 parent 299087c commit 15d22ba672011b7628d88befa3b9aa21937d869b @mworrell mworrell committed Jan 19, 2010
@@ -0,0 +1,3 @@
+[
+ {admin_comments, ["admin", "comments"], resource_admin_comments, []}
+].
@@ -31,11 +31,14 @@
%% interface functions
-export([
install/1,
- event/2
+ event/2,
+ search/2
]).
-include_lib("zotonic.hrl").
+-record(state, {context}).
+
%% @doc Handle the submit event of a new comment
event({submit, {newcomment, Args}, _TriggerId, _TargetId}, Context) ->
@@ -64,6 +67,12 @@ event({submit, {newcomment, Args}, _TriggerId, _TargetId}, Context) ->
end.
+%% @doc Return the list of recent comments. Returned values are the complete records.
+search({search_query, {recent_comments, []}, OffsetLimit}, Context) ->
+ m_comment:search({recent_comments, []}, OffsetLimit, Context);
+search(_, _Context) ->
+ undefined.
+
%%====================================================================
%% API
%%====================================================================
@@ -85,8 +94,9 @@ init(Args) ->
process_flag(trap_exit, true),
Context = proplists:get_value(context, Args),
Context1 = z_context:new(Context),
+ z_notifier:observe(search_query, {?MODULE, search}, Context),
install(Context1),
- {ok, []}.
+ {ok, #state{context=Context1}}.
%% @spec handle_call(Request, From, State) -> {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
@@ -121,7 +131,8 @@ handle_info(_Info, State) ->
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
-terminate(_Reason, _State) ->
+terminate(_Reason, State) ->
+ z_notifier:observe(search_query, {?MODULE, search}, State#state.context),
ok.
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
@@ -31,7 +31,10 @@
list_rsc/2,
get/2,
- insert/5
+ insert/5,
+ delete/2,
+
+ search/3
]).
-include_lib("zotonic.hrl").
@@ -77,6 +80,7 @@ get(CommentId, Context) ->
%% @doc Insert a new comment. Fetches the submitter information from the Context.
%% @spec insert(Id:int(), Name::string(), Email::string(), Message::string(), Context) -> {ok, CommentId} | {error, Reason}
%% @todo Insert external ip address and user agent string
+%% @todo Access control, only allow comment when resource is visible for the current user
insert(RscId, Name, Email, Message, Context) ->
Email = z_string:trim(Email),
Name1 = z_html:escape(z_string:trim(Name)),
@@ -104,9 +108,34 @@ insert(RscId, Name, Email, Message, Context) ->
end.
+%% @doc Delete a comment. Only possible if the user has edit permission on the page.
+delete(CommentId, Context) ->
+ case z_db:q1("select rsc_id from comment where id = $1", [CommentId], Context) of
+ undefined -> {error, enoent};
+ RscId ->
+ case z_acl:rsc_editable(RscId, Context) of
+ true ->
+ z_db:q("delete from comment where id = $1", [CommentId], Context),
+ z_depcache:flush({comment_rsc, RscId}, Context),
+ ok;
+ false ->
+ {error, eacces}
+ end
+ end.
+
+
%% @doc Return the gravatar code of an email address. See also http://gravatar.com/
%% @spec gravatar_code(Email) -> list()
gravatar_code(Email) ->
z_string:to_lower(z_utils:hex_encode(erlang:md5(z_string:to_lower(Email)))).
+
+%% @doc Return the search as used by z_search and the search model.
+search({recent_comments, []}, _OfffsetLimit, _Context) ->
+ #search_sql{
+ select="c.*",
+ from="comment c",
+ order="c.created desc",
+ assoc=true
+ }.
@@ -0,0 +1,49 @@
+%% @author Marc Worrell <marc@worrell.nl>
+%% @copyright 2010 Marc Worrell
+%% @date 2010-01-19
+%% @doc Creates an editable overview of all categories.
+
+%% Copyright 2010 Marc Worrell
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+
+-module(resource_admin_comments).
+-author("Marc Worrell <marc@worrell.nl>").
+
+-export([
+ is_authorized/2,
+ event/2
+]).
+
+-include_lib("resource_html.hrl").
+
+is_authorized(ReqData, Context) ->
+ z_auth:wm_is_authorized(ReqData, Context).
+
+
+html(Context) ->
+ Html = z_template:render("admin_comments.tpl", [{page_admin_comments, true}], Context),
+ z_context:output(Html, Context).
+
+event({postback, {comment_delete, Args}, _TriggerId, _TargetId}, Context) ->
+ CommentId = proplists:get_value(id, Args),
+ case m_comment:delete(CommentId, Context) of
+ ok ->
+ OnSuccess = proplists:get_all_values(on_success, Args),
+ Context1 = z_render:wire(OnSuccess, Context),
+ z_render:growl("The comment has been deleted.", Context1);
+ {error, _Reason} ->
+ %% Assume permission problem.
+ z_render:growl_error("You are not allowed to delete the comment.", Context)
+ end.
+
@@ -0,0 +1 @@
+<li><a href="{% url admin_comments %}" {% if page_admin_comments %}class="current"{% endif %}>Comments</a></li>
@@ -0,0 +1,51 @@
+{% extends "admin_base.tpl" %}
+
+{% block title %}
+Recent Comments
+{% endblock %}
+
+{% block content %}
+ <div id="content" class="zp-85">
+ <div class="block clearfix">
+
+ <h2>Comments</h2>
+
+ <h3 class="above-list">Recent comments</h3>
+ <ul class="short-list">
+ <li class="headers clearfix">
+ <span class="zp-15">Added on</span>
+ <span class="zp-15">Page</span>
+ <span class="zp-25">Message</span>
+ <span class="zp-15">Name</span>
+ <span class="zp-15">Email</span>
+ <span class="zp-15">Options</span>
+ </li>
+ {% with m.search.paged[{recent_comments}] as result %}
+ {% for comment in result %}
+ {% with comment.id as id %}
+ <li {% if not comment.is_visible %}class="unpublished" {% endif %}>
+ <a id="{{ #comment.id }}" href="{{ m.rsc[comment.rsc_id].page_url }}#comment-{{ id }}" class="clearfix">
+ <span class="zp-15">{{ comment.created|date:"d M Y, H:i" }}</span>
+ <span class="zp-15">{{ m.rsc[comment.rsc_id].title|truncate:20 }}</span>
+ <span class="zp-25">{{ comment.message|striptags|truncate:40 }}</span>
+ <span class="zp-15">{{ comment.name|truncate:20 }}</span>
+ <span class="zp-15">{{ comment.email|truncate:20|escape }}</span>
+ <span class="zp-15">
+ {% button text="view" action={redirect location=[m.rsc[comment.rsc_id].page_url,"#comment-",id|format_integer]|join } %}
+ {% button text="delete" postback={comment_delete id=id on_success={slide_fade_out id=#comment.id}} %}
+ </span>
+ </a>
+ </li>
+ {% endwith %}
+ {% empty %}
+ <li>There are no comments.</li>
+ {% endfor %}
+ </ul>
+
+ {% pager result=result dispatch="admin_comments" qargs %}
+
+ {% endwith %}
+
+ </div>
+ </div>
+{% endblock %}

0 comments on commit 15d22ba

Please sign in to comment.