#!/usr/bin/perl BEGIN { ($0 =~ m!(.*)(\\|/)[^/\\]+!) && unshift(@INC, $1, "$1$2Modules"); eval { require bytes; import bytes; } } use lib ("./Modules", "."); #in case $0 is weird use CGI qw/-no_xhtml -nosticky :standard/; use CGI::Carp qw(fatalsToBrowser); use File::Path; use strict; # If you see this message in your browser, your hosting provider # has not properly mapped the .cgi file extension to Perl. Please # contact the provider for more information. Mapping .cgi is a # simple process and usually takes just a few seconds. # ***************************************************************** # ** ** # ** LEGAL NOTICE ** # ** ** # ** The entire suite of Big Medium perl scripts is copyright ** # ** Global Moxie and Josh Clark. All rights reserved. ** # ** ** # ** For more information on Big Medium content management ** # ** software and other Global Moxie products, visit our ** # ** website at: http://www.globalmoxie.com ** # ** ** # ** You may not distribute this program in any manner, ** # ** modified or otherwise, without the express, written ** # ** consent from Global Moxie. ** # ** ** # ** You may make modifications, but only for your own use and ** # ** within the confines of the Big Medium License Agreement ** # ** (see our website for the full license). ** # ** ** # ** You may not distribute "hacks" for Big Medium without ** # ** approval from Global Moxie. ** # ** ** # ** NOTE: We regret that if you modify any code within your ** # ** installation of Big Medium that we cannot offer you tech ** # ** support or assistance. ** # ** ** # ***************************************************************** # ***************************************************************** # ** ** # ** ABOUT THIS SCRIPT ** # ** ** # ** bm_sections.cgi ** # ** Part of the Big Medium suite of perl scripts that allow ** # ** the authoring, formatting and publication of content to ** # ** your website. Big Medium is a product of Global Moxie. ** # ** ** # ** Purpose: This script allows the user to browse, create ** # ** and edit section (and sub-section) settings, directories ** # ** and html templates. ** # ** ** # ** Author: Josh Clark ** # ** Copyright 2002-2003 Josh Clark and Global Moxie ** # ** ** # ** service@globalmoxie.com ~~ http://www.globalmoxie.com ** # ** ** # ***************************************************************** # ***************************************************************** # ** ** # ** VERSION INFO ** # ** Current version: 1.3.3 ** # ** ** # ** Fixed since 1.3.2 ** # ** - Load bm_setup.pl before loading bm_lib.pl. ** # ** - Close filehandle after reading template uploads in ** # ** section editor; prevents Windows systems from incorrectly** # ** hanging onto temp files. ** # ** ** # ** Fixed since 1.2.2 ** # ** - Use File::Path and rmtree to delete section html files ** # ** for improved support under Windows servers. ** # ** - Removed FTP option from section editor. ** # ** - Fixed incorrect display of vertical rollover dimensions ** # ** - Delete document downloads when deleting sections ** # ** ** # ***************************************************************** # ================================================================= # LOAD LIBRARIES # ================================================================= require "bm_setup.pl"; require "bm_lib.pl"; require "bm_vetting.pl"; require "moxie_profiles.pl"; # ================================================================= # BAIL OUT IF BIG MEDIUM POWER SWITCH IS OFF # ================================================================= if ($bmSetup::AllUsage eq "off") { &bmLib::bmHTML("Please Try Back Later...", $bmSetup::AllOff); } package bmSection; &bmSection::main; exit; sub main { # routine: main================================================ # DECLARE/INITIALIZE GLOBAL VARIABLES # ============================================================= # Gather user info that may have been submitted at login ($bmSection::UserName, $bmSection::Password, $bmSection::ProfileNumber) = &MoxieProf::getinput( CGI::param("UserName"), CGI::param("Password"), CGI::param("ProfileNumber") ); # initialize variables used to build section edit pages $bmSection::required = qq~*~; # routine: main================================================ # CONFIRM IDENTITY AND CHECK PRIVILEGES # ============================================================= ($bmSection::Privileges, $bmSection::UserName ) = &MoxieProf::admin_confirm( "the Big Medium section editor", "bm_sections.cgi", $bmSection::UserName, $bmSection::Password, $bmSection::ProfileNumber ); &bmLib::check_privileges( $bmSection::Privileges, "section", $bmSection::UserName ); #Note: Other scripts get checked here for whether SiteUsage has #site turned on; don't do that here because SiteUsage should #allow all template-related functions to continue; just no new #content additions/editing. # routine: main================================================ # LOAD INFO ABOUT THE SITE AND ROUTE USER TO DESTINATION # ============================================================= &bmLib::LoadSectionInfo; if (CGI::param("login_now") eq "login") { &bmSection::section_menu; } elsif (CGI::param("home") == 1) { &bmSection::homepage_editor; } elsif (CGI::param("save_home") eq "Save") { &bmSection::save_homepage; } elsif (CGI::param("set") ) { &bmSection::edit_settings; } elsif (CGI::param("save_set") eq "Save") { &bmSection::save_settings; } elsif (CGI::param("template") ne "") { &bmSection::display_template; } elsif (CGI::param("do_not_delete") eq "Cancel") { &bmSection::section_menu("

Your deletion request was canceled.

"); } elsif (CGI::param("delete_subsecs") eq "Delete") { &bmSection::do_section_delete; } elsif (CGI::param("ContinueDelete") eq "delete") { &bmSection::update_deleted_articledata; } elsif ( CGI::param("update") eq "Update Menu" || CGI::param("delete") > 0) { #note: this option has to come after the other delete #options above, since others also use 'delete' parameter &bmSection::confirm_delete; } elsif (CGI::param("move") ne "") { &bmSection::rearrange_secs; } elsif (CGI::param("rearrange") eq "Save") { &bmSection::do_rearrange; } elsif (CGI::param("edfeed") == 1) { &bmSection::edit_newsfeeds; } elsif (CGI::param("savefeed") == 1) { &bmSection::save_newsfeeds; } else { &bmLib::bump_to_signin( "the Big Medium section editor", "bm_sections.cgi" ); } exit; } #end main routine #### ROUTINES BEGIN sub section_menu { ############################################################### ## ROUTINE: section_menu ## ## This routine displays all section-editing options for the ## homepage and current sections and subsections. ## ############################################################### # routine: section_menu======================================== # DECLARE VARIABLES # ============================================================= my $confirm_msg = shift; #message confirming previous action #html-building my $table; #contents of the section table my $html; #contents of the html page #section info my @subsecs; #subsection indices for each section #misc utility variables my $filename; #holds template filename my $bgcolor; #holds color of current row (main secs) my $subcount; #used to alternate colors (subsecs) my $subcolor; #holds color of current row (subsecs) my $linktext; #holds add/edit text for subsections # routine: section_menu======================================== # BUILD THE PAGE HEADER # ============================================================= #display confirmation message if we have one if ($confirm_msg) { $html = &bmLib::box_it_headline( "Update Status", $confirm_msg); } $html .= CGI::start_form("post","$bmSetup::BigMedURL/bm_sections.cgi"); #display main page options $table = qq~Edit Homepage    New Main Section    Rearrange Main Sections
 ~; $html .= &bmLib::box_it_headline( "Section Editor", $table, "seceditor"); # routine: section_menu======================================== # BUILD INFO FOR EACH MAIN SECTION # ============================================================= foreach (@bmSetup::AllSections) { next if ($_ =~ /_/); #find only main sections (undef, @subsecs) = &bmLib::GetAllSubs($_); $table = qq~Settings    New subsection~; if (@subsecs > 1) { $table .= qq~    Rearrange subsections~; } $table .= qq~    Delete section
 \n~; # routine: section_menu======================================== # BUILD SUBSECTION TABLE IF SECTION HAS SUBSECTIONS # ============================================================= if (@subsecs == 0) { $table .= "
[ No subsections ]\n"; } else { #build subsection table for this main section $table .= qq~~; # routine: section_menu============================ # BUILD INFO FOR EACH SUBSECTION # ================================================= $subcount = 0; foreach (@subsecs) { $subcount++; if ((int($subcount/2)) != ($subcount/2)) { $subcolor = qq~ bgcolor="$bmSetup::AltColumnColor1"~; } else { $subcolor = ""; } $table .= qq~~; ## delete box $table .= qq~~; ## Section name $table .= qq~~; ## Slug name $table .= qq~~; ## Status $bmSetup::SectionActive{$_} = "Off" if $bmSetup::SectionActive{$_} eq ""; $bmSetup::SectionActive{$_} .= " (alias)" if $bmSetup::SectionAlias{$_}; $table .= qq~~; ## template link $filename = $_ . "ind.template"; if (-e "$bmSetup::DataDir/templates/$_.template" || -e "$bmSetup::DataDir/templates/$filename") { $linktext = "Custom"; } else { $linktext = "Default"; } $table .= qq~~; ## Announcement link if (-e "$bmSetup::DataDir/templates/$_.annc") { $linktext = "Custom"; } else { $linktext = "Default"; } $table .= qq~~; } $table .= qq~
Subsections
DeleteSubsectionSlugStatusHTMLAnncNews Feed
$bmSetup::SectionShort{$_}$bmSetup::SectionSlug{$_}\u$bmSetup::SectionActive{$_}$linktext$linktext ~; ## News Feed if (index($bmSetup::SectionSuppress{$_}, "s") < 0) { $table .= "yes"; } else { $table .= "no"; } $table .= qq~
\n~; } $html .= &bmLib::box_it_headline( "Main Section: $bmSetup::SectionName{$_}", $table); } # routine: section_menu======================================== # DISPLAY THE PAGE # ============================================================= $html .= &bmLib::box_it(qq~~); $html .= CGI::endform; &bmLib::bigmed_page( $bmSection::UserName, $bmSection::Privileges, $bmSetup::SiteName, $html, "templates", "section editor"); } #end section_menu routine sub homepage_editor { # Form for editing/creating homepage templates ############################################################### ## ROUTINE: homepage_editor ## ## This routine presents the edit form for submitting changes ## to the homepage description, keywords, templates and ## graphics. ## ############################################################### # routine: homepage_editor===================================== # DECLARE VARIABLES # ============================================================= my @file; #holds file contents for each template my $thisfield; #holds html for each field space my $html; #contents of the page my $home_announce; #the homepage announcement text # routine: homepage_editor===================================== # START BUILDING HTML PAGE # ============================================================= CGI::autoEscape(undef); # turn off auto-escaping in forms; we'll do it ourselves. $html = qq~
\n~; $html .= qq~
~ . &bmLib::box_it_headline("Edit Homepage") . qq~
\n~; # routine: homepage_editor===================================== # BUILD FIELD FOR HOMEPAGE METADATA # ============================================================= $thisfield = qq~The description and keywords are used in <meta> tags in the homepage header, affecting how search engines index your site.

Site description (optional)
~; $thisfield .= CGI::textarea(-name=> "description", -default=> $bmSetup::SectionDesc{"h"}, -rows=> 3, -columns=> 70, -class=> "plain"); $thisfield .= qq~

Keywords (optional)
Separate words with spaces; avoid punctuation
~; $thisfield .= CGI::textfield( -name=> "keywords", -default=> $bmSetup::SectionKeys{"h"}, -size=> 30, -maxlength=>900, -class=> "plain"); $html .= qq~
~ . &bmLib::box_it_headline( "Homepage Metadata", $thisfield, "homemeta"); $html .= qq~

Homepage Template

\n
~; # routine: homepage_editor===================================== # BUILD FIELD FOR HOMEPAGE TEMPLATE # ============================================================= $thisfield = qq~This required template is used to build the website homepage.

Load new template:
~; $thisfield .= CGI::filefield( -name=> "home_template_form", -default=> "", -size=> 20, -maxlength=>500, -accept=> "text/plain,text/html", -class=> "plain"); if (-e "$bmSetup::DataDir/templates/home.template") { $thisfield .= qq~

View/download the current template~; } else { $thisfield .= qq~

[ Currently no template loaded. ]~; } $thisfield .= "

