| | 1027 | package MT::AtomServer::Comments; |
| | 1028 | use strict; |
| | 1029 | |
| | 1030 | use base qw( MT::AtomServer::Weblog ); |
| | 1031 | use MT::I18N qw( encode_text ); |
| | 1032 | |
| | 1033 | sub script { $_[0]->{cfg}->AtomScript . '/comments' } |
| | 1034 | |
| | 1035 | sub handle_request { |
| | 1036 | my $app = shift; |
| | 1037 | $app->authenticate || return; |
| | 1038 | if (my $svc = $app->{param}{svc}) { |
| | 1039 | if ($svc eq 'upload') { |
| | 1040 | return $app->handle_upload; |
| | 1041 | } elsif ($svc eq 'categories') { |
| | 1042 | return $app->get_categories; |
| | 1043 | } |
| | 1044 | } |
| | 1045 | my $method = $app->request_method; |
| | 1046 | if ($method eq 'POST') { |
| | 1047 | # return $app->new_comment; |
| | 1048 | } elsif ($method eq 'PUT') { |
| | 1049 | # return $app->edit_comment; |
| | 1050 | } elsif ($method eq 'DELETE') { |
| | 1051 | # return $app->delete_comment; |
| | 1052 | } elsif ($method eq 'GET') { |
| | 1053 | if ($app->{param}{comment_id}) { |
| | 1054 | return $app->get_comment; |
| | 1055 | } elsif ($app->{param}{entry_id}) { |
| | 1056 | return $app->get_comments; |
| | 1057 | } else { |
| | 1058 | return $app->get_blog_comments; |
| | 1059 | } |
| | 1060 | } |
| | 1061 | } |
| | 1062 | |
| | 1063 | sub new_with_comment { |
| | 1064 | my $app = shift; |
| | 1065 | my ($comment) = @_; |
| | 1066 | my $atom = MT::Atom::Entry->new_with_comment( $comment, Version => 1.0 ); |
| | 1067 | |
| | 1068 | my $mo = MT::Atom::Entry::_create_issued( |
| | 1069 | $comment->modified_on || $comment->created_on, $comment->blog); |
| | 1070 | $atom->set(MT::AtomServer::Weblog::NS_APP(), 'edited', $mo); |
| | 1071 | |
| | 1072 | $atom; |
| | 1073 | } |
| | 1074 | |
| | 1075 | sub get_comment { |
| | 1076 | my $app = shift; |
| | 1077 | my $blog = $app->{blog}; |
| | 1078 | my $comment_id = $app->{param}{comment_id} |
| | 1079 | or return $app->error(400, "No comment_id"); |
| | 1080 | my $comment = MT::Comment->load($comment_id) |
| | 1081 | or return $app->error(400, "Invalid comment_id"); |
| | 1082 | my $entry = $comment->entry; |
| | 1083 | my $uri = $app->base . $app->uri . '/blog_id=' . $blog->id; |
| | 1084 | my $c = $app->new_with_comment($comment); |
| | 1085 | $c->add_link({ rel => 'self', type => $app->atom_x_content_type, |
| | 1086 | href => $uri . '/comment_id=' . $comment->id }); |
| | 1087 | # feed/updated should be added before entries |
| | 1088 | # so we postpone adding them until later |
| | 1089 | $c->set('http://purl.org/syndication/thread/1.0', 'in-reply-to', |
| | 1090 | undef, |
| | 1091 | { ref => $entry->atom_id, |
| | 1092 | type => 'text/html', |
| | 1093 | href => $entry->permalink } ); |
| | 1094 | $app->run_callbacks( 'get_comment', $c, $comment ); |
| | 1095 | $app->response_content_type($app->atom_content_type); |
| | 1096 | $c->as_xml; |
| | 1097 | } |
| | 1098 | |
| | 1099 | sub get_blog_comments { |
| | 1100 | my $app = shift; |
| | 1101 | my $blog = $app->{blog}; |
| | 1102 | my %terms = (blog_id => $blog->id, visible => 1); |
| | 1103 | my %arg = (sort => $app->get_posts_order_field, direction => 'descend'); |
| | 1104 | my $Limit = 20; |
| | 1105 | $arg{limit} = $Limit + 1; |
| | 1106 | $arg{offset} = $app->{param}{offset} || 0; |
| | 1107 | |
| | 1108 | my $feed = $app->new_feed(); |
| | 1109 | my $uri = $app->base . $app->uri . '/blog_id=' . $blog->id; |
| | 1110 | my $blogname = encode_text($blog->name, undef, 'utf-8'); |
| | 1111 | $feed->add_link({ rel => 'alternate', type => 'text/html', |
| | 1112 | href => $blog->site_url }); |
| | 1113 | $feed->add_link({ rel => 'self', type => $app->atom_x_content_type, |
| | 1114 | href => $uri }); |
| | 1115 | $feed->title($blogname); |
| | 1116 | |
| | 1117 | require URI; |
| | 1118 | my $site_uri = URI->new($blog->site_url); |
| | 1119 | if ( $site_uri ) { |
| | 1120 | my $blog_created = MT::Util::format_ts('%Y-%m-%d', $blog->created_on, $blog, 'en', 0); |
| | 1121 | my $id = 'tag:'.$site_uri->host.','.$blog_created.':'.$site_uri->path.'/'.$blog->id; |
| | 1122 | $feed->id($id); |
| | 1123 | } |
| | 1124 | $app->_comments_in_atom($feed, \%terms, \%arg); |
| | 1125 | $app->run_callbacks( 'get_blog_comments', $feed, $blog ); |
| | 1126 | ## xxx add next/prev links |
| | 1127 | $app->response_content_type($app->atom_content_type); |
| | 1128 | $feed->as_xml; |
| | 1129 | } |
| | 1130 | |
| | 1131 | sub get_comments { |
| | 1132 | my $app = shift; |
| | 1133 | my $blog = $app->{blog}; |
| | 1134 | my $entry_id = $app->{param}{entry_id} |
| | 1135 | or return $app->error(400, "No entry_id"); |
| | 1136 | my $entry = MT::Entry->load($entry_id) |
| | 1137 | or return $app->error(400, "Invalid entry_id"); |
| | 1138 | my %terms = (blog_id => $blog->id, entry_id => $entry->id, visible => 1); |
| | 1139 | my %arg = (sort => $app->get_posts_order_field, direction => 'descend'); |
| | 1140 | my $Limit = 20; |
| | 1141 | $arg{limit} = $Limit + 1; |
| | 1142 | $arg{offset} = $app->{param}{offset} || 0; |
| | 1143 | |
| | 1144 | my $feed = $app->new_feed(); |
| | 1145 | my $uri = $app->base . $app->uri . '/blog_id=' . $blog->id; |
| | 1146 | my $blogname = encode_text($blog->name, undef, 'utf-8'); |
| | 1147 | $feed->add_link({ rel => 'alternate', type => 'text/html', |
| | 1148 | href => $entry->permalink }); |
| | 1149 | $feed->add_link({ rel => 'self', type => $app->atom_x_content_type, |
| | 1150 | href => $uri . '/entry_id=' . $entry->id }); |
| | 1151 | $feed->title($entry->title); |
| | 1152 | $feed->id($entry->atom_id . '/comments'); |
| | 1153 | $app->_comments_in_atom($feed, \%terms, \%arg); |
| | 1154 | $app->run_callbacks( 'get_comments', $feed, $entry ); |
| | 1155 | ## xxx add next/prev links |
| | 1156 | $app->response_content_type($app->atom_content_type); |
| | 1157 | $feed->as_xml; |
| | 1158 | } |
| | 1159 | |
| | 1160 | sub _comments_in_atom { |
| | 1161 | my $app = shift; |
| | 1162 | my ( $feed, $terms, $args ) = @_; |
| | 1163 | require MT::Comment; |
| | 1164 | my $iter = MT::Comment->load_iter($terms, $args); |
| | 1165 | my $latest_date = 0; |
| | 1166 | my @comments; |
| | 1167 | while (my $comment = $iter->()) { |
| | 1168 | my $c = $app->new_with_comment($comment); |
| | 1169 | # feed/updated should be added before entries |
| | 1170 | # so we postpone adding them until later |
| | 1171 | my $entry = $comment->entry; |
| | 1172 | $c->set('http://purl.org/syndication/thread/1.0', 'in-reply-to', |
| | 1173 | undef, |
| | 1174 | { ref => $entry->atom_id, |
| | 1175 | type => 'text/html', |
| | 1176 | href => $entry->permalink } ); |
| | 1177 | push @comments, $c; |
| | 1178 | my $date = $comment->modified_on || $comment->created_on; |
| | 1179 | if ( $latest_date < $date ) { |
| | 1180 | $latest_date = $date; |
| | 1181 | $feed->updated( $c->updated ); |
| | 1182 | } |
| | 1183 | } |
| | 1184 | $feed->add_entry($_) foreach @comments; |
| | 1185 | $feed; |
| | 1186 | } |
| | 1187 | |
| | 1188 | |
| | 1288 | =item get_posts |
| | 1289 | |
| | 1290 | callback($eh, $app, $feed, $blog) |
| | 1291 | |
| | 1292 | Called right before get_posts method returns atom feed response. |
| | 1293 | I<$feed> is a reference to XML::Atom::Feed object. |
| | 1294 | I<$blog> is a reference to the requested MT::Blog object. |
| | 1295 | |
| | 1296 | =item get_post |
| | 1297 | |
| | 1298 | callback($eh, $app, $atom_entry, $entry) |
| | 1299 | |
| | 1300 | Called right before get_post method returns atom entry response. |
| | 1301 | I<$atom_entry> is a reference to XML::Atom::Entry object. |
| | 1302 | I<$entry> is a reference to the requested MT::Entry object. |
| | 1303 | |
| | 1304 | =item get_blog_comments |
| | 1305 | |
| | 1306 | callback($eh, $app, $feed, $blog) |
| | 1307 | |
| | 1308 | Called right before get_blog_comments method returns atom feed response. |
| | 1309 | I<$feed> is a reference to XML::Atom::Feed object. |
| | 1310 | I<$blog> is a reference to the requested MT::Blog object. |
| | 1311 | |
| | 1312 | =item get_comments |
| | 1313 | |
| | 1314 | callback($eh, $app, $feed, $entry) |
| | 1315 | |
| | 1316 | Called right before get_comments method returns atom feed response. |
| | 1317 | I<$feed> is a reference to XML::Atom::Feed object. |
| | 1318 | I<$entry> is a reference to the requested MT::Entry object. |
| | 1319 | |
| | 1320 | =item get_comment |
| | 1321 | |
| | 1322 | callback($eh, $app, $atom_entry, $comment) |
| | 1323 | |
| | 1324 | Called right before get_comment method returns atom entry response. |
| | 1325 | I<$atom_entry> is a reference to XML::Atom::Entry object. |
| | 1326 | I<$comment> is a reference to the requested MT::Comment object. |
| | 1327 | |