Skip to content
This repository was archived by the owner on Feb 27, 2024. It is now read-only.

Commit 5ebd805

Browse files
author
Greg Rickaby
authored
Merge pull request #119 from WebDevStudios/feature/60-add-comment-mutation
Feature/60 add comment mutation
2 parents 4286b4f + c6a0143 commit 5ebd805

File tree

10 files changed

+268
-14
lines changed

10 files changed

+268
-14
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {gql} from '@apollo/client'
2+
import {wpDataEndpoints} from '@/api/wordpress/connector'
3+
import commentsFields from '@/api/wordpress/_partials/commentsFields'
4+
5+
// Mutation: Add a comment to the given post
6+
const mutationAddComment = gql`
7+
mutation ADD_COMMENT(
8+
$author: String
9+
$authorEmail: String
10+
$authorUrl: String
11+
$postId: Int!
12+
$content: String!
13+
) {
14+
postComment (
15+
author: $author,
16+
authorEmail: $authorEmail,
17+
authorUrl: $authorUrl,
18+
postId: $postId,
19+
content: $content
20+
) @rest(type: "Comments", path: "${wpDataEndpoints.postComment}?{args}") {
21+
comment {
22+
${commentsFields}
23+
}
24+
}
25+
}
26+
`
27+
28+
export default mutationAddComment
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import mutationAddComment from './mutationAddComment'
2+
import {initializeFeApollo} from '../../connector'
3+
4+
/**
5+
* Post a comment to the given post. Follows established WordPress
6+
* behavior for posting comments:
7+
*
8+
* If this is an authenticated request (i.e. "logged in"), the `author`
9+
* fields will be ignored in favor of the logged-in user's information.
10+
*
11+
* If comment moderation is turned on, the `data.createComment.comment`
12+
* object may be `null`. This does not necessarily indicate an error;
13+
* the comment may be held for moderation.
14+
*
15+
* If the comment does not need manual approval, it will be returned
16+
* with this query.
17+
*
18+
* @author WebDevStudios
19+
* @param {string} author Name of the comment author.
20+
* @param {string} authorEmail Email for the comment author.
21+
* @param {string} authorUrl URL/website for the comment author.
22+
* @param {number} postId Database ID for the post being commented on.
23+
* @param {string} content Content of the comment.
24+
* @return {object} Comment data or error object.
25+
*/
26+
export default async function postComment(
27+
author,
28+
authorEmail,
29+
authorUrl,
30+
postId,
31+
content
32+
) {
33+
const apolloClient = initializeFeApollo()
34+
35+
return apolloClient
36+
.mutate({
37+
mutation: mutationAddComment,
38+
variables: {
39+
author,
40+
authorEmail,
41+
authorUrl,
42+
postId,
43+
content
44+
}
45+
})
46+
.then(
47+
(response) =>
48+
response?.data?.createComment ?? {
49+
error: true,
50+
errorMessage: `An error occurred while trying to post the comment.`
51+
}
52+
)
53+
.catch((error) => {
54+
return {
55+
error: true,
56+
errorMessage: error.message
57+
}
58+
})
59+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import {initializeWpApollo} from '../connector'
2+
import mutationCommentToPost from '../comments/mutationCommentToPost'
3+
4+
/**
5+
* Post a comment to the given post. Follows established WordPress
6+
* behavior for posting comments:
7+
*
8+
* If this is an authenticated request (i.e. "logged in"), the `author`
9+
* fields will be ignored in favor of the logged-in user's information.
10+
*
11+
* If comment moderation is turned on, the `data.createComment.comment`
12+
* object may be `null`. This does not necessarily indicate an error;
13+
* the comment may be held for moderation.
14+
*
15+
* If the comment does not need manual approval, it will be returned
16+
* with this query.
17+
*
18+
* @author WebDevStudios
19+
* @param {string} author Name of the comment author.
20+
* @param {string} authorEmail Email for the comment author.
21+
* @param {string} authorUrl URL/website for the comment author.
22+
* @param {number} postId Database ID for the post being commented on.
23+
* @param {string} content Content of the comment.
24+
* @return {object} Comment data or error object.
25+
*/
26+
export default async function postCommentToPost(
27+
author,
28+
authorEmail,
29+
authorUrl,
30+
postId,
31+
content
32+
) {
33+
// Get/create Apollo instance.
34+
const apolloClient = initializeWpApollo()
35+
36+
// Set up return object.
37+
const response = {
38+
apolloClient,
39+
comment: null
40+
}
41+
42+
// Determine query variables.
43+
const variables = {
44+
author,
45+
authorEmail,
46+
authorUrl,
47+
postId: parseInt(postId),
48+
content
49+
}
50+
51+
// Execute query.
52+
await apolloClient
53+
.mutate({mutation: mutationCommentToPost, variables})
54+
.then((comment) => {
55+
const {data} = comment
56+
// Set error props if data not found.
57+
if (!data?.createComment) {
58+
response.error = true
59+
response.errorMessage = `An error occurred while trying to post the comment.`
60+
61+
return null
62+
}
63+
64+
response.comment = data.createComment.comment
65+
})
66+
.catch((error) => {
67+
response.error = true
68+
response.errorMessage = error.message
69+
})
70+
71+
return response
72+
}
Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
// Query partial: retrieve comment fields.
22
const commentsFields = `
3-
edges {
4-
node {
5-
databaseId
6-
content(format: RENDERED)
7-
parentDatabaseId
8-
approved
9-
id
10-
date
11-
parentId
12-
type
3+
databaseId
4+
content(format: RENDERED)
5+
parentDatabaseId
6+
approved
7+
id
8+
date
9+
parentId
10+
type
11+
author {
12+
node {
13+
name
14+
url
15+
}
1316
}
14-
}
1517
`
1618
export default commentsFields

api/wordpress/_partials/commentsPostFields.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import commentsFields from './commentsFields'
33
// Query partial: retrieve comment post fields.
44
const commentsPostFields = `
55
comments(first: 10) {
6-
${commentsFields}
6+
edges {
7+
node {
8+
${commentsFields}
9+
}
10+
}
711
}
812
`
913
export default commentsPostFields
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {gql} from '@apollo/client'
2+
import commentsFields from '../_partials/commentsFields'
3+
4+
// Mutation: Add a comment to the given post
5+
const mutationCommentToPost = gql`
6+
mutation ADD_COMMENT(
7+
$author: String
8+
$authorEmail: String
9+
$authorUrl: String
10+
$postId: Int!
11+
$content: String!
12+
) {
13+
createComment (
14+
input: {
15+
author: $author,
16+
authorEmail: $authorEmail,
17+
authorUrl: $authorUrl,
18+
commentOn: $postId,
19+
content: $content
20+
}
21+
) {
22+
comment {
23+
${commentsFields}
24+
}
25+
}
26+
}
27+
`
28+
29+
export default mutationCommentToPost

api/wordpress/comments/queryCommentsByPostId.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ const queryCommentsByPostId = gql`
2121
where: {contentId: $id, order: $order, orderby: $orderby}
2222
) {
2323
${archivePageInfo}
24-
${commentsFields}
24+
edges {
25+
node {
26+
${commentsFields}
27+
}
28+
}
2529
}
2630
}
2731
`

api/wordpress/connector.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ const wpDataEndpointBase = '/wp'
1818

1919
// Define Frontend WP API data endpoints.
2020
export const wpDataEndpoints = {
21-
archive: `${wpDataEndpointBase}/archive`
21+
archive: `${wpDataEndpointBase}/archive`,
22+
postComment: `${wpDataEndpointBase}/postComment`
2223
}
2324

2425
let wpApolloClient

pages/api/wp/postComment.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import postCommentToPost from '@/api/wordpress/_global/postCommentToPost'
2+
3+
/**
4+
* Load more posts for an archive.
5+
*
6+
* @author WebDevStudios
7+
* @param {object} req Instance of http.IncomingMessage.
8+
* @param {object} res Instance of http.ServerResponse.
9+
*/
10+
export default async function postComment(req, res) {
11+
try {
12+
// Retrieve props from request query params.
13+
const {author, authorEmail, authorUrl, postId, content} = req.query
14+
15+
const commentResponse = await postCommentToPost(
16+
author,
17+
authorEmail,
18+
authorUrl,
19+
postId,
20+
content
21+
)
22+
23+
// Check for errors.
24+
if (commentResponse.error) {
25+
throw new Error(commentResponse.errorMessage)
26+
}
27+
28+
// Remove Apollo client from return.
29+
delete commentResponse?.apolloClient
30+
31+
res.status(200).send(commentResponse)
32+
} catch (error) {
33+
res
34+
.status(error?.status || 500)
35+
.end(
36+
error?.message || 'An error occurred while attempted to load more posts'
37+
)
38+
}
39+
}

pages/blog/[[...slug]].js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import getPostTypeStaticProps from '@/api/wordpress/_global/getPostTypeStaticPro
33
import Layout from '@/components/common/Layout'
44
import Link from 'next/link'
55
import getArchivePosts from '@/api/frontend/wp/archive/getArchivePosts'
6+
import postComment from '@/api/frontend/wp/comments/postComment'
67
import getPagePropTypes from '@/functions/getPagePropTypes'
78
import Blocks from '@/components/molecules/Blocks'
89

@@ -29,6 +30,20 @@ export default function BlogPost({post, archive, posts, pagination}) {
2930
await getArchivePosts(postType, pagination?.endCursor)
3031
}
3132

33+
/**
34+
* Post a comment back to the blog
35+
*/
36+
async function postTestComment() {
37+
// TODO: get form data and post the comment
38+
await postComment(
39+
'Test Testerson',
40+
41+
'https://nextjswp.test',
42+
post.databaseId,
43+
'This is a test comment.'
44+
)
45+
}
46+
3247
// Check for post archive.
3348
// TODO create generic archive component and move this check to `_app.js`.
3449
if (archive) {
@@ -69,6 +84,7 @@ export default function BlogPost({post, archive, posts, pagination}) {
6984
__html: JSON.stringify(post?.comments ?? [])
7085
}}
7186
/>
87+
<button onClick={postTestComment}>Post test comment</button>
7288
</article>
7389
</Layout>
7490
)

0 commit comments

Comments
 (0)