"; $html .= &bmLib::box_it_headline( "Homepage Template$bmSection::required", $thisfield, "hometem" ); $html .= qq~

Homepage Announcement

\n
~; # routine: homepage_editor===================================== # BUILD FIELD FOR HOMEPAGE ANNOUNCEMENT # ============================================================= # Load the announcement file if (-e "$bmSetup::htmlDir/announcement.txt") { @file = &bmLib::LoadFile("$bmSetup::htmlDir/announcement.txt"); ($home_announce) = &bmLib::make_it_html_safe (join("\n", @file)); } $thisfield = "Announcement appears only on the homepage (if the homepage template uses the ANNOUNCE widget). The announcement may contain links and other html. Leave blank if you do not wish to have an announcement.

"; $thisfield .= CGI::textarea( -name=> "home_announce_form", -default=> $home_announce, -rows=> 10, -columns=> 70, -class=> "plain"); $html .= &bmLib::box_it_headline("Homepage Announcement", $thisfield, "announce"); $html .= "
\n"; # routine: homepage_editor===================================== # BUILD NAVIGATION IMAGE FIELDS # ============================================================= $html .= &bmSection::build_nav_fields( "h", "HNAVIMAGE", "VNAVIMAGE", $bmSetup::hNavHTML, $bmSetup::vNavHTML); # routine: homepage_editor===================================== # DISPLAY FORM IN BIG MEDIUM PAGE # ============================================================= $html .= qq~
~ . &bmLib::box_it(qq~~); $html .= "
" . CGI::endform; &bmLib::bigmed_page( $bmSection::UserName, $bmSection::Privileges, $bmSetup::SiteName, $html, "templates", "section editor" ); exit; } #end homepage_editor routine sub save_homepage { ############################################################### ## ROUTINE: save_homepage ## ## This routine accepts homepage template, graphic and ## announcement info from the Edit Homepage form, and saves ## them to file. User is returned to the Section Editor page. ## ############################################################### # routine: save_homepage======================================= # DECLARE AND VET VARIABLES # ============================================================= my $home_template_form = CGI::param("home_template_form"); my $home_announce_form = CGI::param("home_announce_form"); $bmSetup::SectionDesc{"h"} = CGI::param("description"); $bmSetup::SectionKeys{"h"} = CGI::param("keywords"); my %save_navimage; my $homeline; my @sections; ($home_announce_form) = &bmVet::prep_for_html($home_announce_form); $home_announce_form =~ s/ /\n/g; # routine: save_homepage======================================= # MAKE SURE THERE'S AVAILABLE DISK SPACE # ============================================================= &bmLib::DiskSpace("$bmSetup::DataDir/templates"); # routine: save_homepage======================================= # VET TEMPLATE UPLOAD # ============================================================= ($home_template_form) = &bmSection::vet_text_file( "homepage template", $home_template_form ); if ( ! $home_template_form && ! -e "$bmSetup::DataDir/templates/home.template" ) { &bmLib::bmHTML("HTML Template Required", "Please provide an HTML template for the homepage. Click here for help with the homepage template, or click your browser's Back button to review your entry and load a template."); } # routine: save_settings======================================= # VET AND SAVE NAVIGATION IMAGES # ============================================================= %save_navimage = &bmSection::vet_save_navimages("h"); # routine: save_homepage--===================================== # SAVE NEW TEMPLATE AND INCLUDE FILES # ============================================================= # Update the homepage html template file if loaded if ($home_template_form ne "") { open (MAINTEMPLATE, ">$bmSetup::DataDir/templates/home.template") or die("Unable to write to $bmSetup::DataDir/templates/home.template. $!."); flock(MAINTEMPLATE, 2) or die("Could not do flock 2 exclusive lock for $bmSetup::DataDir/templates/home.template. $!"); print MAINTEMPLATE "$home_template_form\n"; close (MAINTEMPLATE); chmod 0666, "$bmSetup::DataDir/templates/home.template"; } # Update the homepage announcement file open (ANNOUNCE, ">$bmSetup::htmlDir/announcement.txt") or die("Unable to write to $bmSetup::htmlDir/announcement.txt. $!."); flock(ANNOUNCE, 2) or die("Could not do flock 2 exclusive lock for $bmSetup::htmlDir/announcement.txt. $!"); print ANNOUNCE "$home_announce_form\n"; close (ANNOUNCE); chmod 0666, "$bmSetup::htmlDir/announcement.txt"; # routine: save_homepage--===================================== # INSERT UPDATED HOMEPAGE INFO IN FIRST LINE OF SECTION INDEX # ============================================================= #clean up user submissions ($bmSetup::SectionDesc{"h"}, $bmSetup::SectionKeys{"h"} ) = &bmVet::prep_for_simple_text( $bmSetup::SectionDesc{"h"}, $bmSetup::SectionKeys{"h"}); #put together the data line $homeline = "h" . " " . $bmSetup::HomeLabel . " " . $bmSetup::SectionDesc{"h"} . " " . $bmSetup::SectionKeys{"h"} . " " . "on" . " " . " " . $bmSetup::SectionSuppress{"h"} . " " . $save_navimage{"hnav_file"} . " " . $save_navimage{"hnav_url"} . " " . $save_navimage{"hnavroll_file"} . " " . $save_navimage{"hnavroll_url"} . " " . $save_navimage{"vnav_file"} . " " . $save_navimage{"vnav_url"} . " " . $save_navimage{"vnavroll_file"} . " " . $save_navimage{"vnavroll_url"}; #make sure we have a directory to save &bmVet::check_directory("$bmSetup::DataDir/templates" => "Templates Directory" ); &bmLib::FileLock; #load current data file and sub in the new home line @sections = &bmLib::LoadFile("$bmSetup::DataDir/templates/Sections.setup"); shift @sections; unshift (@sections, $homeline); #write to disk open (SECTIONFILE, ">$bmSetup::DataDir/templates/Sections.setup") or die("Unable to write to $bmSetup::DataDir/templates/Sections.setup. $!."); flock(SECTIONFILE, 2) or die("Could not do flock 2 exclusive lock. $!."); foreach (@sections) { print SECTIONFILE "$_\n"; } close (SECTIONFILE); chmod 0666, "$bmSetup::DataDir/templates/Sections.setup"; &bmLib::FileUnlock; # routine: save_homepage--================================== # UPDATE NAVIGATION HTML AND JAVASCRIPT # ========================================================== require "bm_navigation.pl"; &bmNav::create_nav_files; # routine: save_homepage--================================== # GIVE A CONFIRMATION MESSAGE AND SEND BACK TO THE MAIN MENU # ========================================================== &bmSection::section_menu("
Your homepage template and announcement have been saved.
Announcement changes will appear on the live site immediately, but template or navigation changes will not appear on the live site until you rebuild top-level pages.
Unless you have other section changes to make, you should now rebuild top-level pages if you made template or navigation changes."); } # end save_homepage routine sub edit_settings { ############################################################### ## ROUTINE: edit_settings ## ## Presents a form with options to create or edit section ## settings for either a main section or a subsection. This ## includes all settings except html templates and ## announcements. ############################################################### # routine: edit_settings======================================= # DECLARE VARIABLES # ============================================================= #section info my $sec_index = CGI::param("set"); my $mainsec = CGI::param("mainsec"); #for building new subsec #html-building variables my $headline; #page title my $html; #html of page to display my $thisfield; #html for each field area my $h_image_type; #holds label for type of horiz navbar my $v_image_type; #holds label for type of vert navbar my $h_dimensions; #horizontal height/width requirements my $v_dimensions; #vertical height/width requirements #template field variables my $filename; #holds template filename my $sec_template; #holds template html for this section my $sec_subtemplate; #holds default subsection html my $sec_subindex; #holds custom subsection index html my $thistitle; #holds title for template fields my $thishelp; #holds help link for template fields #announcement field variables my $sec_announce; #section announcement for this section my $sec_subannounce; #default subsec annc if main section #section suppression info my @this_suppress; #areas where section suppressed my @suppress; #possible values of suppress checks my %suppress; #variables for suppress checks #misc utility variables my $top_level; #flags that this is a top-level section my $p; #parent of subsection my $ann_cols; #fixes num of columns in annc fields # routine: edit_settings======================================= # SELECT PAGE HEADLINE AND VET SECTION, IF NECESSARY # ============================================================= if ($sec_index eq "new") { $headline = "Create a New Main Section"; } elsif ($sec_index eq "sub") { $headline = "Create a New Subsection"; } else { $sec_index = &bmSection::vet_index($sec_index); $headline = qq~Edit Section Settings~; } # routine: edit_settings======================================= # SET UP SUPPRESSION INFO, IMAGE INFO # ============================================================= if ($sec_index !~ /_/ && $sec_index ne "sub") { #new section or main section $h_image_type = "HNAVIMAGE"; $v_image_type = "VNAVIMAGE"; $h_dimensions = $bmSetup::hNavHTML; $v_dimensions = $bmSetup::vNavHTML; $suppress{"p"} = " Don't generate a spotlight article for this section"; } else { ($p) = split(/_/, $sec_index); $p = $mainsec if $p eq "sub"; $suppress{"m"} = " Don't show section's articles on main $bmSetup::SectionName{$p} page"; $h_image_type = "HSUBNAVIMAGE"; $v_image_type = "VSUBNAVIMAGE"; $h_dimensions = $bmSetup::hSubHTML; $v_dimensions = $bmSetup::vSubHTML; } #suppression info and setup @this_suppress = split(//,$bmSetup::SectionSuppress{$sec_index}); $suppress{"h"} = " Don't show section's articles on homepage"; $suppress{"n"} = " Don't include section in navigation bar"; $suppress{"s"} = qq~ Don't offer a stand-alone news feed for this section~; @suppress = sort keys %suppress; # routine: edit_settings======================================= # LOAD SUBSECTION INDEX TEMPLATE INFO # ============================================================= if ($sec_index !~ /_/ && $sec_index ne "sub") { #this is a main section; load default subsection index $top_level = 1; $filename = $sec_index . "sub.template"; if (-e "$bmSetup::DataDir/templates/$filename" && $sec_index ne "new") { $sec_subtemplate = qq~View/download the current template~; } else { $sec_subtemplate = qq~ [ Currently no default article template loaded. ]~; } $sec_index .= "_0"; #for loading the main page template } else { #this is a subsection; load custom index template $filename = $sec_index . "ind.template"; if (-e "$bmSetup::DataDir/templates/$filename" && $sec_index ne "new") { $sec_subindex = qq~View/download the current template
Delete the custom index template~; } else { $sec_subindex = qq~[ Currently no custom index template loaded. ]~; } } # routine: edit_template======================================= # LOAD SECTION-SPECIFIC TEMPLATE INFO # ============================================================= #this is the main-page template for main sections, or the #article page template for subsections $filename = $sec_index . ".template"; if (-e "$bmSetup::DataDir/templates/$filename" && $sec_index ne "new") { $sec_template = qq~View/download the current template~; #allow template deletion if it's a subsection $sec_template .= qq~
Delete the custom index template~ if $sec_index !~ /_0$/; } else { $sec_template = qq~[ Currently no template loaded. ]~; } #Return top-level section index to normal format $sec_index =~ s/_0$//; # routine: edit_settings======================================= # START BUILDING HTML # ============================================================= CGI::autoEscape(undef); # turn off auto-escaping in forms $html = qq~ \n~; $html .= qq~~; $bmSetup::SectionName{$sec_index} =~ s/>/>/; $html .= qq~
~ . &bmLib::box_it_headline($headline, "$bmSetup::SectionName{$sec_index} " ); $html .= qq~
\n
~; # routine: edit_settings======================================= # BUILD NAME FIELD # ============================================================= $thisfield = qq~Name shown in navigation menus
~; $thisfield .= CGI::textfield( -name=> "sec_name", -default=> $bmSetup::SectionShort{$sec_index}, -size=> 30, -maxlength=>250, -class=> "plain" ); $html .= &bmLib::box_it_headline( "Display Name$bmSection::required", $thisfield, "displayname", "left"); # routine: edit_settings======================================= # BUILD SLUG FIELD # ============================================================= $thisfield = qq~Custom directory name (optional)
~; $thisfield .= CGI::textfield(-name=> "sec_slug", -default=> $bmSetup::SectionSlug{$sec_index}, -size=> 30, -maxlength=>250, -class=> "plain"); $html .= &bmLib::box_it_headline( "Slug Name", $thisfield, "secslug", "right" ); $html .= qq~
\n
~; # routine: edit_settings======================================= # BUILD ALIAS FIELD # ============================================================= ($bmSetup::SectionAlias{$sec_index}) = &bmLib::make_it_html_safe($bmSetup::SectionAlias{$sec_index}); $thisfield = qq~Fill out this field only if the section is not managed by Big Medium. If this is a community section for discussion forums, for example, type the address to the main page for your discussion forum software. (Click for more info. Not sure what to do? Leave this field blank.)

