home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / FAQ / discus_admin_1357211388 / source / adm-page.pl < prev    next >
Text File  |  2009-11-06  |  39KB  |  1,104 lines

  1. # FILE: adm-page.pl
  2. # DESCRIPTION: Page Management
  3. #-------------------------------------------------------------------------------
  4. # DISCUS COPYRIGHT NOTICE
  5. #
  6. # Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
  7. # The use of Discus is governed by the Discus License Agreement which is
  8. # available from the Discus WWW site at:
  9. #    http://www.discusware.com/discus/license
  10. #
  11. # Pursuant to the Discus License Agreement, this copyright notice may not be
  12. # removed or altered in any way.
  13. #-------------------------------------------------------------------------------
  14.  
  15. use strict;
  16. use vars qw($GLOBAL_OPTIONS $DCONF $PARAMS);
  17.  
  18. ###
  19. ### PAGE_admin
  20. ###
  21. ### Controls the Page Manager
  22. ###
  23.  
  24. sub PAGE_admin {
  25.     my ($FORMref) = @_;
  26.     my $result = check_password($FORMref->{username}, undef, { type_required => 'moderator' }, $FORMref->{'COOKIE'});
  27.     bad_login({ username => 1 }) if ! scalar(@{ $result });
  28.     page_mgr_1($FORMref->{'username'}, 0) if ($FORMref->{'action'} eq "pm-mgr_1");
  29.     page_locater_tree($FORMref, $result) if $FORMref->{action} eq "pm-pgtree";
  30.     my ($topic, $page);
  31.     if ($FORMref->{topic}) {
  32.         $topic = $FORMref->{topic}; $page = $FORMref->{page};
  33.     } else {
  34.         $FORMref->{HTTP_REFERER} =~ /(\d+)\/(\d+)/;
  35.         ($topic, $page) = ($1, $2);
  36.     }
  37.     dreq("fcn-priv");
  38.     bad_login({ privilege => 1 }) if ! check_topic_authorization($result->[0]->{user}, $topic, undef);
  39.     page_handle_announcement($FORMref) if $FORMref->{'action'} eq "pm-announce_message";
  40.     page_handle_about($FORMref) if $FORMref->{'action'} eq "pm-about_message";
  41.     page_handle_layout($FORMref) if $FORMref->{'action'} eq "pm-change_layout";
  42.     page_handle_edit($FORMref) if $FORMref->{action} eq "pm-edit_post";
  43.     page_handle_message_properties($FORMref) if $FORMref->{action} eq "pm-prop_edit";
  44.     page_change_link_properties($FORMref) if $FORMref->{action} eq "pm-link_props";
  45.     page_change_subtopic_properties($FORMref) if $FORMref->{action} eq "pm-subtopic_props";
  46.     page_change_subtopic_meta($FORMref) if $FORMref->{action} eq "pm-subtopic_meta";
  47.     page_rename_subtopic($FORMref) if $FORMref->{action} eq "pm-subtopic_rename";
  48.     page_move_items($FORMref, $result, $1) if $FORMref->{action} =~ /^pm-move([12])$/;
  49.     if ($FORMref->{action} eq "pm-open_closer") {
  50.         dreq("fcn-msg-PRO");
  51.         open_close_mgr($FORMref, $result);
  52.     }
  53.     if ($FORMref->{'action'} eq "pm-add_subtopic") {
  54.         dreq("fcn-pgad"); page_mgr_add_subtopic($FORMref);
  55.     }
  56.     if ($FORMref->{'action'} eq "pm-page_editor") {
  57.         page_mgr_navigate($FORMref) if $FORMref->{menu} == 0;
  58.         page_mgr_announcement($FORMref) if $FORMref->{menu} == 1;
  59.         page_mgr_sublist($FORMref) if $FORMref->{menu} == 2;
  60.         page_mgr_about($FORMref) if $FORMref->{menu} == 3;
  61.         page_mgr_message($FORMref) if $FORMref->{menu} == 4;
  62.         page_mgr_print( page_mgr_general($FORMref) ) if $FORMref->{menu} == 5;
  63.         page_mgr_print( page_mgr_general($FORMref) ) if $FORMref->{menu} == 6;
  64.     }
  65.     if ($FORMref->{action} eq "pm-subtopics") {
  66.         my $code = page_mgr_subtopic_management($FORMref);
  67.         page_mgr_sublist($FORMref, undef, { what => $code });
  68.     }
  69.     if ($FORMref->{action} eq "pm-messages") {
  70.         my $code = page_mgr_message_management($FORMref->{SELECTION_action}, $FORMref->{SELECTION_who}, $FORMref);
  71.         page_mgr_message($FORMref, undef, { what => $code });
  72.     }
  73. }
  74.  
  75. ###
  76. ### page_move_items
  77. ###
  78. ### Move message(s) or subtopic(s) from one page to another
  79. ###
  80.  
  81. sub page_move_items {
  82.     my ($FORMref, $result, $type) = @_;
  83.     my $arg = {};
  84.     ($arg->{topic}, $arg->{page}) = split(/\//, $FORMref->{HTTP_REFERER});
  85.     if ($FORMref->{dest_topic} != 0) {
  86.         dreq("fcn-priv");
  87.         my $ca = check_topic_authorization($result->[0]->{user}, $FORMref->{dest_topic}, undef);
  88.         error_message("Illegal Destination", "You do not have permission to move items into the selected topic!", 0, 1) if ! $ca;
  89.         $arg->{new_topic} = $FORMref->{dest_topic};
  90.         $arg->{new_page} = $FORMref->{dest_page};
  91.     } elsif ($FORMref->{subtopic_name} =~ /\S/) {
  92.         $arg->{new_topic} = $arg->{topic};
  93.         $arg->{new_conversation} = 1;
  94.         $arg->{create_new_page} = 1;
  95.         dreq("webtags");
  96.         my ($lint, $name) = webtags($FORMref->{subtopic_name}, 3, 1, 1, $DCONF->{superuser} eq $result->[0]->{user} ? 1 : 0);
  97.         error_message("Illegal Destination", $name, 0, 1) if $lint eq "!Error";
  98.         $arg->{create_new_page_name} = $name;
  99.     } else {
  100.         error_message("Illegal Destination", "You must either enter a topic/page combination or a valid subtopic name as a destination!", 0, 1);
  101.     }
  102.     $arg->{pages_upward_update} = 1;
  103.     if ($type == 1) {
  104.         $arg->{messages} = $FORMref->{string};
  105.         $arg->{type} = 2;
  106.         dreq("fcn-msmv");
  107.         move_message($arg);
  108.         if ($FORMref->{quick}) {
  109.             my $subst = {};
  110.             $subst->{general}->{new_url} = "$DCONF->{authorize_reader}?file=/$arg->{topic}/$arg->{page}.$DCONF->{ext}";
  111.             $subst->{general}->{screen} = -1;
  112.             screen_out("quickadm", $subst);
  113.         }
  114.         page_mgr_message($FORMref);
  115.     } else {
  116.         my @z = split(/,/, $FORMref->{string});
  117.         my %argmove = map { $_, 1 } @z;
  118.         $arg->{move} = \%argmove;
  119.         dreq("fcn-pgmv");
  120.         move_page($arg, undef, undef, undef, $result->[0]->{user});
  121.         $FORMref->{menu} = 2;
  122.         if ($FORMref->{quick}) {
  123.             my $subst = {};
  124.             $subst->{general}->{new_url} = "$DCONF->{authorize_reader}?file=/$arg->{topic}/$arg->{page}.$DCONF->{ext}";
  125.             $subst->{general}->{screen} = -1;
  126.             screen_out("quickadm", $subst);
  127.         }
  128.         page_mgr_sublist($FORMref);
  129.     }
  130. }
  131.  
  132. ###
  133. ### page_locater_tree
  134. ###
  135. ### Pop-up window to locate the desired destination for your message or page
  136. ###
  137.  
  138. sub page_locater_tree {
  139.     my ($FORMref, $result) = @_;
  140.     my $topic = defined $FORMref->{t} ? $FORMref->{t} : $FORMref->{topic};
  141.     my $page = $FORMref->{m};
  142.     my $cutoff = $FORMref->{x};
  143.     my $username = $result->[0]->{user};
  144.     my $nochildren = $FORMref->{ty} =~ /2$/ ? 1 : 0;
  145.     dreq("fcn-priv", "fcn-tree");
  146.     my $privcache = read_privilege_file();
  147.     my @t = grep ($_->{type} == 1 && check_topic_authorization($username, $_->{number}, $privcache), @{board_topics()});
  148.     error_message("Unauthorized Entry", "You are not permitted to move into the selected topic", 0, 1) if $topic && ! check_topic_authorization($username, $topic, $privcache);
  149.     my $tree = read_tree($topic, { no_lock => 1, no_unlock => 1 });
  150.     my $cat = tree_categorize($tree);
  151.     my $parents = tree_build_parents_of($tree, $cat, $page);
  152.     my @bb = (); my @tt = ();
  153.     my %pl = map { $_, 1 } @{$parents};
  154.     $pl{$page} = 1;
  155.     foreach my $l (@t) {
  156.         if ($l->{number} == $topic) {
  157.             @bb = grep($pl{$_->{parent}} == 1, @{$tree});
  158.             push @tt, $l;
  159.         } else {
  160.             $l->{topic} = $l->{number};
  161.             $l->{page} = $l->{number};
  162.             push @tt, $l;
  163.         }
  164.     }
  165.     my %cl = {};
  166.     foreach my $co (split(/,/, $cutoff)) {
  167.         my $cutpar = tree_build_children_of($tree, $cat, $co);
  168.         my @cutarr = tree_dump_into_array($cutpar);
  169.         my %cl2 = map { $_->{page}, $nochildren } @cutarr;
  170.         $cl2{$co} = $nochildren;
  171.         foreach my $key (keys(%cl2)) {
  172.             $cl{$key} = $cl2{$key};
  173.         }
  174.     }
  175.     foreach my $bb (@bb) {
  176.         $bb->{'open'} = 0 + $pl{$bb->{page}};
  177.         $bb->{'unavail'} = 0 + $cl{$bb->{page}};
  178.         $bb->{'unavail'} = 1 if $bb->{islink};
  179.     }
  180.     my $subst = {};
  181.     $subst->{topic_tree} = \@tt;
  182.     $subst->{subtopic_tree} = \@bb;
  183.     $subst->{general}->{username} = $result->[0]->{user};
  184.     $subst->{general}->{cutoff} = $cutoff;
  185.     $DCONF->{html_url} =~ m%^(https?://.*?)(/|$)%; my $html_server = $1; my $html_after = join("", $2, $');
  186.     $DCONF->{message_url} =~ m%^(https?://.*?)(/|$)%; my $message_server = $1; my $message_after = join("", $2, $');
  187.     $DCONF->{script_url} =~ m%^(https?://.*?)(/|$)%; my $script_server = $1; my $script_after = join("", $2, $');
  188.     if ($script_server eq $html_server) {
  189.         $subst->{general}->{icon_url} = join("/", $html_after, $DCONF->{icon_dir});
  190.         $subst->{general}->{script_url} = $script_after;
  191.     } else {
  192.         $subst->{general}->{icon_url} = join("/", $DCONF->{html_url}, $DCONF->{icon_dir});
  193.         $subst->{general}->{script_url} = $DCONF->{script_url};
  194.     }
  195.     $subst->{general}->{topic_open} = $topic;
  196.     $subst->{general}->{type} = $FORMref->{ty};
  197.     undef my $pz;
  198.     foreach my $y (@{ $subst->{subtopic_tree} }) {
  199.         $pz->{ $y->{parent} } = $y->{page};
  200.     }
  201.     foreach my $yy (@{ $subst->{subtopic_tree} }) {
  202.         $yy->{last_of_parent} = 1 if $pz->{ $yy->{parent} } == $yy->{page};
  203.     }
  204.     screen_out("locater", $subst);
  205. }
  206.  
  207. ###
  208. ### page_handle_announcement
  209. ###
  210. ### For previewing and saving of the Announcement Message
  211. ###
  212.  
  213. sub page_handle_announcement {
  214.     my ($FORMref) = @_;
  215.     dreq("adm-msgs", "webtags");
  216.     if ($FORMref->{HTTP_REFERER} !~ m|(\d+)/(\d+)|) {
  217.         error_message("Announcement/About Error", "HTTP referer could not be parsed", 0, 1);
  218.     }
  219.     my $topic = $1; my $page = $2;
  220.     my $msg = $FORMref->{'message'}; $msg =~ s/^\s+//; $msg =~ s/\s+$//;
  221.     my ($lint_subj, $new_message) = webtags($msg, 1, 1, 1, $FORMref->{'username'} eq $DCONF->{'superuser'} ? 1 : 0, $topic);
  222.     if ($FORMref->{preview} == 1 || $lint_subj eq "!Error") {
  223.         preview_admin_message($msg, $new_message, 0, $FORMref);
  224.     } else {
  225.         my $file = set_announce_message({ topic => $topic, page => $page, message => $new_message });
  226.         page_mgr_announcement($FORMref, $file);
  227.     }
  228. }
  229.  
  230. ###
  231. ### page_handle_about
  232. ###
  233. ### For previewing and saving of the About Message
  234. ###
  235.  
  236. sub page_handle_about {
  237.     my ($FORMref) = @_;
  238.     dreq("adm-msgs", "webtags");
  239.     if ($FORMref->{HTTP_REFERER} !~ m|(\d+)/(\d+)|) {
  240.         error_message("Announcement/About Error", "HTTP referer could not be parsed", 0, 1);
  241.     }
  242.     my $topic = $1; my $page = $2;
  243.     my $msg = $FORMref->{'message'}; $msg =~ s/^\s+//; $msg =~ s/\s+$//;
  244.     my ($lint_subj, $new_message) = webtags($msg, 1, 1, 1, $FORMref->{'username'} eq $DCONF->{'superuser'} ? 1 : 0, $topic);
  245.     if ($FORMref->{preview} == 1 || $lint_subj eq "!Error") {
  246.         preview_admin_message($msg, $new_message, 1, $FORMref);
  247.     } else {
  248.         my $file = set_about_message({ topic => $topic, page => $page, message => $new_message });
  249.         page_mgr_about($FORMref, $file);
  250.     }
  251. }
  252.  
  253. ###
  254. ### page_handle_layout
  255. ###
  256. ### For changing the page layout
  257. ###
  258.  
  259. sub page_handle_layout {
  260.     my ($FORMref) = @_;
  261.     error_message("Invalid Topic/Page Combination!", "", 0, 1) if $FORMref->{HTTP_REFERER} !~ m|(\d+)/(\d+)|;
  262.     my ($topic, $page) = ($1, $2);
  263.     my $new_layout = "";
  264.     $new_layout .= "Announce" if $FORMref->{element6} eq "on";
  265.     $new_layout .= "Sublist" if $FORMref->{element1} eq "on";
  266.     $new_layout .= "Create" if $FORMref->{element2} eq "on";
  267.     $new_layout .= "About" if $FORMref->{element3} eq "on";
  268.     $new_layout .= "Messages" if $FORMref->{element4} eq "on";
  269.     $new_layout .= "Add" if $FORMref->{element5} eq "on";
  270.     $new_layout .= "Archive" if $FORMref->{element7} eq "on";
  271.     dreq("fcn-pg_m");
  272.     page_mgr_print( page_mgr_general($FORMref, change_page_layout({ topic => $topic, page => $page, layout => $new_layout })->{file}));
  273. }
  274.  
  275. ###
  276. ### page_handle_edit
  277. ###
  278. ### For editing a post through Page Manager
  279. ###
  280.  
  281. sub page_handle_edit {
  282.     my ($FORMref) = @_;
  283.     dreq("fcn-edit");
  284.     my $arg = {};
  285.     my $postid = $FORMref->{post};
  286.     my $topic = $FORMref->{topic};
  287.     my $page = $FORMref->{page};
  288.     $arg->{username} = $FORMref->{username};
  289.     $arg->{skip_nav_bar} = 1;
  290.     $arg->{is_moderator} = 1;
  291.     $arg->{is_superuser} = 1 if $FORMref->{username} eq $DCONF->{superuser};
  292.     $arg->{escape_url} = "$PARAMS->{cgiurl}?username=$FORMref->{username}&action=pm-page_editor&HTTP_REFERER=/$topic/$page&menu=4";
  293.     $arg->{formaction} = "pm-edit_post";
  294.     $arg->{text} = $FORMref->{message};
  295.     if ($FORMref->{preview} == 0) {
  296.         save_edited_post($topic, $page, $postid, $arg->{text}, $arg);
  297.         seturl($arg->{escape_url});
  298.     }
  299.     edit_post_form($topic, $page, $postid, $arg);
  300. }
  301.  
  302. ###
  303. ### page_handle_message_properties
  304. ###
  305. ### For setting message properties through Page Manager
  306. ###
  307.  
  308. sub page_handle_message_properties {
  309.     my ($FORMref) = @_;
  310.     my %p = {}; my %d = {};
  311.     foreach my $d (split(/,/, $FORMref->{prop_del})) { $d{$d} = 1; }
  312.     my $ctr = 0;
  313.     foreach my $m (split(/,/, $FORMref->{prop_list})) {
  314.         $ctr++;
  315.         next if $d{$m};
  316.         my $v = $FORMref->{"prop_val_$ctr"};
  317.         $p{"property_$m"} = $v;
  318.     }
  319.     if ($FORMref->{prop_new_name} =~ /\S/ && $FORMref->{prop_new_val} =~ /\S/) {
  320.         my $n = $FORMref->{prop_new_name}; $n =~ s/\W//g;
  321.         $p{"property_$n"} = trim($FORMref->{prop_new_val});
  322.     }
  323.     my $gp = GetPage($FORMref->{topic}, $FORMref->{page}, { lock => 1 });
  324.     foreach my $m (@{ $gp->{messages} }) {
  325.         if ($m->{number} == $FORMref->{post}) {
  326.             my %u = %{ $m };
  327.             foreach my $k (keys(%u)) {
  328.                 delete $u{$k} if $k =~ /^property_/;
  329.             }
  330.             foreach my $k (keys(%p)) {
  331.                 $u{$k} = $p{$k};
  332.             }
  333.             $m = \%u;
  334.         }
  335.     }
  336.     $gp->{general}->{messages_raw} = 0;
  337.     SetPage($gp, { unlock => 1 });
  338.     $FORMref->{action} = "pm-messages";
  339.     $FORMref->{HTTP_REFERER} = join("/", $FORMref->{topic}, $FORMref->{page});
  340.     page_mgr_message_management("p", $FORMref->{post}, $FORMref);
  341. }
  342.  
  343.  
  344.  
  345. ###
  346. ### page_mgr_subtopic_management
  347. ###
  348. ### Handles requests from Subtopics screen
  349. ###
  350.  
  351. sub page_mgr_subtopic_management {
  352.     my ($FORMref) = @_;
  353.     my $action = $FORMref->{SELECTION_action};
  354.     my $who = $FORMref->{SELECTION_who};
  355.     my $string = "[dpm]";
  356.     if ($action =~ m%^($string)$%) {
  357.         my $command = $1;
  358.         my $target = $who;
  359.         my $td = {};
  360.         if ($FORMref->{markall}) {
  361.             foreach my $y (split(/,/, $FORMref->{mark_all_string})) {
  362.                 $td->{$y} = 1;
  363.             }
  364.         } elsif ($who eq "all" || $who eq '*') {
  365.             foreach my $y (split(/,/, $FORMref->{MARK})) {
  366.                 $td->{$y} = 1;
  367.             }
  368.         } else {
  369.             $td->{$target} = 1;
  370.         }
  371.         if ($action eq "d") {
  372.             error_message("Delete Subtopics Error", "No subtopics were selected for deletion!", 0, 1) if scalar(keys(%{$td})) == 0;
  373.             dreq("fcn-pgdl");
  374.             my ($topic, $page) = split(/\//, $FORMref->{HTTP_REFERER});
  375.             remove_page({ topic => $topic, page => $page, remove => $td });
  376.             return 1;
  377.         }
  378.         if ($action eq "p") {
  379.             my $fr = $FORMref;
  380.             ($fr->{topic}, $fr->{page}) = split(/\//, $FORMref->{HTTP_REFERER});
  381.             my $P = GetPage($fr->{topic}, $fr->{page}, { no_lock => 1, no_unlock => 1 });
  382.             my $i = first_grep(sub { $_[0]->{page} == $who }, read_tree($fr->{topic}));
  383.             error_message("Edit properties error", "No data found for page '$who' in tree file.  Board administrator should reindex the board through Data Recovery.", 0, 1) if ! defined $i;
  384.             my $j = first_grep(sub { $_[0]->{number} == $who }, $P->{sublist});
  385.             error_message("Edit properties error", "No data found for page '$who' in subtopic list.", 0, 1) if ! defined $j;
  386.             $fr->{HTTP_REFERER} = join("/", $fr->{topic}, $who) if ! $i->{islink};
  387.             my $subst = page_mgr_general($fr, undef, undef, undef);
  388.             $subst->{edit}->{icon} = tree_icon_chooser($i->{icon}, $i->{param}, $i->{islink}, 0);
  389.             $subst->{edit}->{subicon} = $i->{property_emot};
  390.             dreq("webtags");
  391.             $subst->{edit}->{subtopic_name} = inverse_webtags($i->{name}, $fr->{topic}, undef);
  392.             $subst->{edit}->{descr} = inverse_webtags($j->{descr}, $fr->{topic}, undef);
  393.             $subst->{general}->{type} = $i->{islink};
  394.             $subst->{general}->{subtopic} = $i->{name};
  395.             $subst->{general}->{num} = $who;
  396.             $subst->{general}->{topic} = $fr->{topic};
  397.             $subst->{general}->{page} = $fr->{page};
  398.             $subst->{edit}->{url} = $j->{url};
  399.             $subst->{edit}->{target} = $j->{target};
  400.             $subst->{'meta'}->{'meta_description'} = $subst->{file}->{'meta_description'};
  401.             $subst->{'meta'}->{'meta_keywords'} = $subst->{file}->{'meta_keywords'};
  402.             $subst->{'meta'}->{'meta_robots'} = $subst->{file}->{'meta_robots'};
  403.             screen_out("subprops", $subst);
  404.         }
  405.         if ($action eq "m") {
  406.             move_item_tree($FORMref, $td, 2);
  407.         }
  408.     }
  409.     if ($action eq "reorder") {
  410.         my $order = {};
  411.         foreach my $x (keys(%{ $FORMref })) {
  412.             next if $x !~ m|^ORDER(\d+)|;
  413.             $order->{$1} = $FORMref->{$x};
  414.         }
  415.         dreq("fcn-pg_m");
  416.         my ($topic, $page) = split(/\//, $FORMref->{HTTP_REFERER});
  417.         reorder_subtopics({ topic => $topic, page => $page, order => $order});
  418.         return 1;
  419.     }
  420.  
  421. }
  422.  
  423. ###
  424. ### page_mgr_message_management
  425. ###
  426. ### Handles requests from Messages screen
  427. ###
  428.  
  429. sub page_mgr_message_management {
  430.     my ($selection, $item, $FORMref) = @_;
  431.     my $string = "[devipm]";
  432.     if ($selection =~ m%^($string)$%) {
  433.         my $command = $1;
  434.         my $target = $item;
  435.         my $td = {};
  436.         if ($FORMref->{markall}) {
  437.             foreach my $y (split(/,/, $FORMref->{mark_all_string})) {
  438.                 $td->{$y} = 1;
  439.             }
  440.         } elsif ($item eq "all") {
  441.             foreach my $y (split(/,/, $FORMref->{MARK})) {
  442.                 $td->{$y} = 1;
  443.             }
  444.         } else {
  445.             $td->{$target} = 1;
  446.         }
  447.         my ($topic, $page) = split(/\//, $FORMref->{HTTP_REFERER});
  448.         if ($command eq "d") {
  449.             dreq("fcn-msdl");
  450.             remove_message({ topic => $topic, page => $page, td => $td });
  451.             return 1;
  452.         }
  453.         if ($command eq "m") {
  454.             move_item_tree($FORMref, $td, 1);
  455.         }
  456.         if ($command eq "e") {
  457.             dreq("fcn-edit");
  458.             my $arg = {};
  459.             $arg->{username} = $FORMref->{username};
  460.             $arg->{skip_nav_bar} = 1;
  461.             $arg->{is_moderator} = 1;
  462.             $arg->{is_superuser} = 1 if $FORMref->{username} eq $DCONF->{superuser};
  463.             $arg->{escape_url} = "$PARAMS->{cgiurl}?username=$FORMref->{username}&action=pm-page_editor&HTTP_REFERER=/$topic/$page&menu=4";
  464.             $arg->{formaction} = "pm-edit_post";
  465.             edit_post_form($topic, $page, (keys(%{ $td }))[0], $arg);
  466.         }
  467.         if ($command =~ /[vip]/) {
  468.             my $subst = {};
  469.             $subst->{general}->{topic} = $topic;
  470.             $subst->{general}->{page} = $page;
  471.             my $post = (keys(%{ $td }))[0];
  472.             $subst->{general}->{post} = $post;
  473.             my $page_ref = GetPage($topic, $page);
  474.             my $prev = undef;
  475.             while (my $msg = shift (@{ $page_ref->{messages} })) {
  476.                 if ($msg->{number} == $post) {
  477.                     my @messages = ($msg);
  478.                     $subst->{messages} = \@messages;
  479.                     if (my $x = shift (@{ $page_ref->{messages} })) {
  480.                         $subst->{nextprev}->{'next'} = $x;
  481.                     } else {
  482.                         $subst->{nextprev}->{'next'} = undef;
  483.                     }
  484.                     $subst->{nextprev}->{prev} = $prev;
  485.                 } else {
  486.                     $prev = $msg;
  487.                 }
  488.             }
  489.             $subst->{head}->{param} = "Messages";
  490.             $subst->{general}->{skip_headers} = 1;
  491.             $subst->{general}->{skip_nav_bar} = 1;
  492.             $subst->{general}->{skip_bottom} = 1;
  493.             $subst->{general}->{username} = $FORMref->{username};
  494.             $subst->{arg}->{skip_nav_bar} = 1;
  495.             if ($DCONF->{pro}) {
  496.                 dreq("authwrap-PRO");
  497.                 $subst->{messages} = auth_wrap_attachments($subst->{messages}, $topic);
  498.             }
  499.             if ($command eq "p") {
  500.                 $subst->{arg}->{post_info} = 1;
  501.                 dreq("fcn-logs");
  502.                 my $r = log_read_file({ $topic => 1 }, undef, { postindex => $post });
  503.                 my $j = ref $r eq "ARRAY" ? $r->[0] : $r;
  504.                 my ($username, $group) = split(/:/, $j->{username});
  505.                 $subst->{poster} = $j;
  506.                 $subst->{poster}->{identity} = $username;
  507.                 $subst->{poster}->{group} = 1;
  508.                 $subst->{poster}->{group} = 2 if $group eq "MODERATOR";
  509.                 $subst->{poster}->{group} = 0 if ($group eq "PUBLIC" || $group eq "");
  510.                 $subst->{arg}->{post_info} = 2;
  511.                 my $z = $subst->{messages}->[0];
  512.                 my @p = ();
  513.                 foreach my $p (grep(/^property_/, keys(%{$z}))) {
  514.                     my $pp = $p; $pp =~ s/^property_//;
  515.                     push @p, { name => $pp, value => $z->{$p} };
  516.                 }
  517.                 @p = sort { $a->{name} cmp $b->{name} } @p;
  518.                 $subst->{props} = \@p;
  519.             }
  520.             screen_out("viewpost", $subst, undef);
  521.         }
  522.     }
  523.     if ($selection eq "reorder") {
  524.         my ($topic, $page) = split(/\//, $FORMref->{HTTP_REFERER});
  525.         undef my $p;
  526.         foreach my $i (keys(%{ $FORMref })) {
  527.             $p->{$1} = $FORMref->{$i} if $i =~ m|^ORDER(\d+)|;
  528.         }
  529.         dreq("fcn-ms_m");
  530.         reorder_messages( { topic => $topic, page => $page, order => $p });
  531.         return 2;
  532.     }
  533. }
  534.  
  535.  
  536. ###
  537. ### page_mgr_announcement
  538. ###
  539. ### Edit Announcement section of the Page Manager
  540. ###
  541.  
  542. sub page_mgr_announcement {
  543.     my ($FORMref, $file) = @_;
  544.     dreq("webtags");
  545.     my $subst = page_mgr_general($FORMref, $file);
  546.     $subst->{'special'}->{'ann_src'} = $subst->{file}->{'pginfo'}->{'announcement'};
  547.     $subst->{'special'}->{'ann_src'} = inverse_webtags($subst->{file}->{'pginfo'}->{'announcement'}, $subst->{file}->{head}->{topic_number}, 1) if !$GLOBAL_OPTIONS->{'allow_arb_html'};
  548.     $subst->{'special'}->{'abt_src'} = $subst->{file}->{'pginfo'}->{'about'};
  549.     $subst->{'special'}->{'abt_src'} = inverse_webtags($subst->{file}->{'pginfo'}->{'about'}, $subst->{file}->{head}->{topic_number}, 1) if !$GLOBAL_OPTIONS->{'allow_arb_html'};
  550.     page_mgr_print($subst);
  551. }
  552.  
  553. ###
  554. ### page_mgr_sublist
  555. ###
  556. ### Edit Subtopics section of Page Manager
  557. ###
  558.  
  559. sub page_mgr_sublist {
  560.     my ($FORMref, $file, $code, $special_in) = @_;
  561.     my $subst = page_mgr_general($FORMref, $file);
  562.     if ($subst->{file}->{head}->{param} !~ m|Sublist| && $subst->{file}->{head}->{param} =~ m|Messages|) {
  563.         $FORMref->{menu} = 4;
  564.         page_mgr_message($FORMref, $subst->{file});
  565.     }
  566.     if ($subst->{file}->{head}->{param} !~ m|Sublist| && $subst->{file}->{head}->{param} !~ m|Messages|) {
  567.         $FORMref->{menu} = 0;
  568.         page_mgr_navigate($FORMref, $subst->{file});
  569.     }
  570.     my @sublist = @{ expand_sublist($subst->{file}->{'sublist'}, $subst->{file}->{head}->{topic_number}, $special_in) };
  571.     my @salph = sort { $a->{name} cmp $b->{name} } @sublist; $subst->{'subtopics_alph'} = \@salph;
  572.     my @sdate = sort { $b->{lastmod} <=> $a->{lastmod} } @sublist; $subst->{'subtopics_date'} = \@sdate;
  573.     my @spost = sort { $b->{msg_count} <=> $a->{msg_count} } @sublist; $subst->{'subtopics_posts'} = \@spost;
  574.     my @ssub = sort { $b->{subs} <=> $a->{subs} } @sublist; $subst->{'subtopics_pages'} = \@ssub;
  575.     my @match = grep(_is_sublist_filtered($FORMref, $_), @sublist);
  576.     $subst->{general}->{size_s} = scalar(@sublist);
  577.     $subst->{general}->{match} = scalar(@match);
  578.     $subst->{general}->{success_code} = $FORMref->{success};
  579.     my $results_per_screen = 20;
  580.     foreach my $f (keys(%{ $FORMref })) {
  581.         if ($f =~ m|^l(\d+)|) {
  582.             if ($FORMref->{clear} == 1) {
  583.                 $FORMref->{"l$1"} = undef;
  584.                 $FORMref->{"f$1"} = undef;
  585.             }
  586.             $subst->{filter}->{"l$1"} = $FORMref->{"l$1"};
  587.             $subst->{filter}->{"f$1"} = $FORMref->{"f$1"};
  588.         }
  589.     }
  590.  
  591.     if (scalar(@match) > $results_per_screen) {
  592.         $subst->{general}->{s} = $FORMref->{s};
  593.         my $s = 0 + $FORMref->{s};
  594.         my @t = ();
  595.         for (my $i = 0; $i < scalar(@match); $i += $results_per_screen) {
  596.             my $o = {};
  597.             $o->{firstsub} = $match[$i]->{name};
  598.             my $luid = ($i + $results_per_screen) > scalar(@match) ? scalar(@match) : ($i + $results_per_screen);
  599.             $o->{lastsub} = $match[$luid-1]->{name};
  600.             $o->{ident} = 1+$i;
  601.             push @t, $o;
  602.         }
  603.         $s = 1 if ($s < 1 || $s != int($s) || $s > scalar(@match));
  604.         my $c = 0;
  605.         my @l = ();
  606.         foreach my $ue (@match) {
  607.             $ue->{ident} = ++$c;
  608.             push @l, $ue->{number};
  609.         }
  610.         my @z = ();
  611.         if ($FORMref->{s} =~ /^\*+$/) {
  612.             @z = @match;
  613.         } else {
  614.             my @u2 = @match;
  615.             @z = splice @u2, $s-1, $results_per_screen;
  616.             undef @u2;
  617.         }
  618.         $subst->{general}->{markall_string} = join(",", @l);
  619.         $subst->{subtopics} = \@z;
  620.         $subst->{t} = \@t;
  621.         $subst->{first_subtopic} = $z[0];
  622.         $subst->{last_subtopic} = $z[$#z];
  623.         $subst->{general}->{result_per_page} = $results_per_screen;
  624.         $subst->{general}->{screen_up} = $s - $results_per_screen;
  625.         $subst->{general}->{screen_up} = 1 if $subst->{general}->{screen_up} <= 1;
  626.         $subst->{general}->{screen_down} = $s + $results_per_screen;
  627.         $subst->{general}->{screen_down} = $s if $subst->{general}->{screen_down} > scalar(@match);
  628.         $subst->{general}->{screen_last} = 1+$results_per_screen * int(($match[$#match]->{ident}-1) / $results_per_screen);
  629.     } else {
  630.         $subst->{subtopics} = \@match;
  631.     }
  632.     page_mgr_print($subst);
  633. }
  634.  
  635. sub _is_sublist_filtered {
  636.     my ($FORMref, $record) = @_;
  637.     return 1 if $FORMref->{clear} > 0;
  638.     if ($FORMref->{l1} =~ /\S/) {
  639.         my $l1 = quotemeta(trim($FORMref->{l1}));
  640.         return 0 if $FORMref->{f1} == 1 && $record->{name} !~ /$l1/i;
  641.         return 0 if $FORMref->{f1} == 2 && $record->{name} =~ /$l1/i;
  642.     }
  643.     if ($FORMref->{l2} > 0) {
  644.         return 0 if $FORMref->{f2} == 3 && $record->{msg_count} > $FORMref->{l2};
  645.         return 0 if $FORMref->{f2} == 4 && $record->{msg_count} < $FORMref->{l2};
  646.     }
  647.     if ($FORMref->{l3} > 0) {
  648.         return 0 if $FORMref->{f3} == 3 && $record->{subs} > $FORMref->{l3};
  649.         return 0 if $FORMref->{f3} == 4 && $record->{subs} < $FORMref->{l3};
  650.     }
  651.     if ($FORMref->{l4} > 0) {
  652.         my $timecache = time - 24*60*60*$FORMref->{l4};
  653.         return 0 if $FORMref->{f4} == 3 && $record->{lastmod} < $timecache;
  654.         return 0 if $FORMref->{f4} == 4 && $record->{lastmod} > $timecache;
  655.     }
  656.     return 1;
  657. }
  658.  
  659. ###
  660. ### page_mgr_message
  661. ###
  662. ### Edit Messages section of Page Manager
  663. ###
  664.  
  665. sub page_mgr_message {
  666.     my ($FORMref, $file, $stuff) = @_;
  667.     my $subst = page_mgr_general($FORMref, $file, $stuff);
  668.     $subst->{general}->{menu} = 4;
  669.  
  670.     my @messages = @{ $subst->{file}->{messages} };
  671.     my @smf = sort { $a->{'time'} <=> $b->{'time'} } @messages;
  672.     $subst->{'messages_bydate'} = \@smf;
  673.     $subst->{general}->{size_m} = scalar(@messages);
  674.     my $z = undef;
  675.     if ($FORMref->{l4} =~ /\S/) {
  676.         dreq("fcn-logs");
  677.         my %h = map {$_->{number}, 1} @messages;
  678.         my $q = log_read_file($subst->{topic}, undef, \%h);
  679.         my %p = map { $_->{postindex}, (split(/:/, $_->{username}))[0] } @{$q};
  680.         $z = \%p;
  681.     }
  682.     my @match = grep(_is_message_filtered($FORMref, $_, $z), @messages);
  683.     foreach my $k (@match) {
  684.         $k->{text} = remove_html($k->{text});
  685.     }
  686.     $subst->{general}->{match} = scalar(@match);
  687.     my $results_per_screen = 20;
  688.     foreach my $f (keys(%{ $FORMref })) {
  689.         if ($f =~ m|^l(\d+)|) {
  690.             if ($FORMref->{clear} == 1) {
  691.                 $FORMref->{"l$1"} = undef;
  692.                 $FORMref->{"f$1"} = undef;
  693.             }
  694.             $subst->{filter}->{"l$1"} = $FORMref->{"l$1"};
  695.             $subst->{filter}->{"f$1"} = $FORMref->{"f$1"};
  696.         }
  697.     }
  698.     if (scalar(@match) > $results_per_screen) {
  699.         $subst->{general}->{s} = $FORMref->{s};
  700.         my $s = 0 + $FORMref->{s};
  701.         my @t = ();
  702.         my $c = 0;
  703.         my @l = ();
  704.         foreach my $ue (@match) {
  705.             $ue->{ident} = ++$c;
  706.             push @l, $ue->{number};
  707.         }
  708.         for (my $i = 0; $i < scalar(@match); $i += $results_per_screen) {
  709.             my $o = {};
  710.             $o->{firstmsg} = $match[$i]->{'time'};
  711.             my $luid = ($i + $results_per_screen) > scalar(@match) ? scalar(@match) : ($i + $results_per_screen);
  712.             $o->{lastmsg} = $match[$luid-1]->{'time'};
  713.             $o->{ident} = 1+$i;
  714.             push @t, $o;
  715.         }
  716.         $s = 1 if ($s < 1 || $s != int($s) || $s > scalar(@match));
  717.         my @z = ();
  718.         if ($FORMref->{s} =~ /^\*+$/) {
  719.             @z = @match;
  720.         } else {
  721.             my @u2 = @match;
  722.             @z = splice @u2, $s-1, $results_per_screen;
  723.             undef @u2;
  724.         }
  725.         $subst->{general}->{markall_string} = join(",", @l);
  726.         $subst->{messages} = \@z;
  727.         $subst->{t} = \@t;
  728.         $subst->{first_message} = $z[0];
  729.         $subst->{last_message} = $z[$#z];
  730.         $subst->{general}->{result_per_page} = $results_per_screen;
  731.         $subst->{general}->{screen_up} = $s - $results_per_screen;
  732.         $subst->{general}->{screen_up} = 1 if $subst->{general}->{screen_up} <= 1;
  733.         $subst->{general}->{screen_down} = $s + $results_per_screen;
  734.         $subst->{general}->{screen_down} = $s if $subst->{general}->{screen_down} > scalar(@match);
  735.         $subst->{general}->{screen_last} = 1+$results_per_screen * int(($match[$#match]->{ident}-1) / $results_per_screen);
  736.     } else {
  737.         $subst->{messages} = \@match;
  738.     }
  739.     page_mgr_print($subst);
  740. }
  741.  
  742. sub _is_message_filtered {
  743.     my ($FORMref, $record, $m) = @_;
  744.     return 1 if $FORMref->{clear} > 0;
  745.     if ($FORMref->{l1} =~ /\S/) {
  746.         my $l1 = quotemeta(trim($FORMref->{l1}));
  747.         return 0 if $FORMref->{f1} == 1 && $record->{text} !~ /$l1/i;
  748.         return 0 if $FORMref->{f1} == 2 && $record->{text} =~ /$l1/i;
  749.     }
  750.     if ($FORMref->{l2} =~ /\S/) {
  751.         my $l2 = quotemeta(trim($FORMref->{l2}));
  752.         return 0 if $FORMref->{f2} == 1 && $record->{author} !~ /$l2/i;
  753.         return 0 if $FORMref->{f2} == 2 && $record->{author} =~ /$l2/i;
  754.     }
  755.     if ($FORMref->{l3} > 0) {
  756.         my $timecache = time - 24*60*60*$FORMref->{l3};
  757.         return 0 if $FORMref->{f3} == 3 && $record->{'time'} < $timecache;
  758.         return 0 if $FORMref->{f3} == 4 && $record->{'time'} > $timecache;
  759.     }
  760.     if ($FORMref->{l4} =~ /\S/) {
  761.         my $l4 = quotemeta(trim($FORMref->{l4}));
  762.         my $z = $m->{$record->{number}};
  763.         return 0 if $FORMref->{f4} == 1 && $z !~ /$l4/i;
  764.         return 0 if $FORMref->{f4} == 2 && $z =~ /$l4/i;
  765.         return 0 if $FORMref->{f4} == 5 && $z !~ /^$l4$/i;
  766.         return 0 if $FORMref->{f4} == 6 && $z =~ /^$l4$/i;
  767.     }
  768.     return 1;
  769. }
  770.  
  771. ###
  772. ### page_mgr_about
  773. ###
  774. ### Edit About Message section of Page Manager
  775. ###
  776.  
  777. sub page_mgr_about {
  778.     my ($FORMref, $file, $stuff) = @_;
  779.     page_mgr_announcement($FORMref, $file, $stuff);
  780.     $stuff->{menu} = 3;
  781.     dreq("webtags");
  782.     my $subst = page_mgr_general($FORMref, $file, $stuff);
  783.     $subst->{'special'}->{'abt_src'} = $subst->{file}->{'pginfo'}->{'about'};
  784.     $subst->{'special'}->{'abt_src'} = inverse_webtags($subst->{file}->{'pginfo'}->{'about'}, $subst->{file}->{head}->{topic_number}, 1) if !$GLOBAL_OPTIONS->{'allow_arb_html'};
  785.     page_mgr_print($subst);
  786. }
  787.  
  788. ###
  789. ### page_mgr_1
  790. ###
  791. ### Topic Selection screen
  792. ###
  793.  
  794. sub page_mgr_1 {
  795.     my ($username, $param_in) = @_;
  796.     dreq("fcn-priv", "template");
  797.     my $privcache = read_privilege_file(undef, 1);
  798.     undef my $subst;
  799.     $subst->{'topics'} = board_topics(undef, undef, undef, undef, 1);
  800.     foreach my $topic (@{ $subst->{topics} }) {
  801.         if ($topic->{type} == 2 && $param_in == 2 && $username eq $DCONF->{superuser}) {
  802.             next if $GLOBAL_OPTIONS->{topics_to_show} != 1;
  803.             $subst->{'general'}->{'count'} += 1;
  804.             push (@{ $subst->{allowed} }, $topic);
  805.             next;
  806.         }
  807.         next if $topic->{type} == 2;
  808.         next if ! check_topic_authorization($username, $topic->{number}, $privcache) && $topic->{type} != 2;
  809.         $subst->{'general'}->{'count'} += 1;
  810.         push (@{ $subst->{allowed} }, $topic);
  811.     }
  812.     $subst->{'general'}->{'total'} = scalar(@{ $subst->{topics} });
  813.     $subst->{'general'}->{'url'} = "$PARAMS->{cgiurl}?username=$username&action=";
  814.     $subst->{'general'}->{'url'} .= "pm-page_editor" if $param_in == 0;
  815.     $subst->{'general'}->{'url'} .= "access_mgr_2" if $param_in == 2;
  816.     $subst->{'general'}->{'url'} .= "&HTTP_REFERER=/" if $param_in == 0;
  817.     $subst->{'general'}->{'url'} .= "&topic=" if $param_in == 2;
  818.     $subst->{'general'}->{'action'} = $param_in;
  819.     header();
  820.     print templ_int("pagemgr1", $subst);
  821.     program_exit(0);
  822. }
  823.  
  824. ###
  825. ### page_mgr_general
  826. ###
  827. ### General, shared aspects of Page Manager
  828. ###
  829.  
  830. sub page_mgr_general {
  831.     my ($FORMref, $file, $stuff, $subst) = @_;
  832.     $subst->{stuff} = $stuff;
  833.     error_message("Invalid Topic/Page Combination!", "", 0, 1) if $FORMref->{HTTP_REFERER} !~ m|(\d+)/(\d+)|;
  834.     ($subst->{topic}, $subst->{page}) = ($1, $2);
  835.     $subst->{file} = (defined($file) ? $file : GetPage($subst->{topic}, $subst->{page}, { lock => 0, unlock => 0 }));
  836.     $subst->{FORMref} = $FORMref;
  837.     $subst->{general}->{url} = "$PARAMS->{cgiurl}?username=$FORMref->{username}&action=pm-page_editor&HTTP_REFERER=$subst->{topic}/$subst->{page}";
  838.     $subst->{general}->{username} = $FORMref->{username};
  839.     $subst->{general}->{HTTP_REFERER} = join("/", $subst->{topic}, $subst->{page});
  840.     $subst->{levels} = $subst->{file}->{head}->{levels};
  841.     $subst->{head} = $subst->{file}->{head};
  842.     $subst->{general}->{menu} = $FORMref->{menu};
  843.     $subst->{general}->{menu} = $stuff->{menu} if defined $stuff->{menu};
  844.     $subst->{general}->{subtopic_count} = scalar(@{ $subst->{file}->{sublist} });
  845.     $subst->{general}->{message_count} = scalar(@{ $subst->{file}->{messages} });
  846.     $subst->{general}->{announcement} = $file->{pginfo}->{announcement};
  847.     $subst->{general}->{about} = $file->{pginfo}->{about};
  848.     return $subst;
  849. }
  850.  
  851. ###
  852. ### page_mgr_navigate
  853. ###
  854. ### Navigation section of Page Manager
  855. ###
  856.  
  857. sub page_mgr_navigate {
  858.     my ($FORMref) = @_;
  859.     my $subst = page_mgr_general($FORMref);
  860.     my $tree = read_tree($subst->{topic}, undef);
  861.     my $treeback = page_mgr_tree_for_sublist($tree, { me_number => $subst->{page}, parent => ($subst->{file}->{head}->{topic_number} == $subst->{file}->{head}->{me_number} ? 0 : $subst->{file}->{head}->{parent}) } );
  862.     $subst->{parent} = $treeback->{parent}->[0];
  863.     $subst->{siblings} = $treeback->{siblings};
  864.     $subst->{kids} = $treeback->{kids};
  865.     if ($FORMref->{sort} == 1) {
  866.         @{ $subst->{siblings} } = sort { $b->{posts} <=> $a->{posts} } @{ $subst->{siblings} };
  867.         @{ $subst->{kids} } = sort { $b->{posts} <=> $a->{posts} } @{ $subst->{kids} };
  868.     }
  869.     if ($FORMref->{sort} == 2) {
  870.         @{ $subst->{siblings} } = sort { $b->{subs} <=> $a->{subs} } @{ $subst->{siblings} };
  871.         @{ $subst->{kids} } = sort { $b->{subs} <=> $a->{subs} } @{ $subst->{kids} };
  872.     }
  873.     if ($FORMref->{sort} == 3) {
  874.         @{ $subst->{siblings} } = sort { $b->{lastmod} <=> $a->{lastmod} } @{ $subst->{siblings} };
  875.         @{ $subst->{kids} } = sort { $b->{lastmod} <=> $a->{lastmod} } @{ $subst->{kids} };
  876.     }
  877.     $subst->{general}->{sort} = $FORMref->{sort};
  878.     page_mgr_print($subst);
  879. }
  880.  
  881. ###
  882. ### page_mgr_print
  883. ###
  884. ### Internal subroutine to print the Page Manager interface
  885. ###
  886.  
  887. sub page_mgr_print {
  888.     my ($subst) = @_;
  889.     screen_out("pagemgr2", $subst, undef);
  890. }
  891.  
  892. ###
  893. ### page_mgr_tree_for_sublist
  894. ###
  895. ### From tree file, determines children, descendants, parents, and other
  896. ### information so the Page Manager screens can be rendered.
  897. ###
  898.  
  899. sub page_mgr_tree_for_sublist {
  900.     my ($treeref, $hashref) = @_;
  901.     undef my $resultref;
  902.     @{ $resultref->{kids} } = ();
  903.     @{ $resultref->{descendants} } = ();
  904.     @{ $resultref->{before} } = ();
  905.     @{ $resultref->{after} } = ();
  906.     @{ $resultref->{me_and_kids} } = ();
  907.     @{ $resultref->{siblings} } = ();
  908.     my $level = 0;
  909.     my $flag = 0;
  910.     my $current = 0;
  911.     my @treeref_copy = @{ $treeref };
  912.     while (my $ref = shift(@treeref_copy)) {
  913.         if ($ref->{page} == $hashref->{me_number}) {
  914.             $level = $ref->{level};
  915.             $flag = 1;
  916.             $resultref->{myself} = $ref;
  917.             push (@{ $resultref->{me_and_kids} }, $ref);
  918.         } elsif ($flag == 1 && $ref->{level} == (1 + $level)) {
  919.             push (@{ $resultref->{me_and_kids} }, $ref);
  920.             push (@{ $resultref->{descendants} }, $ref);
  921.             push (@{ $resultref->{kids} }, $ref);
  922.             @{ $resultref->{children}->{ $ref->{page} } } = ($ref);
  923.             $current = $ref->{page};
  924.         } elsif ($flag == 1 && $ref->{level} < (1 + $level)) {
  925.             $flag = 2;
  926.             push (@{ $resultref->{after} }, $ref);
  927.         } elsif ($flag == 1) {
  928.             push (@{ $resultref->{descendants} }, $ref);
  929.             push (@{ $resultref->{children}->{ $current } }, $ref);
  930.         } elsif ($flag == 0) {
  931.             push (@{ $resultref->{before} }, $ref);
  932.         } else {
  933.             push (@{ $resultref->{after} }, $ref);
  934.         }
  935.         push (@{ $resultref->{siblings} }, $ref) if $ref->{parent} == $hashref->{parent};
  936.         push (@{ $resultref->{parent} }, $ref) if $ref->{page} == $hashref->{parent};
  937.     }
  938.     return $resultref;
  939. }
  940.  
  941. ###
  942. ### page_change_link_properties
  943. ###
  944. ### For changing the properties of a link
  945. ###
  946.  
  947. sub page_change_link_properties {
  948.     my ($FORMref) = @_;
  949.     dreq("webtags", "fcn-pg_m");
  950.     my ($lint_subj1, $subtopic_name1) = webtags($FORMref->{name}, 3, 1, 1);
  951.     error_message("Change Link Properties - Problem With Name", $subtopic_name1, 0, 1) if $lint_subj1 eq "!Error";
  952.     my ($lint_subj2, $subtopic_name2) = webtags($FORMref->{descr}, 1, 1, 1);
  953.     error_message("Change Link Properties - Problem With Description", $subtopic_name2, 0, 1) if $lint_subj2 eq "!Error";
  954.     my $h = {};
  955.     $h->{name} = $subtopic_name1;
  956.     $h->{descr} = $subtopic_name2;
  957.     $h->{icon} = $FORMref->{icon};
  958.     $h->{emot} = $FORMref->{emoticon};
  959.     $h->{url} = $FORMref->{URL};
  960.     $h->{target} = $FORMref->{target};
  961.     error_message("Invalid Topic/Page Combination!", "", 0, 1) if $FORMref->{HTTP_REFERER} !~ m|(\d+)/(\d+)|;
  962.     my ($topic, $page) = ($1, $2);
  963.     my @U = change_page_properties($topic, $page, $FORMref->{num}, $h);
  964.     my $i = {};
  965.     my $t = {};
  966.     my $subt = $U[0];
  967.     foreach my $k (@{ $subt }) {
  968.         if ($k->{number} == $FORMref->{num}) {
  969.             $i = $k; last;
  970.         }
  971.     }
  972.     my $tree = $U[1];
  973.     foreach my $k (@{ $tree }) {
  974.         if ($k->{page} == $FORMref->{num}) {
  975.             $t = $k; last;
  976.         }
  977.     }
  978.     my $subst = page_mgr_general($FORMref, undef, undef, undef);
  979.     $subst->{edit}->{icon} = tree_icon_chooser($h->{icon}, $t->{param}, 1, 0);
  980.     $subst->{edit}->{subicon} = $h->{emot};
  981.     dreq("webtags");
  982.     $subst->{edit}->{subtopic_name} = $FORMref->{name};
  983.     $subst->{edit}->{descr} = $FORMref->{descr};
  984.     $subst->{general}->{type} = $t->{islink};
  985.     $subst->{general}->{subtopic} = $t->{name};
  986.     $subst->{general}->{num} = $FORMref->{num};
  987.     $subst->{general}->{topic} = $topic;
  988.     $subst->{general}->{page} = $page;
  989.     $subst->{edit}->{url} = $h->{url};
  990.     $subst->{edit}->{target} = $h->{target};
  991.     $subst->{general}->{saved} = 1;
  992.     screen_out("subprops", $subst);
  993. }
  994.  
  995. ###
  996. ### page_change_subtopic_properties
  997. ###
  998. ### For changing all properties, except the name, of a subtopic
  999. ###
  1000.  
  1001. sub page_change_subtopic_properties {
  1002.     my ($FORMref) = @_;
  1003.     dreq("webtags", "fcn-pg_m");
  1004.     my ($lint_subj2, $subtopic_name2) = webtags($FORMref->{descr}, 1, 1, 1);
  1005.     error_message("Change Subtopic Properties - Problem With Description", $subtopic_name2, 0, 1) if $lint_subj2 eq "!Error";
  1006.     my $h = {};
  1007.     $h->{descr} = $subtopic_name2;
  1008.     $h->{icon} = $FORMref->{icon};
  1009.     $h->{emot} = $FORMref->{emoticon};
  1010.     error_message("Invalid Topic/Page Combination!", "", 0, 1) if $FORMref->{HTTP_REFERER} !~ m|(\d+)/(\d+)|;
  1011.     my ($topic, $page) = ($1, $2);
  1012.     my @U = change_page_properties($topic, $page, $FORMref->{num}, $h);
  1013.     $FORMref->{menu} = 2;
  1014.     page_mgr_sublist($FORMref, $U[3], { what => 6 });
  1015. }
  1016.  
  1017. ###
  1018. ### page_change_subtopic_meta
  1019. ###
  1020. ### Changes subtopic META tags (and possibly all child META tags too)
  1021. ###
  1022.  
  1023. sub page_change_subtopic_meta {
  1024.     my ($FORMref) = @_;
  1025.     my $d = $FORMref->{meta_description}; $d =~ s/["\n]//g;
  1026.     my $k = $FORMref->{meta_keywords}; $k =~ s/["\n]//g;
  1027.     my $r = $FORMref->{meta_robots}; $r =~ s/["\n]//g;
  1028.     my ($topic, $page) = split(/\//, $FORMref->{HTTP_REFERER});
  1029.     my $pref = GetPage($topic, $FORMref->{num}, { lock => 1 });
  1030.     $pref->{meta_description} = $d;
  1031.     $pref->{meta_keywords} = $k;
  1032.     $pref->{meta_robots} = $r;
  1033.     SetPage($pref, { unlock => 1 });
  1034.     if ($FORMref->{meta_check} == 1) {
  1035.         dreq("fcn-regn", "fcn-tree");
  1036.         my $chgfile = regeneration_create_change_process_file("regen_meta_tag_change", $d, $k, $r);
  1037.         my $inc = incremental_descendants($topic, $FORMref->{num}, "CSM");
  1038.         if ($inc->{count} == 0) {
  1039.             unlink "$DCONF->{admin_dir}/backups/$inc->{tempfile}.TMP" ;
  1040.         } else {
  1041.             regenerate_board({ esc => 1, hold => regeneration_create_hold({ HTTP_REFERER => "/$topic/$page" }), topic => $pref->{head}->{topic_number}, tempfile => $inc->{tempfile}, done => 0, total => $inc->{count}, action => "regen3", username => $FORMref->{username}, changefile => $chgfile, operation => 8, description => 801 });
  1042.         }
  1043.     }
  1044.     $FORMref->{menu} = 2;
  1045.     $FORMref->{HTTP_REFERER} = join("/", $topic, $page);
  1046.     page_mgr_sublist($FORMref);
  1047. }
  1048.  
  1049.  
  1050. ###
  1051. ### page_rename_subtopic
  1052. ###
  1053. ### Renames a subtopic
  1054. ###
  1055.  
  1056. sub page_rename_subtopic {
  1057.     my ($FORMref) = @_;
  1058.     dreq("webtags", "fcn-pg_m");
  1059.     my ($lint_subj2, $subtopic_name2) = webtags($FORMref->{name}, 1, 1, 1);
  1060.     error_message("Rename Subtopic - Problem With Name", $subtopic_name2, 0, 1) if $lint_subj2 eq "!Error";
  1061.     rename_subtopic($FORMref->{topic}, $FORMref->{num}, $subtopic_name2, $FORMref->{username});
  1062.     $FORMref->{menu} = 2;
  1063.     $FORMref->{HTTP_REFERER} = join("/", $FORMref->{topic}, $FORMref->{page});
  1064.     page_mgr_sublist($FORMref);
  1065. }
  1066.  
  1067. ###
  1068. ### move_item_tree
  1069. ###
  1070. ### Generates a tree for moving messages or pages
  1071. ###
  1072.  
  1073. sub move_item_tree {
  1074.     my ($FORMref, $td, $type) = @_;
  1075.     my @t = keys(%{$td});
  1076.     my $subst = {};
  1077.     $subst->{general}->{type} = $type;
  1078.     $subst->{general}->{number} = scalar(@t);
  1079.     $subst = page_mgr_general($FORMref, undef, undef, $subst);
  1080.     $subst->{general}->{string} = join(",",@t);
  1081.     $subst->{general}->{x} = join(",", splice(@t, 0, 25));
  1082.     ($subst->{general}->{topic},$subst->{general}->{page}) = split(/\//, $FORMref->{HTTP_REFERER});
  1083.     screen_out("mover", $subst);
  1084. }
  1085.  
  1086. ###
  1087. ### first_grep
  1088. ###
  1089. ### Finds the first element of an array that matches a certain condition
  1090. ###
  1091.  
  1092. sub first_grep {
  1093.     my ($coderef, $arrayref) = @_;
  1094.     return undef if ref $coderef ne 'CODE';
  1095.     return undef if ref $arrayref ne 'ARRAY';
  1096.     foreach my $j (@{$arrayref}) {
  1097.         return $j if &{$coderef}($j);
  1098.     }
  1099.     return undef;
  1100. }
  1101.  
  1102.  
  1103. 1;
  1104.