Revision 3 (by moose, 2006/07/10 13:53:17) more additions
package SVNAdmin;
use base Exporter;
our @EXPORT = qw/&http_header &http_redirect start_page end_page start_menu menu_head end_menu menu_item
	start_menu_sect end_menu_sect start_content end_content uri acl_menu
	global_admin repo_admin path_admin menu_default_item
	$q $session $acl $loggedin $login_info $username $page_title $user/;

use strict;
use warnings;

use Carp::Heavy;
use CGI::Carp qw/fatalsToBrowser/;
use CGI qw/:all -oldstyle_urls -no_undef_params *table *TR *Tr *td *div *span *label *ul *li/;
#use CGI::Pretty qw/:all -oldstyle_urls -no_undef_params *table *TR *Tr *td *div *span *label *ul *li/;

use Session;
use SVNACL;
use File::Spec::Functions;
use File::Basename;
use URI;
use URI::Escape;
use URI::QueryParam;

umask 0000;

# conf
our $uri_path = '/admin/';
our $uri = 'http://svn.tomasu.org/';

our $q = new CGI;
our $session = new Session(BASE_PATH => '/home/svn/htdocs/admin/', NAME => 'SID');
our $acl = new SVNACL(digest => 'Crypt', svn_conf => '/var/svn/conf', svn_parent => '/var/svn/repos');

our $login_info;
our $page_title;
our $loggedin = $session->key_exists('loggedin');
our $username = quotemeta $session->key('username');
our $user;

if($loggedin) {
	$user = $acl->user($username);
	$login_info =
		start_menu_sect('User: '.$username) .
			menu_item(-int => 1, -href => uri("user.pl"), -text => 'Settings') .
			menu_item(-int => 1, -href => uri('logout.pl'), -text => 'Logout') .
		end_menu_sect();
}
else {
	my $url = url(-relative => 1);
	if($url =~ /login.pl/) {
		$login_info =
			start_menu_sect('       User       ')  .
				menu_item(-int => 1, -href => uri('login.pl'), -text => 'Login') .
			end_menu_sect();
	} else {
		$session->key('referer', url());
		print http_redirect(-uri => uri('login.pl'));
		exit;
	}
}

sub http_header_merge {
	my $type = shift;
	my %h = @_;

	$h{'-type'} = 'text/html' if $type && !defined $h{'-type'};

	if(exists $h{'-cookie'}) {
		my @cookies;

		if(ref($h{'-cookie'}) eq 'ARRAY') {
			push @cookies, @{$h{'-cookies'}};
		}
		else {
			push @cookies, $h{'cookies'};
		}

		push @cookies, $session->cookie();
	}

	return %h;
}

sub http_header {
	return $q->header(http_header_merge(1, @_));
}

sub http_redirect {
	return $q->redirect(http_header_merge(0, @_));
}

sub uri {
	my ($dummy, $path) = fileparse(url(-full => 0, -absolute => 1));
	my $base = url(-base => 1);
	return $base . catfile($path,@_);
}

sub start_page {
	my %h = @_;
	return
		start_html({ -style => $h{-style}, -title => $h{-title} }) .
			start_table({ -id => 'page', -border => 0, -cellspacing => 0, cellpadding => 0 }) .
				start_Tr() .
					start_td({ -id => 'header', -colspan => 2, -valign => 'middle' }) .
						start_div({-id => 'header_logo'}) .
							span({-id=>'header_logo_sub'},'SUB') . span({-id=>'header_logo_version'},'VERSION') .
						end_div() .
#						img({ -id => 'header_logo', src => 'subversion_logo_trans_right.png' }) .
					end_td() .
				end_Tr() .
				start_Tr();
}

sub end_page {
	return
				end_Tr() .
				start_Tr() .
					start_td({ -id => 'footer', -colspan => 2 }) .
'lalala' .
					end_td() .
				end_Tr() .
			end_table() .
		end_html();
}

sub start_menu {
	my $acl_menu = '';
	my $g = $acl->group('admin');
	if($g->user($username)) {
		$acl_menu = acl_menu();
	}
	else {
		for my $group ( $acl->groups() ) {
			next unless $group->name() =~ /^admin-/;
			for my $user ( $group->usernames() ) {
				next unless $user eq $username;
				$acl_menu = acl_menu();
			}
		}
	}

	return
		start_td({ -id => 'menu', -valign => 'top' }) .
			start_ul({ -class => 'menu' }) .
				$login_info . $acl_menu;
}

sub end_menu {

	return
		end_ul() .
	end_td();
}

sub start_menu_sect {
	my $title = shift;
	return
		li({-class => 'menu_header'}, $title);
}

sub menu_default_item {
	my %h = @_;
	$q->param($h{'-key'}, $h{'-item'}) if !exists $q->Vars()->{ $h{'-key'} };
}

sub menu_item {
	my %h = @_;
	$h{-href} = self_url if !exists $h{-href};
	$h{-text} = '' if !exists $h{-text};
	$h{-class} = 'menu_item' if !exists $h{-class};

	if(exists $h{-int} && $h{-int} == 1) {
		my $page = url(-relative => 1, -query => 0);
		$page =~ s/(.*)\?/$1/; # I dont know why this is needed.

		my $uri = (URI->new($h{-href})->path_segments())[-1];

		if($uri eq $page) {
			$h{-class} .= ' menu_item_selected';
		}
	}

	if(
		$h{-class} !~ /menu_item_selected/ &&
		exists $h{-key} &&
		defined $h{-key} &&
		$h{-key} ne '')
	{
		my $parm = $q->param($h{-key});
		if($parm && $h{-value} eq $parm) {
			$h{-class} .= ' menu_item_selected';
		}

#		if($h{-href} eq self_url) {
			my $uri = URI->new($h{-href});
			$uri->query_param($h{-key} => $h{-value});

			$h{-href} = URI->new($uri->canonical);
#		}
	}

	return
		start_li({ -class => $h{-class} }) .
			((exists $h{-onclick}) ?
				a({ -href => $h{-href}, -onclick => $h{-onclick} }, $h{-text})
			:
				a({ -href => $h{-href} }, $h{-text})
			) .
		end_li();
}

sub end_menu_sect {
	return
		li({ -class => 'menu_item' }, br());
}

sub start_content {
	return
		start_td({-id => 'content'});
}

sub end_content {
	return
			end_td();
		end_Tr();
}

sub acl_menu {
	my $page = url(-relative => 1, -full => 0);
	my $repos = $acl->admin
	return
		start_menu_sect('Section') .
			menu_item(-int => 1, -class => ($page eq 'users.pl' ? 'menu_item menu_item_selected' : 'menu_item'), -href => uri('users.pl'), -text => 'users') .
			menu_item(-int => 1, -class => ($page eq 'groups.pl' ? 'menu_item menu_item_selected' : 'menu_item'), -href => uri('groups.pl'), -text => 'groups') .
			menu_item(-int => 1, -class => ($page eq 'repos.pl' ? 'menu_item menu_item_selected' : 'menu_item'), -href => uri('repos.pl'), -text => 'repos') .
		end_menu_sect();
}


1;