Alias URL: (optional)
~; $thisfield .= CGI::textfield( -name=> "sec_alias", -default=> $bmSetup::SectionAlias{$sec_index}, -size=> 70, -maxlength=> 500, -class=> "plain"); $html .= &bmLib::box_it_headline( "Section Alias", $thisfield, "alias" ); $html .= qq~
\n
~; # routine: edit_settings======================================= # BUILD METADATA FIELD # ============================================================= $thisfield = qq~Description (optional)
~; $thisfield .= CGI::textarea( -name=> "sec_description", -default=> $bmSetup::SectionDesc{$sec_index}, -rows=> 3, -columns=> 70, -class=> "plain"); $thisfield .= qq~

Keywords (optional)
Separate words with spaces; avoid punctuation
~; $thisfield .= CGI::textfield( -name=> "sec_keywords", -default=> $bmSetup::SectionKeys{$sec_index}, -size=> 30, -maxlength=>900, -class=> "plain"); $html .= &bmLib::box_it_headline( "Metadata", $thisfield, "secmeta" ); $html .= qq~
\n
~; # routine: edit_settings======================================= # BUILD SECTION VISIBILITY FIELD # ============================================================= if ($sec_index !~ /_/ && $sec_index ne "sub") { $thisfield = "Main sections are always active."; } else { $thisfield = CGI::checkbox_group( -name=> 'sec_active', -values=> ['on'], -nolabels=> 'true', -default=> [$bmSetup::SectionActive{$sec_index}], -class=> "breathe" ); $thisfield .= qq~ Make section active~; if ($sec_index eq "sub" || $bmSetup::RSSNum == 0) { push (@this_suppress, "s"); #default to no subsection feeds } } $thisfield .= qq~

Display Preferences~; $thisfield .= CGI::checkbox_group( -name=> 'sec_suppress', -values=> \@suppress, -labels=> \%suppress, -columns=> 1, -default=> \@this_suppress, -class=> "breathe" ); $html .= &bmLib::box_it_headline( "Section Status", $thisfield, "secstatus" ); $html .= qq~

Design Templates

\n
~; # routine: edit_template======================================= # BUILD FIELD FOR THIS SECTION'S TEMPLATE # ============================================================= if ($top_level) { $thistitle = "Main Section Template$bmSection::required"; $thishelp = "maintem"; $thisfield = qq~This required template is used to build the main index page of this top-level section. (Template is not required for aliased sections).

Load new template:
~; } else { ($p) = split(/_/, $sec_index); $thistitle = "Custom Article Template"; $thishelp = "cusarttem"; $thisfield = qq~This optional template is used for all article pages in this subsection. If you do not provide this template, Big Medium will build article pages from the default article template for the $bmSetup::SectionName{$p} section.

Load new template:
~; } $thisfield .= CGI::filefield( -name=> "sec_template_form", -default=> "", -size=> 20, -maxlength=>500, -accept=> "text/plain,text/html", -class=> "plain" ); $thisfield .= "

$sec_template"; $html .= &bmLib::box_it_headline( $thistitle, $thisfield, $thishelp ); $html .= qq~
\n
~; # routine: edit_template======================================= # BUILD FIELD FOR DEFAULT ARTICLE IF MAIN SECTION # or # BUILD FIELD FOR CUSTOM SUBSECTION INDEX IF SUBSECTION # ============================================================= if ($top_level) { #Build default article page for main section $thisfield = qq~This required template is used to build all article pages for the $bmSetup::SectionName{$sec_index} section, unless you provide custom templates in subsection settings. (Template not required for aliased sections).

Load new template:
~; $thisfield .= CGI::filefield( -name=> "sec_subtemplate_form", -default=> "", -size=> 20, -maxlength=>500, -accept=> "text/plain,text/html", -class=> "plain" ); $thisfield .= "

$sec_subtemplate"; $html .= &bmLib::box_it_headline( "Default Article Template$bmSection::required", $thisfield, "defarttem" ); } else { #Build custom subsection index for subsection $thisfield = qq~This optional template is used to build the index pages that list articles in this subsection.

If you do not provide this template, Big Medium will use the default subsection index template for the $bmSetup::SectionName{$p} section.

Load new template:
~; $thisfield .= CGI::filefield( -name=> "sec_subindex_form", -default=> "", -size=> 20, -maxlength=>500, -accept=> "text/plain,text/html", -class=> "plain" ); $thisfield .= "

$sec_subindex"; $html .= &bmLib::box_it_headline( "Custom Subsection Index Template", $thisfield, "cusindtem"); } $html .= qq~
\n
~; # routine: edit_template======================================= # BUILD FIELD FOR DEFAULT SUBSECTION INDEX IF MAIN SECTION # ============================================================= if ($top_level) { $thisfield = qq~This required template is used to build all subsection index pages for this section, unless you provide custom templates in subsection settings. (Template not required for aliased sections).

Load new template:
~; $thisfield .= CGI::filefield( -name=> "sec_subindex_form", -default=> "", -size=> 20, -maxlength=>500, -accept=> "text/plain,text/html", -class=> "plain" ); $filename = $sec_index . "ind.template"; if (-e "$bmSetup::DataDir/templates/$filename" && $sec_index ne "new") { $thisfield .= qq~

View/download the current template~; } else { $thisfield .= qq~

[ Currently no template loaded. ]~; } $html .= &bmLib::box_it_headline( "Default Subsection Index Template$bmSection::required", $thisfield, "defindtem" ); $html .= qq~

Section Announcements

\n
~; # routine: edit_template======================================= # LOAD DEFAULT SUBSECTION ANNOUNCEMENT INFO (IF MAIN SECTION) # ============================================================= $ann_cols = "35"; $filename = $sec_index . "sub.annc"; ($sec_subannounce) = &bmLib::make_it_html_safe(&bmSection::LoadTemplate($filename)); $sec_subannounce = CGI::textarea(-name=> "sec_subannounce_form", -default=> $sec_subannounce, -rows=> 10, -columns=> $ann_cols, -class=> "plain"); $sec_subannounce = qq~Optional announcement appears on all subsection pages with templates that include the ANNOUNCE widget (except subsections where you have added a custom announcement)

[ HTML allowed ]
$sec_subannounce~; $sec_subannounce = qq~
\n
~ . &bmLib::box_it_headline( "Default Subsection Announcement", $sec_subannounce, "announce" ); # routine: edit_template======================================= # PREPARE HEADING FOR MAIN SECTION ANNOUNCEMENT # ============================================================= $thisfield = "Optional announcement appears on the main section page if the template uses the ANNOUNCE widget.

[ HTML allowed ]
"; $headline = "Main Section Page Announcement"; $sec_index .= "_0"; #this is just temporary } else { # routine: edit_template======================================= # PREPARE HEADING FOR SUBSECTION ANNOUNCEMENT # ============================================================= $html .= qq~

Section Announcement

\n
~; $ann_cols = "70"; $thisfield = "Optional announcement appears on all subsection pages whose templates use the ANNOUNCE widget. If left blank, Big Medium will use the default subsection announcement for the $bmSetup::SectionName{$p} section.

