Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Tickets are now held for moderator approval. |
|---|---|
| Timelines: | family | ancestors | descendants | both | moderation |
| Files: | files | file ages | folders |
| SHA1: |
aa4dd798351eeced19d8e13aa2bd28be |
| User & Date: | drh 2012-11-01 15:08:29.735 |
Context
|
2012-11-01
| ||
| 17:56 | Add moderator approval for attachments. check-in: 9ac467310f user: drh tags: moderation | |
| 15:08 | Tickets are now held for moderator approval. check-in: aa4dd79835 user: drh tags: moderation | |
| 14:34 | Wiki moderation now appears to be working. check-in: b7ccf110f3 user: drh tags: moderation | |
Changes
Changes to src/info.c.
| ︙ | ︙ | |||
1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 |
*/
void tinfo_page(void){
int rid;
char *zDate;
const char *zUuid;
char zTktName[UUID_SIZE+1];
Manifest *pTktChng;
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
pTktChng = manifest_get(rid, CFTYPE_TICKET);
if( pTktChng==0 ){
fossil_redirect_home();
}
style_header("Ticket Change Details");
| > > > > > > > > > > > > > > < < < < < < < < | | | < | | > | > > > | > > > > > > > > | | | | > > | | > > > > > > > > > > > > | 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 |
*/
void tinfo_page(void){
int rid;
char *zDate;
const char *zUuid;
char zTktName[UUID_SIZE+1];
Manifest *pTktChng;
int modPending;
const char *zModAction;
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
pTktChng = manifest_get(rid, CFTYPE_TICKET);
zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
memcpy(zTktName, pTktChng->zTicketUuid, UUID_SIZE+1);
if( pTktChng==0 ){
fossil_redirect_home();
}
if( g.perm.ModTkt && (zModAction = P("modaction"))!=0 ){
if( strcmp(zModAction,"delete")==0 ){
moderation_disapprove(rid);
cgi_redirectf("%R/tktview/%s", zTktName);
/*NOTREACHED*/
}
if( strcmp(zModAction,"approve")==0 ){
moderation_approve(rid);
}
}
style_header("Ticket Change Details");
style_submenu_element("Raw", "Raw", "%R/artifact/%S", zUuid);
style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);
@ <div class="section">Overview</div>
@ <p><table class="label-value">
@ <tr><th>Artifact ID:</th>
@ <td>%z(href("%R/artifact/%s",zUuid))%s(zUuid)</a>
if( g.perm.Setup ){
@ (%d(rid))
}
modPending = moderation_pending(rid);
if( modPending ){
@ <span class="modpending">*** Moderation Pending ***</span>
}
@ <tr><th>Ticket:</th>
@ <td>%z(href("%R/tktview/%s",zTktName))%s(zTktName)</a></td></tr>
@ <tr><th>Date:</th><td>
hyperlink_to_date(zDate, "</td></tr>");
free(zDate);
@ <tr><th>User:</th><td>
hyperlink_to_user(pTktChng->zUser, zDate, "</td></tr>");
@ </table>
if( g.perm.ModTkt && modPending ){
@ <div class="section">Moderation</div>
@ <blockquote>
@ <form method="POST" action="%R/tinfo/%s(zUuid)">
@ <label><input type="radio" name="modaction" value="delete">
@ Delete this change</label><br />
@ <label><input type="radio" name="modaction" value="approve">
@ Approve this change</label><br />
@ <input type="submit" value="Submit">
@ </form>
@ </blockquote>
}
@ <div class="section">Changes</div>
@ <p>
ticket_output_change_artifact(pTktChng);
manifest_destroy(pTktChng);
style_footer();
}
/*
** WEBPAGE: info
** URL: info/ARTIFACTID
|
| ︙ | ︙ |
Changes to src/moderate.c.
| ︙ | ︙ | |||
138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
void modreq_page(void){
Blob sql;
Stmt q;
login_check_credentials();
if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
style_header("Pending Moderation Requests");
blob_init(&sql, timeline_query_for_www(), -1);
blob_appendf(&sql,
" AND event.objid IN (SELECT objid FROM modreq)"
" ORDER BY event.mtime DESC"
);
db_prepare(&q, blob_str(&sql));
www_print_timeline(&q, 0, 0, 0, 0);
| > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
void modreq_page(void){
Blob sql;
Stmt q;
login_check_credentials();
if( !g.perm.RdWiki && !g.perm.RdTkt ){ login_needed(); return; }
style_header("Pending Moderation Requests");
@ <h2>All Pending Moderation Requests</h2>
blob_init(&sql, timeline_query_for_www(), -1);
blob_appendf(&sql,
" AND event.objid IN (SELECT objid FROM modreq)"
" ORDER BY event.mtime DESC"
);
db_prepare(&q, blob_str(&sql));
www_print_timeline(&q, 0, 0, 0, 0);
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
413 414 415 416 417 418 419 420 421 422 423 424 425 426 |
if( idx>=nField ){
Th_ErrorMessage(g.interp, "no such TICKET column: ", argv[1], argl[1]);
return TH_ERROR;
}
azAppend[idx] = mprintf("%.*s", argl[2], argv[2]);
return TH_OK;
}
/*
** Subscript command: submit_ticket
**
** Construct and submit a new ticket artifact. The fields of the artifact
** are the names of the columns in the TICKET table. The content is
** taken from TH variables. If the content is unchanged, the field is
| > > > > > > > > > > > > > > > > > > > > > > > > | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
if( idx>=nField ){
Th_ErrorMessage(g.interp, "no such TICKET column: ", argv[1], argl[1]);
return TH_ERROR;
}
azAppend[idx] = mprintf("%.*s", argl[2], argv[2]);
return TH_OK;
}
/*
** Write a ticket into the repository.
*/
static void ticket_put(Blob *pTicket, const char *zTktId, int needMod){
int rid = content_put_ex(pTicket, 0, 0, 0, needMod);
if( rid==0 ){
fossil_panic("trouble committing ticket: %s", g.zErrMsg);
}
if( needMod ){
moderation_table_create();
db_multi_exec(
"INSERT INTO modreq(objid, tktid) VALUES(%d,'%s')",
rid, zTktId
);
}else{
db_multi_exec("INSERT INTO unsent VALUES(%d);", rid);
db_multi_exec("INSERT INTO unclustered VALUES(%d);", rid);
}
manifest_crosslink_begin();
manifest_crosslink(rid, pTicket);
assert( blob_is_reset(pTicket) );
manifest_crosslink_end();
}
/*
** Subscript command: submit_ticket
**
** Construct and submit a new ticket artifact. The fields of the artifact
** are the names of the columns in the TICKET table. The content is
** taken from TH variables. If the content is unchanged, the field is
|
| ︙ | ︙ | |||
496 497 498 499 500 501 502 |
@ <hr /></font>
return TH_OK;
}else if( g.thTrace ){
Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
"}<br />\n",
blob_str(&tktchng));
}else{
| | < < < < < < < | 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
@ <hr /></font>
return TH_OK;
}else if( g.thTrace ){
Th_Trace("submit_ticket {\n<blockquote><pre>\n%h\n</pre></blockquote>\n"
"}<br />\n",
blob_str(&tktchng));
}else{
ticket_put(&tktchng, zUuid, g.perm.ModTkt==0);
}
return ticket_change();
}
/*
** WEBPAGE: tktnew
|
| ︙ | ︙ | |||
1185 1186 1187 1188 1189 1190 1191 |
azField[i], strlen(zValue), zValue);
}
}
blob_appendf(&tktchng, "K %s\n", zTktUuid);
blob_appendf(&tktchng, "U %F\n", zUser);
md5sum_blob(&tktchng, &cksum);
blob_appendf(&tktchng, "Z %b\n", &cksum);
| | < < < < < < < | 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 |
azField[i], strlen(zValue), zValue);
}
}
blob_appendf(&tktchng, "K %s\n", zTktUuid);
blob_appendf(&tktchng, "U %F\n", zUser);
md5sum_blob(&tktchng, &cksum);
blob_appendf(&tktchng, "Z %b\n", &cksum);
ticket_put(&tktchng, zTktUuid, 0);
printf("ticket %s succeeded for %s\n",
(eCmd==set?"set":"add"),zTktUuid);
}
}
}
|