Fossil SCM
Separate /forumpost and /forumthread pages.
Commit
2dfb887310cf6313bba6fd2c62694adabc0a2b9f3fbaf48fcc98c8fecc55787c
Parent
fd06544c04a3a13…
1 file changed
+32
-12
+32
-12
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -287,29 +287,29 @@ | ||
| 287 | 287 | } |
| 288 | 288 | zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate); |
| 289 | 289 | @ <p>By %h(pPost->zUser) on %h(zDate) (%d(p->fpid)) |
| 290 | 290 | fossil_free(zDate); |
| 291 | 291 | if( p->pEdit ){ |
| 292 | - @ edit of %z(href("%R/forumthread/%S?t",p->pEdit->zUuid))%d(p->fprev)</a> | |
| 292 | + @ edit of %z(href("%R/forumpost/%S?t",p->pEdit->zUuid))%d(p->fprev)</a> | |
| 293 | 293 | } |
| 294 | 294 | if( p->firt ){ |
| 295 | 295 | ForumEntry *pIrt = p->pPrev; |
| 296 | 296 | while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; |
| 297 | 297 | if( pIrt ){ |
| 298 | - @ reply to %z(href("%R/forumthread/%S?t",pIrt->zUuid))%d(p->firt)</a> | |
| 298 | + @ reply to %z(href("%R/forumpost/%S?t",pIrt->zUuid))%d(p->firt)</a> | |
| 299 | 299 | } |
| 300 | 300 | } |
| 301 | 301 | if( p->pLeaf ){ |
| 302 | - @ updated by %z(href("%R/forumthread/%S?t",p->pLeaf->zUuid))\ | |
| 302 | + @ updated by %z(href("%R/forumpost/%S?t",p->pLeaf->zUuid))\ | |
| 303 | 303 | @ %d(p->pLeaf->fpid)</a> |
| 304 | 304 | } |
| 305 | 305 | if( g.perm.Debug ){ |
| 306 | 306 | @ <span class="debug">\ |
| 307 | 307 | @ <a href="%R/artifact/%h(p->zUuid)">artifact</a></span> |
| 308 | 308 | } |
| 309 | 309 | if( p->fpid!=target ){ |
| 310 | - @ %z(href("%R/forumthread/%S?t",p->zUuid))[link]</a> | |
| 310 | + @ %z(href("%R/forumpost/%S?t",p->zUuid))[link]</a> | |
| 311 | 311 | } |
| 312 | 312 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 313 | 313 | if( g.perm.WrForum && p->pLeaf==0 ){ |
| 314 | 314 | int sameUser = login_is_individual() |
| 315 | 315 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| @@ -405,11 +405,11 @@ | ||
| 405 | 405 | @ <a href="%R/artifact/%h(p->pLeaf->zUuid)">(%d(fpid))</a></span> |
| 406 | 406 | } |
| 407 | 407 | manifest_destroy(pOPost); |
| 408 | 408 | } |
| 409 | 409 | if( fpid!=target ){ |
| 410 | - @ %z(href("%R/forumthread/%S",zUuid))[link]</a> | |
| 410 | + @ %z(href("%R/forumpost/%S",zUuid))[link]</a> | |
| 411 | 411 | } |
| 412 | 412 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 413 | 413 | if( g.perm.WrForum ){ |
| 414 | 414 | int sameUser = login_is_individual() |
| 415 | 415 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| @@ -440,19 +440,38 @@ | ||
| 440 | 440 | @ </div> |
| 441 | 441 | } |
| 442 | 442 | forumthread_delete(pThread); |
| 443 | 443 | return target; |
| 444 | 444 | } |
| 445 | + | |
| 446 | +/* | |
| 447 | +** WEBPAGE: forumpost | |
| 448 | +** | |
| 449 | +** Show a single forum posting. The posting is shown in context with | |
| 450 | +** it's entire thread. The selected posting is enclosed within | |
| 451 | +** <div class='forumSel'>...</div>. Javascript is used to move the | |
| 452 | +** selected posting into view after the page loads. | |
| 453 | +** | |
| 454 | +** Query parameters: | |
| 455 | +** | |
| 456 | +** name=X REQUIRED. The hash of the post to display | |
| 457 | +** t Show a chronologic listing instead of hierarchical | |
| 458 | +*/ | |
| 459 | +void forumpost_page(void){ | |
| 460 | + forumthread_page(); | |
| 461 | +} | |
| 445 | 462 | |
| 446 | 463 | /* |
| 447 | 464 | ** WEBPAGE: forumthread |
| 448 | 465 | ** |
| 449 | 466 | ** Show all forum messages associated with a particular message thread. |
| 467 | +** The result is basically the same as /forumpost except that none of | |
| 468 | +** the postings in the thread are selected. | |
| 450 | 469 | ** |
| 451 | 470 | ** Query parameters: |
| 452 | 471 | ** |
| 453 | -** name=X The hash of the first post of the thread. REQUIRED | |
| 472 | +** name=X REQUIRED. The hash of any post of the thread. | |
| 454 | 473 | ** t Show a chronologic listing instead of hierarchical |
| 455 | 474 | */ |
| 456 | 475 | void forumthread_page(void){ |
| 457 | 476 | int fpid; |
| 458 | 477 | int froot; |
| @@ -472,18 +491,19 @@ | ||
| 472 | 491 | style_header("Forum"); |
| 473 | 492 | froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid); |
| 474 | 493 | if( froot==0 ){ |
| 475 | 494 | webpage_error("Not a forum post: \"%s\"", zName); |
| 476 | 495 | } |
| 496 | + if( fossil_strcmp(g.zPath,"forumthread")==0 ) fpid = 0; | |
| 477 | 497 | if( P("t") ){ |
| 478 | 498 | if( g.perm.Debug ){ |
| 479 | - style_submenu_element("Hierarchical", "%R/forumthread/%s", zName); | |
| 499 | + style_submenu_element("Hierarchical", "%R/%s/%s", g.zPath, zName); | |
| 480 | 500 | } |
| 481 | 501 | forum_display_chronological(froot, fpid); |
| 482 | 502 | }else{ |
| 483 | 503 | if( g.perm.Debug ){ |
| 484 | - style_submenu_element("Chronological", "%R/forumthread/%s?t", zName); | |
| 504 | + style_submenu_element("Chronological", "%R/%s/%s?t", g.zPath, zName); | |
| 485 | 505 | } |
| 486 | 506 | forum_display_hierarchical(froot, fpid); |
| 487 | 507 | } |
| 488 | 508 | style_load_js("forum.js"); |
| 489 | 509 | style_footer(); |
| @@ -587,11 +607,11 @@ | ||
| 587 | 607 | @ </div> |
| 588 | 608 | blob_reset(&x); |
| 589 | 609 | return 0; |
| 590 | 610 | }else{ |
| 591 | 611 | int nrid = wiki_put(&x, 0, forum_need_moderation()); |
| 592 | - cgi_redirectf("%R/forumthread/%S", rid_to_uuid(nrid)); | |
| 612 | + cgi_redirectf("%R/forumpost/%S", rid_to_uuid(nrid)); | |
| 593 | 613 | return 1; |
| 594 | 614 | } |
| 595 | 615 | } |
| 596 | 616 | |
| 597 | 617 | /* |
| @@ -681,23 +701,23 @@ | ||
| 681 | 701 | fpid = symbolic_name_to_rid(PD("fpid",""), "f"); |
| 682 | 702 | if( fpid<=0 || (pPost = manifest_get(fpid, CFTYPE_FORUM, 0))==0 ){ |
| 683 | 703 | webpage_error("Missing or invalid fpid query parameter"); |
| 684 | 704 | } |
| 685 | 705 | if( P("cancel") ){ |
| 686 | - cgi_redirectf("%R/forumthread/%S",P("fpid")); | |
| 706 | + cgi_redirectf("%R/forumpost/%S",P("fpid")); | |
| 687 | 707 | return; |
| 688 | 708 | } |
| 689 | 709 | isCsrfSafe = cgi_csrf_safe(1); |
| 690 | 710 | if( g.perm.ModForum && isCsrfSafe ){ |
| 691 | 711 | if( P("approve") ){ |
| 692 | 712 | moderation_approve(fpid); |
| 693 | - cgi_redirectf("%R/forumthread/%S",P("fpid")); | |
| 713 | + cgi_redirectf("%R/forumpost/%S",P("fpid")); | |
| 694 | 714 | return; |
| 695 | 715 | } |
| 696 | 716 | if( P("reject") ){ |
| 697 | 717 | moderation_disapprove(fpid); |
| 698 | - cgi_redirectf("%R/forumthread/%S",P("fpid")); | |
| 718 | + cgi_redirectf("%R/forumpost/%S",P("fpid")); | |
| 699 | 719 | return; |
| 700 | 720 | } |
| 701 | 721 | } |
| 702 | 722 | isDelete = P("nullout")!=0; |
| 703 | 723 | if( P("submit") && isCsrfSafe ){ |
| 704 | 724 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -287,29 +287,29 @@ | |
| 287 | } |
| 288 | zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate); |
| 289 | @ <p>By %h(pPost->zUser) on %h(zDate) (%d(p->fpid)) |
| 290 | fossil_free(zDate); |
| 291 | if( p->pEdit ){ |
| 292 | @ edit of %z(href("%R/forumthread/%S?t",p->pEdit->zUuid))%d(p->fprev)</a> |
| 293 | } |
| 294 | if( p->firt ){ |
| 295 | ForumEntry *pIrt = p->pPrev; |
| 296 | while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; |
| 297 | if( pIrt ){ |
| 298 | @ reply to %z(href("%R/forumthread/%S?t",pIrt->zUuid))%d(p->firt)</a> |
| 299 | } |
| 300 | } |
| 301 | if( p->pLeaf ){ |
| 302 | @ updated by %z(href("%R/forumthread/%S?t",p->pLeaf->zUuid))\ |
| 303 | @ %d(p->pLeaf->fpid)</a> |
| 304 | } |
| 305 | if( g.perm.Debug ){ |
| 306 | @ <span class="debug">\ |
| 307 | @ <a href="%R/artifact/%h(p->zUuid)">artifact</a></span> |
| 308 | } |
| 309 | if( p->fpid!=target ){ |
| 310 | @ %z(href("%R/forumthread/%S?t",p->zUuid))[link]</a> |
| 311 | } |
| 312 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 313 | if( g.perm.WrForum && p->pLeaf==0 ){ |
| 314 | int sameUser = login_is_individual() |
| 315 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| @@ -405,11 +405,11 @@ | |
| 405 | @ <a href="%R/artifact/%h(p->pLeaf->zUuid)">(%d(fpid))</a></span> |
| 406 | } |
| 407 | manifest_destroy(pOPost); |
| 408 | } |
| 409 | if( fpid!=target ){ |
| 410 | @ %z(href("%R/forumthread/%S",zUuid))[link]</a> |
| 411 | } |
| 412 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 413 | if( g.perm.WrForum ){ |
| 414 | int sameUser = login_is_individual() |
| 415 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| @@ -440,19 +440,38 @@ | |
| 440 | @ </div> |
| 441 | } |
| 442 | forumthread_delete(pThread); |
| 443 | return target; |
| 444 | } |
| 445 | |
| 446 | /* |
| 447 | ** WEBPAGE: forumthread |
| 448 | ** |
| 449 | ** Show all forum messages associated with a particular message thread. |
| 450 | ** |
| 451 | ** Query parameters: |
| 452 | ** |
| 453 | ** name=X The hash of the first post of the thread. REQUIRED |
| 454 | ** t Show a chronologic listing instead of hierarchical |
| 455 | */ |
| 456 | void forumthread_page(void){ |
| 457 | int fpid; |
| 458 | int froot; |
| @@ -472,18 +491,19 @@ | |
| 472 | style_header("Forum"); |
| 473 | froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid); |
| 474 | if( froot==0 ){ |
| 475 | webpage_error("Not a forum post: \"%s\"", zName); |
| 476 | } |
| 477 | if( P("t") ){ |
| 478 | if( g.perm.Debug ){ |
| 479 | style_submenu_element("Hierarchical", "%R/forumthread/%s", zName); |
| 480 | } |
| 481 | forum_display_chronological(froot, fpid); |
| 482 | }else{ |
| 483 | if( g.perm.Debug ){ |
| 484 | style_submenu_element("Chronological", "%R/forumthread/%s?t", zName); |
| 485 | } |
| 486 | forum_display_hierarchical(froot, fpid); |
| 487 | } |
| 488 | style_load_js("forum.js"); |
| 489 | style_footer(); |
| @@ -587,11 +607,11 @@ | |
| 587 | @ </div> |
| 588 | blob_reset(&x); |
| 589 | return 0; |
| 590 | }else{ |
| 591 | int nrid = wiki_put(&x, 0, forum_need_moderation()); |
| 592 | cgi_redirectf("%R/forumthread/%S", rid_to_uuid(nrid)); |
| 593 | return 1; |
| 594 | } |
| 595 | } |
| 596 | |
| 597 | /* |
| @@ -681,23 +701,23 @@ | |
| 681 | fpid = symbolic_name_to_rid(PD("fpid",""), "f"); |
| 682 | if( fpid<=0 || (pPost = manifest_get(fpid, CFTYPE_FORUM, 0))==0 ){ |
| 683 | webpage_error("Missing or invalid fpid query parameter"); |
| 684 | } |
| 685 | if( P("cancel") ){ |
| 686 | cgi_redirectf("%R/forumthread/%S",P("fpid")); |
| 687 | return; |
| 688 | } |
| 689 | isCsrfSafe = cgi_csrf_safe(1); |
| 690 | if( g.perm.ModForum && isCsrfSafe ){ |
| 691 | if( P("approve") ){ |
| 692 | moderation_approve(fpid); |
| 693 | cgi_redirectf("%R/forumthread/%S",P("fpid")); |
| 694 | return; |
| 695 | } |
| 696 | if( P("reject") ){ |
| 697 | moderation_disapprove(fpid); |
| 698 | cgi_redirectf("%R/forumthread/%S",P("fpid")); |
| 699 | return; |
| 700 | } |
| 701 | } |
| 702 | isDelete = P("nullout")!=0; |
| 703 | if( P("submit") && isCsrfSafe ){ |
| 704 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -287,29 +287,29 @@ | |
| 287 | } |
| 288 | zDate = db_text(0, "SELECT datetime(%.17g)", pPost->rDate); |
| 289 | @ <p>By %h(pPost->zUser) on %h(zDate) (%d(p->fpid)) |
| 290 | fossil_free(zDate); |
| 291 | if( p->pEdit ){ |
| 292 | @ edit of %z(href("%R/forumpost/%S?t",p->pEdit->zUuid))%d(p->fprev)</a> |
| 293 | } |
| 294 | if( p->firt ){ |
| 295 | ForumEntry *pIrt = p->pPrev; |
| 296 | while( pIrt && pIrt->fpid!=p->firt ) pIrt = pIrt->pPrev; |
| 297 | if( pIrt ){ |
| 298 | @ reply to %z(href("%R/forumpost/%S?t",pIrt->zUuid))%d(p->firt)</a> |
| 299 | } |
| 300 | } |
| 301 | if( p->pLeaf ){ |
| 302 | @ updated by %z(href("%R/forumpost/%S?t",p->pLeaf->zUuid))\ |
| 303 | @ %d(p->pLeaf->fpid)</a> |
| 304 | } |
| 305 | if( g.perm.Debug ){ |
| 306 | @ <span class="debug">\ |
| 307 | @ <a href="%R/artifact/%h(p->zUuid)">artifact</a></span> |
| 308 | } |
| 309 | if( p->fpid!=target ){ |
| 310 | @ %z(href("%R/forumpost/%S?t",p->zUuid))[link]</a> |
| 311 | } |
| 312 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 313 | if( g.perm.WrForum && p->pLeaf==0 ){ |
| 314 | int sameUser = login_is_individual() |
| 315 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| @@ -405,11 +405,11 @@ | |
| 405 | @ <a href="%R/artifact/%h(p->pLeaf->zUuid)">(%d(fpid))</a></span> |
| 406 | } |
| 407 | manifest_destroy(pOPost); |
| 408 | } |
| 409 | if( fpid!=target ){ |
| 410 | @ %z(href("%R/forumpost/%S",zUuid))[link]</a> |
| 411 | } |
| 412 | forum_render(0, pPost->zMimetype, pPost->zWiki, 0); |
| 413 | if( g.perm.WrForum ){ |
| 414 | int sameUser = login_is_individual() |
| 415 | && fossil_strcmp(pPost->zUser, g.zLogin)==0; |
| @@ -440,19 +440,38 @@ | |
| 440 | @ </div> |
| 441 | } |
| 442 | forumthread_delete(pThread); |
| 443 | return target; |
| 444 | } |
| 445 | |
| 446 | /* |
| 447 | ** WEBPAGE: forumpost |
| 448 | ** |
| 449 | ** Show a single forum posting. The posting is shown in context with |
| 450 | ** it's entire thread. The selected posting is enclosed within |
| 451 | ** <div class='forumSel'>...</div>. Javascript is used to move the |
| 452 | ** selected posting into view after the page loads. |
| 453 | ** |
| 454 | ** Query parameters: |
| 455 | ** |
| 456 | ** name=X REQUIRED. The hash of the post to display |
| 457 | ** t Show a chronologic listing instead of hierarchical |
| 458 | */ |
| 459 | void forumpost_page(void){ |
| 460 | forumthread_page(); |
| 461 | } |
| 462 | |
| 463 | /* |
| 464 | ** WEBPAGE: forumthread |
| 465 | ** |
| 466 | ** Show all forum messages associated with a particular message thread. |
| 467 | ** The result is basically the same as /forumpost except that none of |
| 468 | ** the postings in the thread are selected. |
| 469 | ** |
| 470 | ** Query parameters: |
| 471 | ** |
| 472 | ** name=X REQUIRED. The hash of any post of the thread. |
| 473 | ** t Show a chronologic listing instead of hierarchical |
| 474 | */ |
| 475 | void forumthread_page(void){ |
| 476 | int fpid; |
| 477 | int froot; |
| @@ -472,18 +491,19 @@ | |
| 491 | style_header("Forum"); |
| 492 | froot = db_int(0, "SELECT froot FROM forumpost WHERE fpid=%d", fpid); |
| 493 | if( froot==0 ){ |
| 494 | webpage_error("Not a forum post: \"%s\"", zName); |
| 495 | } |
| 496 | if( fossil_strcmp(g.zPath,"forumthread")==0 ) fpid = 0; |
| 497 | if( P("t") ){ |
| 498 | if( g.perm.Debug ){ |
| 499 | style_submenu_element("Hierarchical", "%R/%s/%s", g.zPath, zName); |
| 500 | } |
| 501 | forum_display_chronological(froot, fpid); |
| 502 | }else{ |
| 503 | if( g.perm.Debug ){ |
| 504 | style_submenu_element("Chronological", "%R/%s/%s?t", g.zPath, zName); |
| 505 | } |
| 506 | forum_display_hierarchical(froot, fpid); |
| 507 | } |
| 508 | style_load_js("forum.js"); |
| 509 | style_footer(); |
| @@ -587,11 +607,11 @@ | |
| 607 | @ </div> |
| 608 | blob_reset(&x); |
| 609 | return 0; |
| 610 | }else{ |
| 611 | int nrid = wiki_put(&x, 0, forum_need_moderation()); |
| 612 | cgi_redirectf("%R/forumpost/%S", rid_to_uuid(nrid)); |
| 613 | return 1; |
| 614 | } |
| 615 | } |
| 616 | |
| 617 | /* |
| @@ -681,23 +701,23 @@ | |
| 701 | fpid = symbolic_name_to_rid(PD("fpid",""), "f"); |
| 702 | if( fpid<=0 || (pPost = manifest_get(fpid, CFTYPE_FORUM, 0))==0 ){ |
| 703 | webpage_error("Missing or invalid fpid query parameter"); |
| 704 | } |
| 705 | if( P("cancel") ){ |
| 706 | cgi_redirectf("%R/forumpost/%S",P("fpid")); |
| 707 | return; |
| 708 | } |
| 709 | isCsrfSafe = cgi_csrf_safe(1); |
| 710 | if( g.perm.ModForum && isCsrfSafe ){ |
| 711 | if( P("approve") ){ |
| 712 | moderation_approve(fpid); |
| 713 | cgi_redirectf("%R/forumpost/%S",P("fpid")); |
| 714 | return; |
| 715 | } |
| 716 | if( P("reject") ){ |
| 717 | moderation_disapprove(fpid); |
| 718 | cgi_redirectf("%R/forumpost/%S",P("fpid")); |
| 719 | return; |
| 720 | } |
| 721 | } |
| 722 | isDelete = P("nullout")!=0; |
| 723 | if( P("submit") && isCsrfSafe ){ |
| 724 |