[ HTML allowed ]
"; $headline = "Custom Subsection Announcement"; } # routine: edit_template======================================= # BUILD FIELDS FOR ANNOUNCEMENTS # ============================================================= # Load the section's main html template file $filename = $sec_index . ".annc"; ($sec_announce) = &bmLib::make_it_html_safe(&bmSection::LoadTemplate($filename)); $thisfield .= CGI::textarea(-name=> "sec_announce_form", -default=> $sec_announce, -rows=> 10, -columns=> $ann_cols, -class=> "plain"); $html .= &bmLib::box_it_headline( $headline, $thisfield, "announce" ); $html .= $sec_subannounce . "
\n"; # routine: edit_settings======================================= # BUILD NAVIGATION IMAGE FIELDS # ============================================================= $html .= &bmSection::build_nav_fields( $sec_index, $h_image_type, $v_image_type, $h_dimensions, $v_dimensions); # routine: edit_settings======================================= # FINISH UP AND DISPLAY PAGE # ============================================================= $html .= &bmLib::box_it(qq~~); $html .= CGI::endform; &bmLib::bigmed_page( $bmSection::UserName, $bmSection::Privileges, $bmSetup::SiteName, $html, "templates", "section editor" ); } #end edit_settings routine sub save_settings { ############################################################### ## ROUTINE: save_settings ## ## This routine accepts, vets and saves section setting ## information, updating the main section info file with the ## latest info. ## ############################################################### # routine: save_settings======================================= # DECLARE VARIABLES # ============================================================= #section info my $sec_index = CGI::param("sec_index_form"); my $sec_name = CGI::param("sec_name"); my $sec_slug = CGI::param("sec_slug"); my $sec_alias = CGI::param("sec_alias"); my $sec_desc = CGI::param("sec_description"); my $sec_keys = CGI::param("sec_keywords"); my $sec_active = CGI::param("sec_active"); my @sec_suppress = CGI::param("sec_suppress"); my $suppress; #string of @sec_suppress checkboxes my $thisline; #data lines for sec and subsecs #template values my $sec_template = CGI::param("sec_template_form"); my $sec_subtemplate = CGI::param("sec_subtemplate_form"); my $sec_subindex = CGI::param("sec_subindex_form"); my @delete = CGI::param("delete"); #announcement info my $sec_announce = CGI::param("sec_announce_form"); my $sec_subannounce = CGI::param("sec_subannounce_form"); my $announce_dir; #base dir for section announcements #image info my %save_navimage; #subsection variables my $high_sub; #highest index of subsections my @subsections; #list of subsecs for this section #misc utility variables my $p; #parent section my $err_message; #helps give error message on slug name my $count; #counter steos thru parameter names my @sections; #used to read/write section index my $this_id; #reads id of each line of section index my $this_p; #parent of current line of section index my $updated; #indicates this section added to index my $filename; #holds filenames for template files my $filename2; #holds filename for subindex template my $mysection; #flags current section is being updated my @homeline; #used to load homepage data line # routine: save_settings======================================= # MAKE SURE THERE'S AVAILABLE DISK SPACE # ============================================================= &bmLib::DiskSpace("$bmSetup::DataDir/templates"); # routine: save_settings======================================= # MAKE SURE WE HAVE GOOD SECTION OR, IF NEW, ASSIGN ONE # ============================================================= # similar code does same thing in bm_sitesettings.pl # (copy_template_info routine) if ($sec_index eq "new") { #assign a number to this new section #find highest current section number and set one higher $sec_index = 0; foreach (@bmSetup::AllSections) { ($p) = split (/\_/); if ($p > $sec_index) { $sec_index = $p; } } $sec_index++; # make sure it's not a previously deleted section while ($bmSetup::SectionDeleted{$sec_index} eq "d") { $sec_index++; } } elsif ($sec_index eq "sub") { #assign a number to this new subsection #get current subsection info (will be overwritten below) $p = &bmSection::vet_index(CGI::param("mainsec")); ($high_sub, @subsections) = &bmLib::GetAllSubs($p); # get next subsection id, not previously deleted $high_sub++; while ($bmSetup::SectionDeleted{"$p\_$high_sub"} eq "d") { $high_sub++; } $sec_index = "$p\_$high_sub"; } else { #make sure we're editing a valid section $sec_index = &bmSection::vet_index($sec_index); } #get current subsection info ($high_sub, @subsections) = &bmLib::GetAllSubs($sec_index); # routine: save_settings======================================= # CLEAN UP VARIABLES, BLOCK TAMPERING, CHECK REQUIRED FIELDS # ============================================================= ( $sec_name, $sec_slug, $sec_desc, $sec_keys) = &bmVet::prep_for_simple_text( $sec_name, $sec_slug, $sec_desc, $sec_keys); &bmVet::is_field_empty ("Section name", $sec_name ); ($sec_alias) = &bmVet::scrub_bm_param($sec_alias); ($p) = split(/_/, $sec_index); if ($sec_index =~ /_/) { # adjust subsection to include main section name $sec_name = "$bmSetup::SectionName{$p}>$sec_name"; } else { #all main sections are on $sec_active = "on"; } $sec_active = "" if $sec_active ne "on"; $suppress = join("", @sec_suppress); $suppress =~ s/[^hnmsp]//g; #make sure we receive only valid values #h: home #n: top news #m: main page #s: syndication feeds #p: spotlight (promo) article # routine: save_announce======================================= # SCRUB ANNOUNCEMENT TEXT # ============================================================= ($sec_announce) = &bmVet::prep_for_html($sec_announce); $sec_announce =~ s/ /\n/g; ($sec_subannounce) = &bmVet::prep_for_html($sec_subannounce); $sec_subannounce =~ s/ /\n/g; # routine: save_settings======================================= # CONFIRM UNIQUE AND VALID SLUG NAME # ============================================================= $sec_slug = $sec_index if $sec_slug eq ""; &bmSection::vet_slug($sec_slug, "this section", $sec_index); $bmSetup::SectionSlug{$sec_index} = $sec_slug; # routine: save_settings======================================= # VET FILE UPLOADS # ============================================================= # $sec_template is the main section template for main sections # and the custom article template for subsections my $section_template_label = "section template"; $section_template_label = "article template" if index($sec_index, "_") > 0; ($sec_template, $sec_subtemplate, $sec_subindex ) = &bmSection::vet_text_file($section_template_label, $sec_template, "article template", $sec_subtemplate, "subsection index template", $sec_subindex ); # routine: save_settings======================================= # DELETE ANY TEMPLATES IF REQUESTED # ============================================================= foreach (@delete) { if (-e "$bmSetup::DataDir/templates/$_") { unlink "$bmSetup::DataDir/templates/$_" || die ("Could not unlink $bmSetup::DataDir/templates/$_. $!."); } } # routine: save_settings======================================= # MAKE SURE WE HAVE REQUIRED MAIN SECTION TEMPLATES # ============================================================= if ($sec_index !~ /_/) { $filename = $sec_index . "sub.template"; $filename2 = $sec_index . "ind.template"; #test if: it's not an aliased sections and one or more #templates is missing if ( $sec_alias eq "" && ( ( $sec_subtemplate eq "" && ! -e "$bmSetup::DataDir/templates/$filename" ) || ( $sec_template eq "" && ! -e "$bmSetup::DataDir/templates/$sec_index\_0.template" ) || ( $sec_subindex eq "" && ! -e "$bmSetup::DataDir/templates/$filename2" ) ) ) { &bmLib::bmHTML("Missing Template Info", "The main section template, the default article template, and the default subsection index template are all required. Please click your browser's Back button and supply all three templates."); } # routine: save_settings=================================== # SAVE SUBSECTION TEMPLATE # ========================================================= if ($sec_subtemplate ne "") { open (DATA, ">$bmSetup::DataDir/templates/$filename") or die("Unable to write to $bmSetup::DataDir/templates/$filename. $!."); flock(DATA, 2) or die("Could not do flock 2 exclusive lock for $bmSetup::DataDir/templates/$filename. $!."); print DATA "$sec_subtemplate\n"; close (DATA); chmod 0666, "$bmSetup::DataDir/templates/$filename"; } } # routine: save_settings======================================= # SAVE SUBSECTION INDEX TEMPLATE IF WE HAVE IT # ============================================================= if ($sec_subindex ne "") { $filename = $sec_index . "ind.template"; open (DATA, ">$bmSetup::DataDir/templates/$filename") or die("Unable to write to $bmSetup::DataDir/templates/$filename. $!."); flock(DATA, 2) or die("Could not do flock 2 exclusive lock for $bmSetup::DataDir/templates/$filename. $!."); print DATA "$sec_subindex\n"; close (DATA); chmod 0666, "$bmSetup::DataDir/templates/$filename"; } # routine: save_settings======================================= # UPDATE SECTION TEMPLATE IF SUBMITTED # ============================================================= if ($sec_template ne "") { $sec_index .= "_0" if $sec_index !~ /_/; #temporary for this file process open (DATA, ">$bmSetup::DataDir/templates/$sec_index.template") or die("Unable to write to $bmSetup::DataDir/templates/$sec_index.template. $!."); flock(DATA, 2) or die("Could not do flock 2 exclusive lock for $bmSetup::DataDir/templates/$sec_index.template. $!."); #exclusive lock for writing print DATA "$sec_template\n"; close (DATA); chmod 0666, "$bmSetup::DataDir/templates/$sec_index.template"; $sec_index =~ s/_0$//; } # routine: save_settings======================================= # VET AND SAVE NAVIGATION IMAGES # ============================================================= %save_navimage = &bmSection::vet_save_navimages($sec_index); # routine: save_settings======================================= # CREATE SECTION DIRECTORIES IF NECESSARY # ============================================================= &bmVet::check_directory( "$bmSetup::htmlDir/$bmSetup::SectionSlug{$p}" => "Main Section Directory" ); if ($sec_index =~ /_/ ) { &bmVet::check_directory( "$bmSetup::htmlDir/$bmSetup::SectionSlug{$p}/$bmSetup::SectionSlug{$sec_index}" => "Subsection Directory" ); } # routine: save_settings======================================= # SAVE SUBSECTION ANNOUNCEMENT TO DISK # ============================================================= #get announcement directory $announce_dir = $bmSetup::SectionSlug{$p}; if ($sec_index =~ /_/) { $announce_dir .= "/$bmSetup::SectionSlug{$sec_index}"; } else { #build a subannouncement for top-level articles, too unshift (@subsections, "$sec_index\_0"); } #remaining portion of saving subsection announcement only #relevant if editing a top-level section (subsections have no #subsections). #build filename for this announcement $filename = "$bmSetup::DataDir/templates/$sec_index" . "sub.annc"; #update subsection announce data file if ($sec_subannounce ne "") { open (SUBSECDATA, ">$filename") or die("Unable to write to $filename"); flock(SUBSECDATA, 2) or die("Could not do flock 2 exclusive lock for $filename. $!"); #exclusive lock for writing print SUBSECDATA "$sec_subannounce\n"; close (SUBSECDATA); chmod 0666, "$filename"; } elsif (-e "$filename") { unlink "$filename" || die("Could not unlink $filename. $!"); } #update announcement and quicktease includes in each subsection, #unless that section has a custom include foreach (@subsections) { my $slugdir; (undef, undef, $slugdir) = &bmLib::format_section_index($_); #make sure there's a subsection directory &bmVet::check_directory( "$bmSetup::htmlDir/$slugdir" => "Content Directory" ); $filename = "$bmSetup::htmlDir/$slugdir/subann.txt"; #make sure there's a quicktease include unless (-e "$bmSetup::htmlDir/$slugdir/quicktease.txt") { open (DATA, ">$bmSetup::htmlDir/$slugdir/quicktease.txt") || die ("Could not create empty quicktease include file at $bmSetup::htmlDir/$slugdir/quicktease.txt. $!."); flock (DATA,2) || die ("Could not do flock 2 exclusive lock on quicktease include file at $bmSetup::htmlDir/$slugdir/quicktease.txt. $!."); print DATA "\n"; close (DATA); chmod 0666, "$bmSetup::htmlDir/$slugdir/quicktease.txt"; } next if ( -e "$bmSetup::DataDir/templates/$_.annc" && $_ ne "$sec_index\_0" ); open (SUBINCLUDE, ">$filename") or die("Unable to write to $filename. $!."); flock(SUBINCLUDE, 2) or die("Could not do flock 2 exclusive lock for $filename. $!."); print SUBINCLUDE "$sec_subannounce\n"; close (SUBINCLUDE); chmod 0666, "$filename"; } #done with subsections #a bit of top-level tidying if ($sec_index !~ /_/) { $sec_index .= "_0" ; #temporary shift (@subsections); #take _0 directory of subsec list } # routine: save_settings======================================= # SAVE SECTION ANNOUNCEMENT TO DISK (OR DELETE) # ============================================================= if ($sec_announce ne "") { open (SECTIONDATA, ">$bmSetup::DataDir/templates/$sec_index.annc") or die("Unable to write to $bmSetup::DataDir/templates/$sec_index.annc. $!."); flock(SECTIONDATA, 2) or die("Could not do flock 2 exclusive lock for $bmSetup::DataDir/templates/$sec_index.annc. $!"); print SECTIONDATA "$sec_announce\n"; close (SECTIONDATA); chmod 0666, "$bmSetup::DataDir/templates/$sec_index.annc"; } elsif (-e "$bmSetup::DataDir/templates/$sec_index.annc") { unlink "$bmSetup::DataDir/templates/$sec_index.annc" || die("Could not unlink $bmSetup::DataDir/templates/$sec_index.annc. $!"); } if ($sec_index !~ /_0$/ && $sec_announce eq "") { #it's an empty subsection custom index; #get the default subsection index instead $filename = (split(/_/,$sec_index))[0] . "sub.annc"; ($sec_announce) = &bmSection::LoadTemplate($filename); } #update announcement include for section $filename = "$bmSetup::htmlDir/$announce_dir/"; $filename .= "sub" if $sec_index !~ /_0/; $filename .= "ann.txt"; open (SECINCLUDE, ">$filename") or die("Unable to write to $filename. $!."); flock(SECINCLUDE, 2) or die("Could not do flock 2 exclusive lock for $filename. $!."); print SECINCLUDE "$sec_announce\n"; close (SECINCLUDE); chmod 0666, "$filename"; $sec_index =~ s/_0$//; # routine: save_settings======================================= # MAKE SURE THERE'S A QUICKTEASE INCLUDE # ============================================================= unless (-e "$bmSetup::htmlDir/$announce_dir/quicktease.txt") { open (DATA, ">$bmSetup::htmlDir/$announce_dir/quicktease.txt") || die ("Could not create empty quicktease include file at $bmSetup::htmlDir/$announce_dir/quicktease.txt. $!."); flock (DATA,2) || die ("Could not do flock 2 exclusive lock on quicktease include file at $bmSetup::htmlDir/$announce_dir/quicktease.txt. $!."); print DATA "\n"; close (DATA); chmod 0666, "$bmSetup::htmlDir/$announce_dir/quicktease.txt"; } # routine: save_settings======================================= # UPDATE THIS SECTION'S LINES IN SECTION INDEX # ============================================================= $thisline .= $sec_index . " " . $sec_name . " " . $sec_desc . " " . $sec_keys . " " . $sec_active . " " . $sec_slug . " " . $suppress . " " . $save_navimage{"hnav_file"} . " " . $save_navimage{"hnav_url"} . " " . $save_navimage{"hnavroll_file"} . " " . $save_navimage{"hnavroll_url"} . " " . $save_navimage{"vnav_file"} . " " . $save_navimage{"vnav_url"} . " " . $save_navimage{"vnavroll_file"} . " " . $save_navimage{"vnavroll_url"} . " " . $sec_alias . "\n"; #Rebuild existing subsection lines, add to line for this section #(only applies to existing main sections) foreach (@subsections) { $thisline .= $_ . " " . "$sec_name>$bmSetup::SectionShort{$_}" . " " . $bmSetup::SectionDesc{$_} . " " . $bmSetup::SectionKeys{$_} . " " . $bmSetup::SectionActive{$_} . " " . $bmSetup::SectionSlug{$_} . " " . $bmSetup::SectionSuppress{$_} . " " . $bmSetup::SectionHFile{$_} . " " . $bmSetup::SectionHURL{$_} . " " . $bmSetup::SectionHrollFile{$_} . " " . $bmSetup::SectionHrollURL{$_} . " " . $bmSetup::SectionVFile{$_} . " " . $bmSetup::SectionVURL{$_} . " " . $bmSetup::SectionVrollFile{$_} . " " . $bmSetup::SectionVrollURL{$_} . " " . $bmSetup::SectionAlias{$_} . "\n"; } # routine: save_settings======================================= # WRITE THE UPDATED SECTIONS LIST TO SECTIONS.SETUP FILE # ============================================================= &bmLib::FileLock; #get current section data @sections = &bmLib::LoadFile("$bmSetup::DataDir/templates/Sections.setup"); @homeline = split(/ /, $sections[0]); if ($homeline[0] ne "h") { #the homepage settings have not been set yet; create the line unshift (@sections, "h $bmSetup::HomeLabel\ on"); } &bmVet::check_directory( "$bmSetup::DataDir/templates" => "Templates Directory" ); open (SECTIONFILE, ">$bmSetup::DataDir/templates/Sections.setup") or die("Unable to write to $bmSetup::DataDir/templates/Sections.setup. $!."); flock(SECTIONFILE, 2) or die("Could not do flock 2 exclusive lock. $!."); foreach (@sections) { ($this_id) = split(/ /); ($this_p) = split(/_/, $this_id); if ($this_id eq $sec_index || $this_id =~ /^$sec_index\_/) { next if $updated == 1; print SECTIONFILE "$thisline"; $updated = 1; next; } #if new subsection, note when we move out of main section #(if old subsection, would have updated line above) $mysection = 1 if ($this_p eq $p); if ($mysection == 1 && $this_p ne $p && $updated < 1) { print SECTIONFILE "$thisline"; $updated = 1; } print SECTIONFILE "$_\n"; } #if new section, add to end of list print SECTIONFILE "$thisline" if $updated < 1; close (SECTIONFILE); chmod 0666, "$bmSetup::DataDir/templates/Sections.setup"; &bmLib::FileUnlock; &bmLib::LoadSectionInfo; # routine: save_settings==================================== # UPDATE NAVIGATION SETTINGS # ========================================================== require "bm_navigation.pl"; &bmNav::create_nav_files; # routine: save_settings======================================= # GIVE CONFIRMATION MESSAGE AND SEND BACK TO MAIN MENU # ============================================================= &bmSection::section_menu(qq~
Settings for the $bmSetup::SectionName{$sec_index} section have been saved.
Announcement changes will appear on the live site immediately, but template or navigation changes will not appear on the live site until you rebuild pages.

Unless you are making other section changes, you should now rebuild all pages for the $bmSetup::SectionName{$p} section to see the changes reflected on the live site.~); } #end save_settings routine sub confirm_delete { ############################################################### ## ROUTINE: confirm_delete ## ## If user requests to delete a section or subsection, this ## routine throws up a warning message and asks for ## confirmation, offering an opportunity to cancel. ## ############################################################### # routine: confirm_delete====================================== # DECLARE VARIABLES # ============================================================= #sections to delete my @deletethese = CGI::param("delete"); #message info my $what_delete = "one or more subsections"; my $confirm_msg = CGI::start_form("post", "$bmSetup::BigMedURL/bm_sections.cgi"); my $confirm_list = "All checked sections will be deleted:
\n"; my $caveat = qq~

(If in doubt, click "Cancel" and consider making the section(s) inactive instead of deleting).

~; # routine: confirm_delete====================================== # RETURN TO SECTION MENU IF NOTHING TO DELETE # ============================================================= if (@deletethese == 0) { #nothing to do here &bmSection::section_menu; exit; } # routine: confirm_delete====================================== # BUILD CONFIRMATION MESSAGE # ============================================================= foreach (@deletethese) { if ($bmSetup::SectionName{$_} eq "") { &bmLib::bmHTML("Didn't Recognize a Section", "Your deletion request included a request to delete the section with index ID $_, but that section is not in the master index (perhaps you already deleted it?). Click here to return to the section editor."); } if ($_ !~ /_/) { #main section deletion request if (@deletethese > 1) { &bmLib::bmHTML("Too Many Sections", "Sorry, we cannot fulfill this request. You requested to delete multiple sections, including a main section. Main sections may only be deleted one at a time. Please return to the section editor to submit a properly formatted deletion request."); } $what_delete = "the entire $bmSetup::SectionName{$_} section and all of its subsections and contents"; $confirm_list = qq~\nDo you really want to do this?~; $caveat = ""; } else { #subsection deletion request $bmSetup::SectionName{$_} =~ s/>/>/; $confirm_list .= qq~
$bmSetup::SectionName{$_}\n~; } } # routine: confirm_delete====================================== # DISPLAY MESSAGE # ============================================================= $confirm_msg .= qq~

You have asked to delete $what_delete.

This will permanently remove all files, html templates and content related to the section(s). This cannot be undone.

$confirm_list

$caveat

  

~; &bmLib::bmHTML("PLEASE CONFIRM: This Cannot Be Undone", $confirm_msg); } #end confirm_delete subroutine sub do_section_delete { ############################################################### ## ROUTINE: do_section_delete ## ## This routine deletes sections and subsections that have ## been passed to the script via web form from the ## confirm_delete routine. ## ############################################################### # routine: do_section_delete=================================== # DECLARE VARIABLES # ============================================================= #sections to delete my @delete = CGI::param("delete"); my @secindex; #the section index file my @updated_sections; #the updated section index file my %delete_main; #marks main sections to be deleted my %delete_sub; #marks subsections to be deleted my $sec; #section added to updated sections list # routine: do_section_delete=================================== # RETURN TO SECTION MENU IF THERE ARE NO SECTIONS TO DELETE # ============================================================= if (@delete == 0) { &bmSection::section_menu(qq~

Your deletion request was canceled

~); exit; } if (@delete == 1 && $delete[0] !~ /_/) { # routine: do_section_delete=============================== # DELETE MAIN SECTIONS # ========================================================= &bmSection::delete_main(@delete); } else { # routine: do_section_delete=============================== # START SUBSECTION DELETION # ========================================================= foreach (@delete) { #be sure we're only dealing with subsections; #discard any main sections that are in the mix next if $_ !~ /_/ || $_ =~ /_0$/; $delete_sub{$_} = 1; } # routine: do_section_delete=============================== # UPDATE MASTER SECTION INDEX # ========================================================= &bmLib::FileLock; @secindex = &bmLib::LoadFile("$bmSetup::DataDir/templates/Sections.setup"); #add section lines to updated index unless marked for del foreach (@secindex) { ($sec) = split (/ /); push (@updated_sections, $_) if ($delete_sub{$sec} != 1); } # routine: do_section_delete=============================== # SAVE UPDATED INDEX TO DISK # ========================================================= open (SECTIONFILE, ">$bmSetup::DataDir/templates/Sections.setup") or die("Unable to write to $bmSetup::DataDir/templates/Sections.setup. $!."); flock(SECTIONFILE, 2) or die("Could not do flock 2 exclusive lock on $bmSetup::DataDir/templates/Sections.setup. $!."); foreach (@updated_sections) { print SECTIONFILE "$_\n"; } close (SECTIONFILE); chmod 0666, "$bmSetup::DataDir/templates/Sections.setup"; &bmLib::FileUnlock; # routine: do_section_delete=============================== # UPDATE DELETED SECTION LOG # ========================================================= open (DELETELIST, ">>$bmSetup::DataDir/deleted_sections.txt") or die("Unable to write to deleted section log at $bmSetup::DataDir/deleted_sections.txt. $!."); flock(DELETELIST, 2) or die("Could not do flock 2 exclusive lock on deleted section log at $bmSetup::DataDir/deleted_sections.txt. $!"); foreach (keys %delete_sub) { print DELETELIST "$_\n"; } close (DELETELIST); chmod 0666, "$bmSetup::DataDir/deleted_sections.txt"; # routine: do_section_delete=============================== # DELETE ALL ASSOCIATED FILES FOR THE SUBSECTIONS # ========================================================= &bmSection::delete_sub(@delete); # routine: do_section_delete================================ # UPDATE NAVIGATION SETTINGS # ========================================================== #reload section data to reflect updates &bmLib::LoadSectionInfo; require "bm_navigation.pl"; &bmNav::create_nav_files; # routine: do_section_delete=============================== # UPDATE ARTICLE DATA FILES # ========================================================= &bmSection::update_deleted_articledata(@delete); } } #end do_section_delete sub delete_main { ############################################################### ## ROUTINE: delete_main ## ## This routine deletes a main section, all of its subsections ## and all associated files and directories. ## ############################################################### # routine: delete_main========================================= # DECLARE VARIABLES # ============================================================= my $maindel = shift; #section to delete my @subs_to_delete; #subsections of this deleted section my @secindex; #the section index file my @updated_sections; #the new updated sections file my $sec; #section getting added to section index my $mainsec; #parent section of the section my $file; #filename of file to delete # routine: delete_main========================================= # UPDATE THE DELETED SECTIONS LOG # ============================================================= open (DELETELIST, ">>$bmSetup::DataDir/deleted_sections.txt") or die("Unable to write to deleted sections log at $bmSetup::DataDir/deleted_sections.txt. $!."); flock(DELETELIST, 2) or die("Could not do flock 2 exclusive lock on deleted sections log at $bmSetup::DataDir/deleted_sections.txt. $!."); print DELETELIST "$maindel\n"; close (DELETELIST); chmod 0666, "$bmSetup::DataDir/deleted_sections.txt"; # routine: delete_main========================================= # UPDATE SECTION INDEX, REMOVING SECTION AND SUBSECTIONS # ============================================================= &bmLib::FileLock; @secindex = &bmLib::LoadFile("$bmSetup::DataDir/templates/Sections.setup"); foreach (@secindex) { ($sec) = split (/ /); ($mainsec) = split (/\_/,$sec); push (@updated_sections, $_) if ($mainsec ne $maindel); } #end foreach # routine: delete_main========================================= # WRITE TO SECTION INDEX # ============================================================= open (SECTIONFILE, ">$bmSetup::DataDir/templates/Sections.setup") or die("Unable to write to section index at $bmSetup::DataDir/Sections.setup. $!."); flock(SECTIONFILE, 2) or die("Could not do flock 2 exclusive lock on section index at $bmSetup::DataDir/templates/Sections.setup. $!"); foreach (@updated_sections) { print SECTIONFILE "$_\n"; } close (SECTIONFILE); chmod 0666, "$bmSetup::DataDir/templates/Sections.setup"; &bmLib::FileUnlock; # routine: delete_main========================================= # DELETE THE SUBSECTIONS # ============================================================= (undef, @subs_to_delete) = &bmLib::GetAllSubs($maindel); &bmSection::delete_sub(@subs_to_delete); # routine: delete_main========================================= # DELETE MAIN SECTION TEMPLATES # ============================================================= foreach ( "_0.template", "sub.template", "ind.template", "_0.annc", "sub.annc") { if (-e "$bmSetup::DataDir/templates/$maindel$_") { unlink ("$bmSetup::DataDir/templates/$maindel$_") or die("Unable to unlink $bmSetup::DataDir/templates/$maindel$_. $!."); } } # routine: delete_main========================================= # DELETE MAIN DIRECTORY AND REMAINING CONTENTS # ============================================================= if (-e "$bmSetup::htmlDir/$bmSetup::SectionSlug{$maindel}" && $bmSetup::SectionSlug{$maindel}) { main::rmtree("$bmSetup::htmlDir/$bmSetup::SectionSlug{$maindel}", 0, 1); } # routine: delete_main====================================== # UPDATE NAVIGATION SETTINGS # ========================================================== #reload section data to reflect updates &bmLib::LoadSectionInfo; require "bm_navigation.pl"; &bmNav::create_nav_files; # routine: delete_main========================================= # UPDATE ARTICLE INDEX AND DATA FILES # ============================================================= &bmSection::update_deleted_articledata($maindel); } # End delete_main routine sub delete_sub { ############################################################### ## ROUTINE: delete_sub ## ## This routine deletes template and html files for ## the subsections whose ids are passed ## to the routine in an array. (Article data is updated ## elsewhere, ## ############################################################### # routine: delete_sub========================================== # DECLARE VARIABLES # ============================================================= my (@sections) = @_; #subsections to delete my $p; #parent section of each section my $html_delete; #html directory of each section my $file; #filename to delete my $del_sec; #current section to delete foreach (@sections) { #be sure we're only dealing with subsections; #discard any main sections next if $_ !~ /_/ || $_ =~ /_0$/; $del_sec = $_; # routine: delete_sub====================================== # DELETE CUSTOM SUBSECTION TEMPLATES IF ANY # ========================================================= foreach (".template", ".annc", "ind.annc") { if (-e "$bmSetup::DataDir/templates/$del_sec$_") { unlink ("$bmSetup::DataDir/templates/$del_sec$_"); } } # routine: delete_sub====================================== # DELETE HTML DIRECTORY AND CONTENTS # ========================================================= ($p) = split (/_/, $del_sec); #parent section $html_delete = "$bmSetup::htmlDir/$bmSetup::SectionSlug{$p}/$bmSetup::SectionSlug{$del_sec}"; if (-e "$html_delete" && $bmSetup::SectionSlug{$del_sec}) { # delete the entire html directory and its contents main::rmtree("$html_delete", 0, 1); } } } #end delete_subsection routine sub LoadTemplate { ############################################################### ## ROUTINE: LoadTemplate ## ## Similar to the LoadFile routine in bm_lib.pl but this one ## loads in a single scalar variable instead of an array ## of lines from the file. Also, only loads files from ## the site's templates directory. ## ############################################################### # routine: LoadTemplate======================================== # DECLARE VARIABLES # ============================================================= my $filename = shift; my $file_contents; $filename = "$bmSetup::DataDir/templates/$filename"; &bmLib::CheckBadChars($filename); undef $/; #put into slurp mode to read whole file as single line if (-e "$filename") { open (DATA, "$filename") or die( "Could not open $filename. $!"); flock(DATA, 1) or die("Could not do flock 1 shared lock on $filename. $!"); $file_contents = ; close (DATA); } $/ = "\n"; #return to regular mode to read file as array $file_contents; } #end LoadTemplate routine sub display_template { ############################################################### ## ROUTINE: display_template ## ## This routine loads one of the page templates, converts all ## html into entities and displays as html within a browser. ## ############################################################### # routine: display_template==================================== # DECLARE VARIABLES # ============================================================= my $sec_index = CGI::param("template"); my $type = CGI::param("t"); my $filename; my $file; #make sure that we have a valid section if ($sec_index ne "h") { $sec_index = &bmSection::vet_index($sec_index); } my %template = ("" => "homepage template", "t" => "section template for the $bmSetup::SectionShort{$sec_index} section", "s" => "default subsection template for the $bmSetup::SectionShort{$sec_index} section", "i" => "custom subsection index template for the $bmSetup::SectionShort{$sec_index} section" ); # routine: display_template==================================== # LOAD TEMPLATE # ============================================================= if ($sec_index eq "h") { #homepage template $file = &bmSection::LoadTemplate("home.template"); } elsif ($type eq "t") { #section template $sec_index .= "_0" if $sec_index !~ /_/; $file = &bmSection::LoadTemplate("$sec_index.template"); } elsif ($type eq "s") { #default subsection template $filename = $sec_index . "sub.template"; $file = &bmSection::LoadTemplate($filename); } elsif ($type eq "i") { #custom subsection index $filename = $sec_index . "ind.template"; $file = &bmSection::LoadTemplate($filename); } else { &bmLib::bmHTML("Didn't Understand", "Could not complete your request, because of a formatting problem. It appears that the \"t\" parameter in the URL is invalid."); } # routine: display_template==================================== # DISPLAY HTML-SAFE TEMPLATE IN BROWSER # ============================================================= if ($file eq "") { &bmLib::bmHTML("No Template Loaded", "Sorry, there is no $template{$type} to display."); } ($file) = &bmLib::make_it_html_safe($file); print qq~Content-type: text/html; charset=UTF-8\n\n \n \u$template{$type}
$file
\n~; } #end display_template routine sub vet_index { ############################################################### ## ROUTINE: vet_index ## ## This routine scrubs an index number to make sure that it ## is valid. ############################################################### my $sec_index = shift; #make sure that only numbers and underscore are in section id $sec_index =~ s/[^\d_]//g; if ($sec_index eq "") { &bmLib::bmHTML("Invalid Section", "Unable to load the section information for the requested section. The submitted section does not appear to be valid. Consult your website administrator if you continue to receive this message."); } if ($bmSetup::SectionName{$sec_index} eq "") { &bmLib::bmHTML("Invalid Section", "Could not locate a record of a section with index $sec_index. It does not appear to exist. If you believe this is an error, consult your website administrator."); } return $sec_index; } #end vet_index routine sub vet_text_file { ############################################################### ## ROUTINE: vet_text_file ## ## This routine checks an array of CGI file upload params and ## confirms that they're UTF-8 text files. ## ## Input: ## Array alternating text label ($type) with CGI param. ## ## Returns the files as an array of scrubbed values. ## ############################################################### # routine: vet_text_file======================================= # DECLARE VARIABLES # ============================================================= my (@files) = @_; my $mime; # mime type (must be text/plain or text/html) my $info_hash; # header info of passed file my $clean; # scrubbed file contents my $type; #the description of the file being parsed my $file; #the filehandle of the file being parsed my @results; #the array of file contents returned # routine: vet_text_file======================================= # STEP THROUGH FILES TO CHECK # ============================================================= while (@files) { $type = shift(@files); $file = shift(@files); if ($file eq "") { #only do it if we have an upload push (@results, undef); next; } #get and confirm mime type $info_hash = CGI::uploadInfo($file); $mime = $info_hash->{'Content-Type'}; if ( $mime ne "text/plain" && $mime ne "text/html" && $mime ne "" ) { &bmLib::bmHTML ("Templates Must Be Text Files", "The $type file you submitted was not a plain text file (you sent a file of type: $mime). Please click your browser's Back button to select a different file."); } undef $/; #read whole file as single line $clean = <$file>; $/ = "\n"; #return to regular mode close ($file); #make sure that the file is UTF-8 my $encoding = &bmLib::check_utf8(0, $clean); if ($encoding ne "UTF-8") { &bmLib::bmHTML("Bad characters in $type", qq~The $type you submitted appears to contain characters that are not encoded in the UTF-8 format of Unicode, the Web's international alphabet. To fix the problem, review this checklist:

After making appropriate changes, please click your browser's Back button to try again.

Need help? Visit the Global Moxie support forums.

~); } #clean file and convert to unix line feeds ($clean) = &bmVet::prep_for_html($clean); $clean =~ s/ /\n/g; push (@results, $clean); } @results; } #end vet_text_file routine sub vet_slug { ############################################################### ## ROUTINE: vet_slug ## ## This routine checks the format and uniqueness of section ## slugs submitted through the section settings page for ## new or existing sections and subsections. ## ############################################################### # routine: vet_slug============================================ # DECLARE VARIABLES # ============================================================= my ($newslug, $type, $newid) = @_; my $err_message; # routine: vet_slug============================================ # CHECK SLUG FORMAT # ============================================================= if ($newslug =~ /[^a-zA-Z0-9_\-]/) { ($newslug) = &bmLib::make_it_html_safe($newslug); &bmLib::bmHTML("

Please Choose Another Slug Name", "Sorry, you cannot use the slug $newslug for $type. The slug for your new subsections must be only one word and may contain only letters, numbers, hyphens (-) and underscores (_). The slug is used as the name of the directory in which all the subsection articles are stored and also for the Web address of all subsection articles.

Please click your browser's Back button to review your entry.

"); } # routine: vet_slug============================================ # CHECK VALID LENGTH FOR SLUG # ============================================================= if (length($newslug) > 250) { &bmLib::bmHTML("Slug Name Too Long", "The slug for $type is too long. Slugs may not be longer than 250 characters. Please click your browser's Back button to review your entry."); } # routine: vet_slug============================================ # CHECK ILLEGAL NAMES # ============================================================= if ( $newslug eq "bmadmin" || $newslug eq "tips" || $newslug eq "moxiepix" || $newslug eq "bigmed_pix" || $newslug eq "affiliate" || $newslug eq "rssLatest") { &bmLib::bmHTML("Reserved Slug Name", "Sorry, you cannot use the slug $newslug for $type because Big Medium reserves that directory name for administrative purposes. This list of slugs are reserved:Please click your browser's Back button to review your entry."); } # routine: vet_slug============================================ # CHECK UNIQUENESS # ============================================================= #use allsections instead of sections array foreach (@bmSetup::AllSections) { if ( $bmSetup::SectionSlug{$_} eq $newslug && $_ ne $newid && $_ ne "$newid\_0" ) { if ($newslug eq $newid) { $err_message= " If you left the slug field blank, Big Medium tried to use the unique section ID as a slug but ran into this problem. "; } &bmLib::bmHTML("Duplicate Section Slug", "You tried to assign the slug name $newslug to $type, but it has already been assigned to another section ($bmSetup::SectionName{$_}). $err_message Please click your browser's Back button and select a slug that has not been assigned to another section.

Not sure what a section slug is? Click here for help."); } } } #end vet_slug routine sub build_nav_fields { ############################################################### ## ROUTINE: build_nav_fields ## ## This routine builds edit forms for a set of horizontal ## and vertical navigation elements. ## ############################################################### # routine: build_nav_fields==================================== # DECLARE VARIABLES # ============================================================= my ( $sec_index, $h_image_type, $v_image_type, $h_dimensions, $v_dimensions ) = @_; my ($toggle, $toggle_tabs); my $html = qq~

Navigation Images

\n~; my $thisfield = "These optional images are used in pages using the $h_image_type widget for creating graphical navigation bars."; if ($bmSetup::SectionHFile{$sec_index} || $bmSetup::SectionHURL{$sec_index} || $bmSetup::SectionHrollFile{$sec_index} || $bmSetup::SectionHrollURL{$sec_index}) { $html .= qq~\n
~; } else { $toggle = "himage"; $toggle_tabs .= qq~
  • Horizontal Navigation
  • \n~; } # routine: build_nav_fields==================================== # BUILD HORIZONTAL NAVIGATION IMAGE FIELD # ============================================================= $thisfield .= &bmLib::build_image_entry ( "horizontal navigation", $bmSetup::SectionHFile{$sec_index}, $bmSetup::SectionHURL{$sec_index}, "hnav", $h_dimensions, "The clickable image in the horizontal nav bar"); $thisfield .= qq~
    * * *
    ~; $thisfield .= &bmLib::build_image_entry ( "rollover", $bmSetup::SectionHrollFile{$sec_index}, $bmSetup::SectionHrollURL{$sec_index}, "hnavroll", $h_dimensions, "The rollover image for the horizontal nav bar"); $html .= &bmLib::box_it_headline("Horizontal Navigation Images", $thisfield, "navimages", undef, $toggle ); $html .= "
    \n" unless $toggle; # routine: build_nav_fields==================================== # BUILD VERTICAL NAVIGATION IMAGE FIELD # ============================================================= undef $toggle; if ($bmSetup::SectionVFile{$sec_index} || $bmSetup::SectionVURL{$sec_index} || $bmSetup::SectionVrollFile{$sec_index} || $bmSetup::SectionVrollURL{$sec_index}) { $html .= qq~\n
    ~; } else { $toggle = "vimage"; $toggle_tabs .= qq~
  • Vertical Navigation
  • \n~; } $thisfield = "These optional images are used in pages using the $v_image_type widget for creating graphical navigation bars."; $thisfield .= &bmLib::build_image_entry ( "vertical navigation", $bmSetup::SectionVFile{$sec_index}, $bmSetup::SectionVURL{$sec_index}, "vnav", $v_dimensions, "The clickable image in the vertical nav bar"); $thisfield .= qq~
    * * *
    ~; $thisfield .= &bmLib::build_image_entry ( "rollover", $bmSetup::SectionVrollFile{$sec_index}, $bmSetup::SectionVrollURL{$sec_index}, "vnavroll", $v_dimensions, "The rollover image for the vertical nav bar"); $html .= &bmLib::box_it_headline("Vertical Navigation Images", $thisfield, "navimages", undef, $toggle); $html .= "
    \n" unless $toggle; if ($toggle_tabs) { $html .= qq~\n
    \n~; $toggle_tabs = ""; } return $html; } #end build_nav_fields routine sub vet_save_navimages { ############################################################### ## ROUTINE: vet_save_navimages ## ## This routine steps through the four types of navigation ## images submitted, deletes any if requested, and passes ## off to the vet_save_image routine to confirm validity ## and save to disk. ## ############################################################### # routine: vet_save_navimages================================== # DECLARE VARIABLES # ============================================================= my ($sec_index) = @_; my %nav_image; my $error; my %images = ( "hnav" => "horizontal navigation", "hnavroll" => "horizontal navigation rollover", "vnav" => "vertical navigation", "vnavroll" => "vertical navigation rollover"); my %oldfile = ("hnav" => $bmSetup::SectionHFile{$sec_index}, "hnavroll" => $bmSetup::SectionHrollFile{$sec_index}, "vnav" => $bmSetup::SectionVFile{$sec_index}, "vnavroll" => $bmSetup::SectionVrollFile{$sec_index}); my %oldurl = ( "hnav" => $bmSetup::SectionHURL{$sec_index}, "hnavroll" => $bmSetup::SectionHrollURL{$sec_index}, "vnav" => $bmSetup::SectionVURL{$sec_index}, "vnavroll" => $bmSetup::SectionVrollURL{$sec_index}); foreach (sort keys %images) { #sort in alpha order (hnav, hnavroll, vnav, vnavroll) #get the submitted values my $got_image = &bmVet::clean_image_file(CGI::param("got_$_\_image")); my $image_file = CGI::param("art_$_" . "image"); my $delete_image = CGI::param("delete$_" . "image"); my $got_url = CGI::param("goturl_$_\_image"); my $url_check = CGI::param("art_$_" . "urlcheckbox"); my $image_url = CGI::param("art_$_" . "imageurl"); #vet any submitted image url ($image_url) = &bmVet::scrub_bm_param( &bmVet::check_remote_image( "$images{$_}", $url_check, $image_url )); #Use a high image limit of 1000K for image size limit and #assume webmaster knows what they're doing ( $nav_image{"$_\_file"}, $nav_image{"$_\_url"}, $nav_image{"$_\_err"} ) = &bmVet::resolve_image($image_file, "$images{$_}", 1000, $sec_index, $got_image, $delete_image, $image_url, $got_url, $url_check, $oldfile{$_}, $oldurl{$_}, $_); if ($nav_image{"$_\_err"}) { $error .= qq~
  • $nav_image{"$_\_err"}~; } else { delete $nav_image{"$_\_err"}; #Delete image file if not needed and no error if ($nav_image{"$_\_file"} eq "" && $got_image && -e "$bmSetup::ImageDir/$got_image" ) { unlink ("$bmSetup::ImageDir/$got_image") || die ("Could not unlink $bmSetup::ImageDir/$got_image. $!."); } } } #Do error messages if ($error) { &bmLib::bmHTML("Problem with Image File", qq~We encountered some trouble with one or more files that you uploaded:Please click your browser's Back button to fix the problem(s).~); } return %nav_image; } #end vet_save_navimages sub update_deleted_articledata { ############################################################### ## ROUTINE: update_deleted_articledata ## ## Routine updates article index and article data files ## as part of the deletion of a main section and/or one or ## more subsections. ## ## This routine is usually called multiple times, stepping ## through all of the site's articles in batches defined in ## size by $bmSetup::BatchProcess. After each batch, a html ## page with a meta-refresh tag is displayed, so the routine ## continues to update pages. ## ## As it goes through, the routine removes references in ## the master index file and article data files to the ## deleted sections. Articles that belonged *only* to deleted ## sections are removed from master index and their data ## files deleted. HTML files are not dealt with here, ## because the main section deleting routines deal with those. ## ############################################################### # routine: update_deleted_articledata========================== # DECLARE VARIABLES # ============================================================= #sections to delete my @delete_sec = @_; #counting variables my $start_delete_num = CGI::param("start_delete_num"); my $end_delete_num = $start_delete_num + $bmSetup::BatchProcess -1; my $i; #steps through the master index array my $removed_articles; #adjusts next start number #article info my @masterindex; #master article index array my $masterfile; #contents of updated master index my @update_articles; #article data files to be updated my @liners; #complete article info for each line my @line_sec; #sections to which article belongs my @newsecs; #updated sections for articles my $newsecs; #updated list, in string form my %revised_sections; #hash of $newsecs info for articles #message variables my $remaining; #number of articles left to scan my $confirm_msg; my $section_insert; #url parameters for the refresh url #misc utility variables my %sub_del; #subsections to delete my %main_del; #main sections to delete my $num_sections = @delete_sec; #number of sections to delete my $update; #marks article data file needs updating my @file; #holds the article data file contents # routine: update_deleted_articledata========================== # COLLECT SECTIONS TO DELETE FROM CONTINUING PROCESSES # ============================================================= if (@delete_sec == 0) { $num_sections = CGI::param("num"); for (1..$num_sections) { push (@delete_sec, CGI::param("d$_")); } } # routine: update_deleted_articledata========================== # MARKS SECTIONS TO DELETE # ============================================================= foreach (@delete_sec) { $sub_del{$_} = 1; #delete this subsection $main_del{$_} = 1 if $_ !~ /_/; #delete this main section } # routine: update_deleted_articledata========================== # LOAD MASTER SECTIONS INDEX # ============================================================= &bmLib::FileLock; @masterindex = &bmLib::LoadFile("$bmSetup::DataDir/articles/masterindex.cgi"); if ($end_delete_num >= @masterindex) { $end_delete_num = @masterindex - 1; } # routine: update_deleted_articledata========================== # STEP THROUGH CURRENT BATCH OF ARTICLES # ============================================================= #number per batch defined by $bmSetup::BatchProcess $i = $start_delete_num -1; if ($start_delete_num > 0) { #we're continuing a delete; get the list so far as a string $masterfile = join("\n", @masterindex[0..$i], "") } #start stepping while ($i<$end_delete_num) { $i++; undef @newsecs; undef $update; @liners = split (/ /,$masterindex[$i]); # routine: update_deleted_articledata====================== # STEP THROUGH ARTICLE'S SECTIONS TO CHECK FOR UPDATES # ========================================================= @line_sec = split (/\|/, $liners[4]); foreach (@line_sec) { if ( $sub_del{$_} == 1 || $main_del{(split(/_/,$_))[0]} == 1 ) { #this article has a deleted section #mark for updating $update = 1; } else { #this section is okay; add to this article's #new sections list push (@newsecs, $_); } } if ($update) { # routine: update_deleted_articledata====================== # AT LEAST ONE DELETED SECTION FOUND FOR THIS ARTICLE # ========================================================= $newsecs = join("\|", @newsecs); if ($newsecs eq "") { # routine: update_deleted_articledata================== # ARTICLE NO LONGER BELONGS TO ANY SECTIONS # ===================================================== #delete article data file if ( -e "$bmSetup::DataDir/articles/$liners[0]\.cgi") { unlink ("$bmSetup::DataDir/articles/$liners[0]\.cgi") or die "Unable to unlink article data file $bmSetup::DataDir/articles/$liners[0].cgi. $!."; } #delete image files #(body images are left behind in this version) foreach ("s", "t", "a") { if ( -e "$bmSetup::ImageDir/$_$liners[0]\.jpg") { unlink ("$bmSetup::ImageDir/$_$liners[0]\.jpg") or die "Unable to unlink article image file $bmSetup::ImageDir/$_$liners[0]\.jpg. $!."; } if ( -e "$bmSetup::ImageDir/$_$liners[0]\.gif") { unlink ("$bmSetup::ImageDir/$_$liners[0]\.gif") or die "Unable to unlink article image file $bmSetup::ImageDir/$_$liners[0]\.gif. $!."; } } # delete document files if any if ($liners[8] eq "Doc" && $liners[9]) { if (-e "$bmSetup::DataDir/unpubdocs/$liners[9]") { unlink ("$bmSetup::DataDir/unpubdocs/$liners[9]") or die ("Could not delete document file at $bmSetup::DataDir/unpubdocs/$liners[9]. $!."); } if (-e "$bmSetup::htmlDir/bm~doc/$liners[9]") { unlink ("$bmSetup::htmlDir/bm~doc/$liners[9]") or die ("Could not delete document file at $bmSetup::htmlDir/bm~doc/$liners[9]. $!."); } } #don't add back to master index file; #add to count of deleted articles $removed_articles++; } else { # routine: update_deleted_articledata================== # ARTICLE HAD DELETED SECTIONS, BUT STILL HAS VALIDS # ===================================================== #add to articles that need updating push (@update_articles, $liners[0]); #repLace art_sections with revised section info $liners[4] = $newsecs; $masterfile .= join(" ", @liners) . "\n"; #this hash used to update the article data files: $newsecs =~ s/\|/ /g; $revised_sections{$liners[0]} = $newsecs; } } # end test for updates else { #no changes, add to masterfile $masterfile .= "$masterindex[$i]\n"; } } # end stepping through lines of the master index # routine: update_deleted_articledata============================== # APPEND REMAINING ARTICLES IF MORE REMAIN # ================================================================= $i++; $masterfile .= join("\n",@masterindex[$i..(@masterindex-1)]); $masterfile =~ s/\s*$/\n/; $masterfile = "" if $masterfile eq "\n"; # routine: update_deleted_articledata============================== # WRITE UPDATED MASTER INDEX TO DISK # ================================================================= open (MASTERINDEX, ">$bmSetup::DataDir/articles/masterindex.cgi") or die("Unable to write to $bmSetup::DataDir/articles/masterindex.cgi. $!."); flock(MASTERINDEX, 2) or die("Could not do flock 2 exclusive lock on master index at $bmSetup::DataDir/articles/masterindex.cgi. $!."); print MASTERINDEX $masterfile; close (MASTERINDEX); chmod 0666, "$bmSetup::DataDir/articles/masterindex.cgi"; &bmLib::FileUnlock; # routine: update_deleted_articledata============================== # UPDATE ALL ARTICLE DATA FILES MARKED FOR CHANGES # ================================================================= foreach (@update_articles) { @file = &bmLib::LoadFile("$bmSetup::DataDir/articles/$_.cgi"); #replace old section line with new list $file[6]= $revised_sections{$_}; open (DATA, ">$bmSetup::DataDir/articles/$_.cgi") or die("Could not write to $bmSetup::DataDir/articles/$_.cgi. $!."); flock(DATA, 2) or die("Could not do flock 2 exclusive lock on $bmSetup::DataDir/articles/$_.cgi. $!."); print DATA join("\n",@file ,""); close (DATA); chmod 0666, "$bmSetup::DataDir/articles/$_.cgi"; } # routine: update_deleted_articledata============================== # GIVE PROGRESS UPDATE # ================================================================= $end_delete_num++; $remaining = @masterindex - $end_delete_num; $end_delete_num = $end_delete_num - $removed_articles; if ($remaining < 1) { # We're all done, bump back to the main sections menu if (keys %main_del) { $confirm_msg = $bmSetup::SectionName{(keys %main_del)[0]}; $confirm_msg = qq~

    The $confirm_msg section and all of its contents have been permanently deleted. Unless you have other section changes to make, you should now rebuild all pages for all sections.

    ~; &bmLib::LoadSectionInfo; &bmSection::section_menu($confirm_msg); exit; } else { $confirm_msg = qq~

    The subsection(s) you indicated have been permanently deleted, and all of your other changes have been saved. Unless you have other section changes to make, you should now rebuild all pages for the parent section(s) of the deleted subsection(s). Click here for the Rebuild Pages menu.

    ~; &bmLib::LoadSectionInfo; &bmSection::section_menu($confirm_msg); exit; } } else { # set up a meta refresh page to keep coming back to this # routine until we've scanned all articles if (keys %main_del) { $confirm_msg = $bmSetup::SectionName{(keys %main_del)[0]} . " section"; } else { $confirm_msg = "the subsection(s) you indicated"; } $i = 0; foreach (@delete_sec) { $i++; $section_insert .= "&d$i=$_"; } $confirm_msg = qq~We have deleted all html files, directories and templates for the $confirm_msg, and we are now updating the article data files and the image directory to reflect these changes.

    $remaining articles remaining to scan...~; &bmLib::bmHTML("PLEASE STAND BY: Updating article data files...", $confirm_msg, "$bmSetup::BigMedURL/bm_sections.cgi?ContinueDelete=delete&num=$num_sections&start_delete_num=$end_delete_num&$section_insert"); } } # end update_deleted_articledata routine sub rearrange_secs { ############################################################### ## ROUTINE: rearrange_secs ## ## Routine presents a form to allow user to reorder all main ## sections, or the subsections of a single main section. ## ############################################################### # routine: rearrange_secs====================================== # DECLARE VARIABLES # ============================================================= my $section = CGI::param("move"); my @sections; #list of sections to rearrange #html variables my $html; #html to display my $thisfield; #html for form field my $label; #type of sections to rearrange #misc utility variables my $order; #holds current order # of the subsection list # routine: rearrange_secs====================================== # GET ARRAY OF SECTIONS TO REARRANGE # ============================================================= if ($section eq "main") { #get all main sections, including aliased sections foreach (@bmSetup::AllSections) { push (@sections, $_) if $_ !~ /_/; } $label = "Main Sections"; } else { #get all subsections (including aliases) of the main section foreach (@bmSetup::AllSections) { push (@sections, $_) if $_ =~ /^$section\_/; } $label = "Subsections of the $bmSetup::SectionName{$section} section"; } # routine: rearrange_secs====================================== # BUILD THE PAGE THE PAGE # ============================================================= CGI::autoEscape(undef); # turn off auto-escaping in forms $html = CGI::start_form("post", "bm_sections.cgi"); $html .= qq~\n
    ~; $thisfield = qq~

    Select a new order for the ~ . lc($label) . qq~. This determines the order in which the sections appear in navigation bars.

    \n~; for (1..@sections) { $order = $_; $thisfield .= qq~
    $bmSetup::SectionShort{$sections[$order-1]}
    ~); $html .= "
    " . CGI::endform; &bmLib::bigmed_page( $bmSection::UserName, $bmSection::Privileges, $bmSetup::SiteName, $html, "templates", "section editor"); } #end rearrange_secs routine sub do_rearrange { ############################################################### ## ROUTINE: do_rearrange ## ## Routine accepts the values passed in from the ## rearrange_secs web form and updates the section index ## to display the revised section order. ## ############################################################### # routine: do_rearrange======================================== # DECLARE VARIABLES # ============================================================= my $section = CGI::param("movesec"); my @sections; #sections to rearrange my %order; #key:section; value:order # my @new_order; #holds order of sections, then content my %main_sec; #all sec/subsec lines of each main section my @secindex; #current section index file #misc utility variables my $this; #holds the current line info my $main; #main section of current line my $confirm_msg; #the confirmation message returned to the user # routine: do_rearrange======================================== # QUIT IF NO SECTION # ============================================================= if ($section ne "main" && $section =~ /[^\d_]/) { &bmHTML("Sorry, Didn't Understand", "The format of the sections you asked to rearrange does not appear to be correct. Please click your browser's Back button to review your entry."); } # routine: do_rearrange======================================== # GET ARRAY OF SECTIONS TO REARRANGE # ============================================================= if ($section eq "main") { foreach (@bmSetup::AllSections) { push (@sections, $_) if $_ !~ /_/; } } else { foreach (@bmSetup::AllSections) { push (@sections, $_) if $_ =~ /^$section\_/; } } # routine: do_rearrange======================================== # FIGURE OUT REVISED ORDER # ============================================================= # Don't trust that the user passed unique values for each section foreach (@sections) { $order{$_} = CGI::param("sec$_"); } #Put into new order; if there are dupes, a "tie" is settled #by making the section that came first in the old order #first in the new order $new_order[0] = "main"; #placeholder for main section line for (1..@sections) { $this = $_; foreach (@sections) { push (@new_order, $_) if $order{$_} == $this; } } #make sure didn't miss any; shouldn't happen, but to be safe... foreach (@sections) { push (@new_order, $_) if $order{$_} < 1 || $order{$_} > @sections; } #update hash with proper pointers; #hash keys are sections, values are order for (1..@new_order) { $order{$new_order[$_]} = $_; } # routine: do_rearrange======================================== # PUT DATA LINES FROM CURRENT INDEX INTO HASHES BY MAIN SECTION # ============================================================= &bmLib::FileLock; @secindex= &bmLib::LoadFile("$bmSetup::DataDir/templates/Sections.setup"); foreach (@secindex) { ($this) = split(/ /); ($main) = split(/_/, $this); $main_sec{$main} .= "$_\n"; #these apply only to subsection rearrangement #(since $section is "main" for main section rearrangement): if ($this eq $main && $main eq $section) { #main section line of section we're rearranging #put this at the head of the new_order array $new_order[0] = $_; } elsif ($section eq $main) { #one of the subsections we're rearranging $new_order[$order{$this}] = $_; } } # routine: do_rearrange======================================== # RELOAD @new_order WITH NEW MAIN SECTION ORDER # ============================================================= #all main section and subsection info is now stored in hashes #with main section as key; all that's needed is to step through #the order of the main sections and pour in this hash data. #that's what the new new_order routine will provide. if ($section ne "main") { #put subsections in current order within the main section $main_sec{$section} = ""; foreach (@new_order) { $main_sec{$section} .= "$_\n"; } #now replace @new_order with current main section order undef @new_order; foreach (@bmSetup::AllSections) { push (@new_order, $_) if $_ !~ /_/; } } else { #this is a main section rearrangement; #get rid of the main line placeholder shift @new_order; } # routine: do_rearrange======================================== # MAKE SURE THERE'S AVAILABLE DISK SPACE # ============================================================= #don't need much, 512k should be fine &bmLib::DiskSpace("$bmSetup::DataDir/templates", 512); # routine: do_rearrange======================================== # REBUILD SECTION INDEX AND WRITE TO DISK # ============================================================= open (SECTIONFILE, ">$bmSetup::DataDir/templates/Sections.setup") or die("Unable to write to section index at $bmSetup::DataDir/templates/Sections.setup. $!."); flock(SECTIONFILE, 2) or die("Could not do flock 2 exclusive lock on section index at $bmSetup::DataDir/templates/Sections.setup. $!"); print SECTIONFILE $main_sec{"h"}; foreach (@new_order) { print SECTIONFILE $main_sec{$_}; } close (SECTIONFILE); chmod 0666, "$bmSetup::DataDir/templates/Sections.setup"; &bmLib::FileUnlock; # routine: do_rearrange======================================== # CONFIRMATION MESSAGE # ============================================================= if ($section eq "main") { $confirm_msg = qq~
    The main sections of the site have been reordered. Unless you are making other section changes, you should now rebuild all pages of all sections to make these changes visible on the live site.~; } else { $confirm_msg = qq~
    The main subsections of the $bmSetup::SectionName{$section} section have been reordered. Unless you are making other section changes, you should now rebuild all pages of the section to make these changes visible on the live site.~; } # routine: do_rearrange======================================== # RELOAD SECTION INFO AND KICK OVER TO SECTION MENU # ============================================================= &bmLib::LoadSectionInfo; require "bm_navigation.pl"; &bmNav::create_nav_files; &bmSection::section_menu($confirm_msg); } #end do_rearrange routine sub edit_newsfeeds { ############################################################### ## ROUTINE: edit_newsfeeds ## ## Displays a checkbox interface to allow users to select ## which sections should offer news feeds. ## ############################################################### #no need to do utf8 on this form, it's all ascii my $html = qq~

    You can offer multiple news feeds to allow your visitors to subscribe to very general or very focused content on your site. Check the news-feed content you would like to offer, and click the "Save" button at the bottom of the list:

    \n~; my $sublist = 0; #display the homepage line $html .= qq~

    Latest articles from the entire site

    News feeds for the latest articles from specific sections:

    \n~; #display all of the sections foreach (@bmSetup::SectionIndex) { if ($sublist == 0 && index($_, "_") >= 0) { #first subsection $html .= qq~
    • ~; $sublist = 1; } elsif ($sublist == 1 && index($_, "_") < 0){ #first main section after a subsection $html .= qq~
    \n

    ~; $sublist = 0; } elsif ($sublist==1) { $html .= "

  • "; } else { $html .= "

    "; } $html .= qq~ 0 && index($bmSetup::SectionSuppress{$_}, "s") < 0) || ($bmSetup::RSSNum ==0 && index($_, "_") < 0) ) { $html .= " checked"; } if (index($_, "_") >= 0) { #subsection $bmSetup::SectionName{$_} =~ s/>/>/; $html .= qq~> Focused feed: $bmSetup::SectionName{$_}

  • \n~; } else { $html .= qq~> $bmSetup::SectionName{$_} section

    \n~; } } if ($sublist == 1) { $html .= "\n"; } $html .= qq~

     

    \n~; &bmLib::bmHTML("Select Your News Feeds", $html); } #end edit_newsfeeds routine sub save_newsfeeds { ############################################################### ## ROUTINE: save_newsfeeds ## ## Sets/removes the "s" flag from the SectionSuppress hash ## for each non-aliased section of the site, based on user ## input from the edit_newsfeeds routine. ## ############################################################### my %feed; # routine: save_newsfeeds====================================== # MARK SECTIONS FOR WHICH WE WANT TO OFFER A FEED # ============================================================= foreach (CGI::param("feed")) { $feed{$_} = 1; } # routine: save_newsfeeds====================================== # LOCK AND LOAD # ============================================================= &bmLib::FileLock; my @secindex= &bmLib::LoadFile("$bmSetup::DataDir/templates/Sections.setup"); # routine: save_newsfeeds====================================== # MAKE SURE THERE'S AVAILABLE DISK SPACE # ============================================================= #don't need much, 512k should be fine &bmLib::DiskSpace("$bmSetup::DataDir/templates", 512); # routine: save_newsfeeds====================================== # REBUILD SECTION INDEX AND WRITE TO DISK # ============================================================= open (SECTIONFILE, ">$bmSetup::DataDir/templates/Sections.setup") or die("Unable to write to section index at $bmSetup::DataDir/templates/Sections.setup. $!."); flock(SECTIONFILE, 2) or die("Could not do flock 2 exclusive lock on section index at $bmSetup::DataDir/templates/Sections.setup. $!"); #update all sections (unaliased sections get no feed) foreach (@secindex) { my @line = split(/ /); if ($feed{$line[0]}) { #remove the feed-suppress flag $line[6] =~ s/s//; $_ = join(" ", @line); } elsif (index($line[6], "s") < 0) { $line[6] .= "s"; $_ = join(" ", @line); } print SECTIONFILE "$_\n"; } close (SECTIONFILE); chmod 0666, "$bmSetup::DataDir/templates/Sections.setup"; &bmLib::FileUnlock; # routine: save_newsfeeds====================================== # CONFIRM THE SAVE # ============================================================= &bmLib::bmHTML("News Feed Settings Saved", qq~Your news-feed content settings have been saved (please rebuild top-level pages to refresh your feeds). Close this window to continue.~); }