[vhffs-dev] [1400] Using common root class for all panel types.

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 1400
Author:   beuss
Date:     2009-05-23 15:14:44 +0200 (Sat, 23 May 2009)

Log Message:
-----------
Using common root class for all panel types. Keeping Vhffs::Panel::Main for compatibility

Modified Paths:
--------------
    branches/vhffs-design/vhffs-api/src/Vhffs/Makefile.am
    branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Main.pm
    branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Public.pm

Added Paths:
-----------
    branches/vhffs-design/vhffs-api/src/Vhffs/Panel.pm


Modified: branches/vhffs-design/vhffs-api/src/Vhffs/Makefile.am
===================================================================
--- branches/vhffs-design/vhffs-api/src/Vhffs/Makefile.am	2009-05-22 21:23:53 UTC (rev 1399)
+++ branches/vhffs-design/vhffs-api/src/Vhffs/Makefile.am	2009-05-23 13:14:44 UTC (rev 1400)
@@ -15,12 +15,14 @@
 	Main.pm \
 	ObjectFactory.pm \
 	Object.pm \
+	Panel.pm \
 	Robots.pm \
 	Services.pm \
 	Stats.pm \
 	Tag.pm \
 	User.pm \
 	Panel/Admin.pm \
+	Panel/Anonymous.pm \
 	Panel/Avatar.pm \
 	Panel/Captcha.pm \
 	Panel/Commons.pm \

Modified: branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Main.pm
===================================================================
--- branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Main.pm	2009-05-22 21:23:53 UTC (rev 1399)
+++ branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Main.pm	2009-05-23 13:14:44 UTC (rev 1400)
@@ -1,833 +1,83 @@
-#!%PERL% -w
+# Copyright (c) vhffs project and its contributors
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without 
+# modification, are permitted provided that the following conditions 
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright 
+#   notice, this list of conditions and the following disclaimer.
+#2. Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in 
+#   the documentation and/or other materials provided with the 
+#   distribution.
+#3. Neither the name of vhffs nor the names of its contributors 
+#   may be used to endorse or promote products derived from this 
+#   software without specific prior written permission.
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+# POSSIBILITY OF SUCH DAMAGE.
 
-package Vhffs::Panel::Main;
-require Exporter;
-@ISA    = qw(Exporter);
-@EXPORT = qw( display );
-
 use strict;
 use utf8;
-use POSIX qw(locale_h);
-use HTML::Template;
-use locale;
-use Locale::gettext;
-use CGI;
-use CGI::Session;
-use File::Spec;
-use Encode;
 
-use Vhffs::Main;
-use Vhffs::User;
-use Vhffs::Group;
-use Vhffs::Panel::Menu;
-use Vhffs::Panel::User;
-use Vhffs::Panel::Commons;
-use Vhffs::Panel::Admin;
+package Vhffs::Panel::Main;
 
-use Vhffs::Panel::Cvs;
-use Vhffs::Panel::DNS;
-use Vhffs::Panel::Mail;
-use Vhffs::Panel::MailingList;
-use Vhffs::Panel::Mysql;
-use Vhffs::Panel::Pgsql;
-use Vhffs::Panel::Repository;
-use Vhffs::Panel::Svn;
-use Vhffs::Panel::Git;
-use Vhffs::Panel::Web;
-use Vhffs::Panel::Cron;
+use base qw(Vhffs::Panel);
 
-=pod
+use locale;
+use Locale::gettext;
+use POSIX qw(locale_h);
 
-=head1 NAME
+use lib '%VHFFS_LIB_DIR%';
+use Vhffs::Tag;
+use Vhffs::Functions;
 
-Vhffs::Panel::Main - Provides acces to common VHFFS
-functionnalities from Vhffs Panel.
-
-=head1 SYNOPSIS
-
-TODO
-
-=head1 METHODS
-
-=cut
-
-=pod
-
-=head2 check_public
-
-    $panel->check_public;
-
-Checks that public area is available, if it's not the case show a message and exits.
-
-=cut
-
-sub check_public {
-    my $panel = shift;
-    my $vhffs = $panel->{vhffs};
-    my $templatedir = $vhffs->get_config->get_templatedir;
-    if( $vhffs->get_config->get_panel->{'use_public'} ne 'yes' ) {
-        my $template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
-        $template->param( TEXT_CLOSE    => gettext('Public area not available') );
-        $template->param( TEXT_EXPLAIN  => gettext('Public area is not available on this platform.') );
-
-        $panel->light( $template );
-	$panel->display;
-        exit( 0 );
-    }
+sub new {
+	my $class = shift;
+	my $panel = $class->SUPER::new(@_);
+	return $panel;
 }
 
-=pod
+=head2 render
 
+	$panel->render($template_file, $template_vars, $layout_file);
+	
+Render the specified Template::Toolkit file using C<$template_vars>
+as substitutions.
 
-=head2 is_open
-
-    $panel->is_open;
-
-Return 1 if panel is open, else return 0
-
 =cut
 
-sub is_open {
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	use Vhffs::Functions;
-	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'open'} );
-}
-
-=pod
-
-
-=head2 is_public
-
-    $panel->is_public;
-
-Return 1 if public part is enabled, else return 0
-
-=cut
-
-sub is_public {
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	use Vhffs::Functions;
-	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'use_public'} );
-}
-
-=pod
-
-
-=head2 use_avatars
-
-    $panel->use_avatars;
-
-Return 1 if either or both users or groups avatars are enabled, else return 0
-
-=cut
-
-sub use_avatars {
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	use Vhffs::Functions;
-	return ( Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'users_avatars'} )
-		|| Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'groups_avatars'} ) );
-}
-
-=pod
-
-
-=head2 use_users_avatars
-
-    $panel->use_users_avatars;
-
-Return 1 if users avatars are enabled, else return 0
-
-=cut
-
-sub use_users_avatars {
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	use Vhffs::Functions;
-	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'users_avatars'} );
-}
-
-=pod
-
-
-=head2 use_groups_avatars
-
-    $panel->use_groups_avatars;
-
-Return 1 if groups avatars are enabled, else return 0
-
-=cut
-
-sub use_groups_avatars {
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	use Vhffs::Functions;
-	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'groups_avatars'} );
-}
-
-=pod
-
-
-=head2 check_modo
-
-    $panel->check_modo
-
-Checks that logged in user is admin or moderator. If it is
-not the case, show a message and exits.
-
-=cut
-
-sub check_modo {
-    my $panel = shift;
-    my $user = $panel->{user};
-    unless($user->is_moderator || $user->is_admin) {
-        $panel->set_title( gettext('Access denied') );
-        $panel->add_error( gettext('You are not granted to access this page') );
-	$panel->build;
-	$panel->display;
-	exit 0;
-    }
-}
-
-=head2
-
-    $panel->check_admin
-
-Check that logged in user is an admin. If it is not
-the case, show a message and exits.
-
-=cut
-
-sub check_admin {
-    my $panel = shift;
-    my $user = $panel->{user};
-    unless($user->is_admin) {
-        $panel->set_title( gettext('Access denied') );
-        $panel->add_error( gettext('You are not granted to access this page') );
-        $panel->build;
-        $panel->display;
-        exit 0;
-    }
-}
-
-sub list_themes
-{
-	my $vhffs = shift;
-	return -1 unless defined $vhffs;
-
-	my @themes;
+sub render {
+	my ($self, $file, $vars, $layout) = @_;
+	my $conf = $self->{vhffs}->get_config;
 	
-	my $dir = $vhffs->get_config->get_panel->{'themesdir'};
-	return undef unless defined $dir;
+	$vars = {} unless(defined $vars);
+	
+	my $default_vars = {
+		panel_url => $conf->get_panel->{url},
+		help_url => $conf->get_panel->{url_help},
+		users_avatar => Vhffs::Functions::strtobool( $conf->get_panel->{'users_avatars'} ),
+		groups_avatar => Vhffs::Functions::strtobool( $conf->get_panel->{'groups_avatars'} ) 
+	};
+	
+	$vars = {%$default_vars, %$vars};
 
-	opendir( DIR , $dir) or return -2;
-	my @files = readdir( DIR );
-	foreach( @files )
-	{
-		next if( /\./);
-		if( -d $dir."/".$_ )
-		{
-			push @themes , $_;
-		}
+	# Handling ajax stuff
+	unless($self->{is_ajax_request}) {
 	}
-
-	closedir( DIR );
-	return @themes;
-}
-
-
-sub list_languages
-{
-	my $vhffs = shift;
-	return -1 if( ! defined $vhffs );
-
-    return $vhffs->get_config->get_available_languages;
-}
-
-
-
-sub select_lang {
-    my $self = shift;
-    my @langs = $self->{vhffs}->get_config->get_available_languages;
-    my $txt = '';
-	foreach my $l ( @langs )
-	{
-		$txt .= "<a href=\"auth.pl?lang=".$l."\"><img src=\"/themes/".$self->{theme}."/images/".$l.".png\" alt=\"".$l."language\"/></a>";
-	}
-	return $txt;
-}
-
-
-sub new
-{
-	my $class = ref($_[0]) || $_[0];
-	my $this = {};
-	$this->{errors} = [];
-	$this->{infos} = [];
-	$this->{cookies} = [];
-	bless( $this, $class );
-
-	my $cgi = new CGI;
-	$cgi->charset('UTF-8');
-	$this->{cgi} = $cgi;
-	$this->{url} = CGI::url();
-
-	my $vhffs = init Vhffs::Main;
-	$this->{vhffs} = $vhffs;
-	unless( defined $vhffs )  {
-		print CGI->header( -type=>'text/html', -charset=>'utf-8' ), 'Unable to open database connection\n';
-		exit 1;
-	}
-
-	my $config = $vhffs->get_config;
-	$this->{config} = $config;
-	my $templatedir = $config->get_templatedir;
-	$this->{templatedir} = $templatedir;
-
-	# lang cookie
-	my $lang = $cgi->param('lang');
-	$this->add_cookie( CGI->cookie( -name=>'language', -value=>$lang, -expires=>'+10y' ) ) if defined $lang;
-	$lang = CGI->cookie('language') unless defined $lang;
-	$lang = $vhffs->get_config->get_default_language() unless defined $lang;
-	$lang = 'en_US' unless defined $lang;
-	$this->{lang} = $lang;
-
-	setlocale(LC_ALL, $lang);
-	bindtextdomain('vhffs', '%localedir%');
-	textdomain('vhffs');
-
-	# theme cookie
-	my $theme = $cgi->param('theme');
-	$this->add_cookie( CGI->cookie( -name=>'theme', -value=>$theme, -expires=>'+10y' ) ) if defined $theme;
-	$theme = CGI->cookie('theme') unless defined $theme;
-	$theme = $config->get_panel->{'default_theme'} unless defined $theme;
-	$theme = 'vhffs' unless( defined $theme  &&  -f $config->get_panel->{'themesdir'}.'/'.$theme.'/main.css' );
-	$this->{theme} = 'vhffs';
-
-	my $template = new HTML::Template( filename => $templatedir.'/panel/main/main.tmpl' );
-	$this->{template} = $template;
-
-	if( $vhffs->is_valid() == 0 )
-	{
-		my $template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
-		$template->param( TEXT_CLOSE    => gettext("Platform temporary closed<br/>database error") );
-		$template->param( TEXT_EXPLAIN  => gettext("This platform is temporary closed. Administrators are performing some maintenances tasks or system has database errors. Please come back in a few minutes to log in.") );
-    
-		$this->light( $template );
-		$this->display;
-		exit 0;
-	}
-
-	if( $vhffs->get_config->get_panel->{'open'} ne 'yes' )
-	{
-		$template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
-		$template->param( TEXT_CLOSE    => gettext("Platform temporary closed.") );
-		$template->param( TEXT_EXPLAIN  => gettext("This platform is temporary closed. Administrators are performing some maintenances tasks. Please come back in a few minutes to log in.") );
-
-		$this->light( $template );
-		$this->display;
-		exit 0;
-	}
 	
-	$this->{is_ajax_request} = (defined $this->{cgi}->http('X-Requested-With')
-		and $this->{cgi}->http('X-Requested-With') eq 'XMLHttpRequest');
-
-	return $this;
+	$self->SUPER::render($file, $vars, $self->{templatedir}.'/panel/', $layout);
 }
 
-
-
-sub get_session
-{
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	my $cgi = $panel->{cgi};
-
-	my $sid = $cgi->cookie( CGI::Session::name() );
-	unless( defined $sid )  {
-		$panel->add_error( gettext('No cookie found, please accept the cookie and then please login again !') );
-		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
-		exit 0;
-	}
-
-	my $session = new CGI::Session( undef, $sid, {Directory=>'/tmp'} );
-	unless( defined $session )  {
-		$panel->add_error( gettext('Cannot create or fetch session file, please check that /tmp is readable and writeable') );
-		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
-		exit 0;
-	}
-
-	my $username = $session->param('username');
-	my $uid = $session->param('uid');
-	unless(  defined $username  &&  defined $uid  &&  !$session->is_new()  )  {
-		$panel->add_error( gettext('Expired session ! Please login again') );
-		$session->delete();
-		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
-		exit 0;
-	}
-
-	my $user = Vhffs::User::get_by_uid($vhffs, $uid);
-	unless ( defined $user )  {
-		$panel->add_error( gettext('User does not exist') );
-		$session->delete();
-		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
-		exit 0;
-	}
-
-	unless( $user->get_status == Vhffs::Constants::ACTIVATED )  {
-		$panel->add_error( gettext('You\'re are not allowed to browse panel') );
-		$session->delete();
-		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
-		exit 0;
-	}
-
-	$panel->{session} = $session;
-	$panel->{user} = $user;
-	return $session;
-}
-
-
-=head2 generate_header
-
-    print $panel->generate_header;
-
-Generates panel header (account name, project label, contextuel menu, etc.).
-
-=cut
-
-sub generate_header {
-    my $panel = shift;
-    my $user = $panel->{user};
-    my $theme = $panel->{theme};
-    my $templatedir = $panel->{templatedir};
-    my $vhffs = $panel->{vhffs};
-    my $cgi = $panel->{cgi};
-
-    my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
-
-    my $menutemplate = new HTML::Template( filename => $templatedir.'/panel/menu/main.tmpl' );
-    $menutemplate->param( THEME => $theme );
-
-    $menutemplate->param( USERNAME          => $user->get_username() );
-    # Sets account type and admin link if needed
-    if( $user->is_admin == 1 ) {
-        $menutemplate->param( TEXT_ACCOUNT    => gettext('Admin account') );
-        $menutemplate->param( TEXT_ADMIN => gettext('Administration') ) 
-    } elsif( $user->is_moderator == 1 ) {
-        $menutemplate->param( TEXT_ACCOUNT    => gettext('Moderator account') );
-        $menutemplate->param( TEXT_ADMIN => gettext('Administration') ) 
-    } else {
-        $menutemplate->param( TEXT_ACCOUNT    => gettext('User account') );
-    }
-    $menutemplate->param( TEXT_HOME         => gettext('Home page') );
-    $menutemplate->param( TEXT_PREFS        => gettext("User Preferences") );
-    $menutemplate->param( TEXT_PROJECTS     => gettext('My Projects') );
-    $menutemplate->param( TEXT_HELP         => gettext("Help") );
-    $menutemplate->param( TEXT_SUBMITBUG    => gettext("Submit a bug") );
-    $menutemplate->param( TEXT_LOGOUT       => gettext("Logout") );
-    $menutemplate->param( HELP_URL          => $vhffs->get_config->get_panel->{'url_help'} || 'http://www.vhffs.org/' );
-
-    # Current project stuff (TODO stop handle it in session)
-    if( ( CGI::url( -absolute => 1) =~ /^\/admin\// ) || defined $cgi->param('admin_menu')) {
-        if( $user->is_admin ) {
-            $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_admin_ctxmenu( $vhffs->get_config ) );
-        } elsif( $user->is_moderator ) {
-            $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_moderator_ctxmenu( $vhffs->get_config ) );
-        }
-    } elsif( $group ) {
-        $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_project_ctxmenu( $vhffs->get_config , $group ) );
-    }
-
-
-    return $menutemplate->output();
-}
-
-sub has_errors
-{
-    my $panel = shift;
-    return (@{$panel->{errors}} > 0);
-}
-
-sub set_title
-{
-    my ($panel, $title) = @_;
-    $panel->{title} = $title;
-}
-
-sub add_error
-{
-    my ($panel, $error) = @_;
-    push(@{$panel->{errors}}, {msg => $error});
-}
-
-sub add_info
-{
-    my ($panel, $info) = @_;
-    push(@{$panel->{infos}}, {msg => $info});
-}
-
-sub add_cookie
-{
-    my ($panel, $cookie) = @_;
-    push(@{$panel->{cookies}}, $cookie);
-}
-
-sub clear_infos
-{
-    my $panel = shift;
-    $panel->{infos} = [];
-}
-
-sub welcome
-{
-	my $panel = shift;
-	my $vhffs = $panel->{'vhffs'};
-	my $user = $panel->{'user'};
-	my $templatedir = $panel->{'templatedir'};
-
-	$panel->set_title( sprintf( gettext('Hello %s, welcome in VHFFS !'), $user->get_username() ) );
-
-	my $template = new HTML::Template( filename => $templatedir.'/panel/misc/welcome.tmpl' );
-	$template->param( TEXT_WELCOME => gettext('If you are new to VHFFS, you should start to read quickly the whole help available by clicking on the help button in the upper right of your screen') );
-
-	# check groups quota
-	my @overquota;
-	foreach my $group ( @{$user->get_groups} )  {
-		my $quota = $group->get_quota;
-		my $curused = $group->get_quota_used;
-		if( $curused > $quota-$quota/10 )  {
-			my %g = ( groupname => $group->get_groupname );
-			push @overquota, \%g;
-		}
-	}
-	if( @overquota )  {
-		$template->param( OVER_QUOTA_TEXT => gettext('The following projects have reached or are going to reach the disk quota limit, please take a look !') );
-		$template->param( OVER_QUOTA => \@overquota );
-	}
-
-	return $template;
-}
-
-
-sub project_info
-{
-	my $panel = shift;
-	my $vhffs = $panel->{vhffs};
-	my $cgi = $panel->{cgi};
-	my $templatedir = $vhffs->get_config->get_templatedir;
-	my $temp;
-	my $object;
-	my $objects;
-	my $template;
-	my $subtemplate;
-
-	my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
-		
-    if( ! defined( $group ) ) {
-        $template = new HTML::Template( filename => $templatedir."/panel/misc/simplemsg.tmpl" );
-        $template->param( MESSAGE  => gettext("Group error" ) );
-    } else {
-        $template = new HTML::Template( filename => $templatedir."/panel/group/info.tmpl" );
-        $panel->set_title( sprintf( gettext("Group %s") , $group->get_groupname ) );
-        $template->param( THEME => $panel->{theme} );
-
-        # Quota stuff
-        $template->param( QUOTA_TEXT => sprintf( gettext("Quota (used/total) : %s/%s") , $group->get_quota_used , $group->get_quota ) );
-        # Yes, sorry quota progress image has to be 300px width max
-        $template->param( QUOTA_WIDTH => ( ($group->get_quota_used / $group->get_quota) * 300 ) );
-
-        my $gid = $group->get_gid;
-        my $config = $vhffs->get_config;
-        my $services_list = '';
-
-        $template->param( TEXT_PREFS => gettext('Preferences') );
-        $template->param( TEXT_GENERAL => gettext('General') );
-        $template->param( TEXT_FULLHISTORY => gettext('Full history') );
-
-        $template->param( GROUPNAME => $group->get_groupname );
-
-	my $groupconfig = $config->get_groups;
-	if( defined $groupconfig && defined ( my $url = $groupconfig->{'url_doc'} ) )  {
-		$template->param( HELP_TEXT => gettext('Help') );
-		$template->param( HELP_URL => $url );
-	}
-
-        if($config->get_service_availability('web')) {
-            my $webs = Vhffs::Panel::Web::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('web', $webs)->output;
-        }
-
-        if($config->get_service_availability('mysql')) {
-            my $mysql = Vhffs::Panel::Mysql::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('mysql', $mysql)->output;
-        }
-
-        if($config->get_service_availability('pgsql')) {
-            my $pg = Vhffs::Panel::Pgsql::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('pgsql', $pg)->output;
-        }
-
-        if($config->get_service_availability('cvs')) {
-            my $cvs = Vhffs::Panel::Cvs::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('cvs', $cvs)->output;
-        }
-
-        if($config->get_service_availability('svn')) {
-            my $svn = Vhffs::Panel::Svn::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('svn', $svn)->output;
-        }
-
-        if($config->get_service_availability('git')) {
-            my $git = Vhffs::Panel::Git::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('git', $git)->output;
-        }
-
-        if($config->get_service_availability('mailinglist')) {
-            my $ml = Vhffs::Panel::MailingList::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('mailinglist', $ml)->output;
-        }
-
-        if($config->get_service_availability('mail')) {
-            my $mail = Vhffs::Panel::Mail::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('mail', $mail)->output;
-        }
-
-        if($config->get_service_availability('repository')) {
-            my $repos = Vhffs::Panel::Repository::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('repository', $repos)->output;
-        }
-
-        if($config->get_service_availability('dns')) {
-            my $dns = Vhffs::Panel::DNS::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('dns', $dns)->output;
-        }
-
-        if($config->get_service_availability('cron')) {
-            my $cron = Vhffs::Panel::Cron::getall_per_group( $vhffs, $gid );
-            $services_list .= $panel->create_service_index('cron', $cron)->output;
-        }
-
-        $template->param( SERVICES => $services_list );
-	}
-	return $template;
-}
-
-
-sub set_refresh_url
-{
-	my ( $panel , $url , $time ) = @_;
-
-	if( defined $url )  {
-		my $template = $panel->{template};
-		$template->param( REFRESH_URL => $url );
-		$template->param( REFRESH_TIME => $time || 3 );
-	}
-	return;
-}
-
-
-sub build
-{
-	my $panel = shift;
-	my $template = shift;
-	my $cgi = $panel->{cgi};
-	my $theme = $panel->{theme};
-	my $templatedir = $panel->{templatedir};
-
-	$panel->add_info( Encode::decode_utf8( $cgi->param('msg') ) ) if( defined $cgi->param('msg') );
-	$panel->add_error( Encode::decode_utf8( $cgi->param('error') ) ) if( defined $cgi->param('error') );
-
-	my $paneltemplate = new HTML::Template( filename => $templatedir.'/panel/main/panel.tmpl' );
-	$paneltemplate->param( THEME => $theme );
-	$paneltemplate->param( TITLE => $panel->{title} );
-	$paneltemplate->param( HEADER => $panel->generate_header );
-
-	if( @{$panel->{errors}} > 0 ) {
-		my $tmplerrors = new HTML::Template( filename => $templatedir.'/panel/misc/errors.tmpl' );
-		$tmplerrors->param( ERRORS => $panel->{errors} );
-		$paneltemplate->param( ERRORS => $tmplerrors->output );
-	}
-
-	if( @{$panel->{infos}} > 0 ) {
-		my $tmplinfos = new HTML::Template( filename => $templatedir.'/panel/misc/infos.tmpl' );
-		$tmplinfos->param( INFOS => $panel->{infos} );
-		$paneltemplate->param( INFOS => $tmplinfos->output );
-	}
-
-	$paneltemplate->param( TEXT_HELP => gettext('Help') );
-	$paneltemplate->param( TEXT_HELP_CONTENT => gettext('Stay over an icon to see its description.') );
-
-	$paneltemplate->param( CONTENT => $template->output ) if( defined $template );
-
-	$panel->{content} = $paneltemplate->output;
-	return;
-}
-
-
-sub light
-{
-	my $panel = shift;
-	my $template = shift;
-	my $cgi = $panel->{cgi};
-	my $theme = $panel->{theme};
-	my $templatedir = $panel->{templatedir};
-
-	$panel->add_info( Encode::decode_utf8( $cgi->param('msg') ) ) if( defined $cgi->param('msg') );
-
-	$template->param( THEME => $theme ) if( ($template->query(name => 'THEME') || '') eq 'VAR' );
-
-	if( @{$panel->{errors}} > 0 ) {
-		my $tmplerrors = new HTML::Template( filename => $templatedir.'/panel/misc/errors.tmpl' );
-		$tmplerrors->param( ERRORS => $panel->{errors} );
-		$template->param( ERRORS => $tmplerrors->output );
-	}
-
-	if( @{$panel->{infos}} > 0 ) {
-		my $tmplinfos = new HTML::Template( filename => $templatedir.'/panel/misc/infos.tmpl' );
-		$tmplinfos->param( INFOS => $panel->{infos} );
-		$template->param( INFOS => $tmplinfos->output );
-	}
-
-	$panel->{content} = $template->output;
-	return;
-}
-
-
-sub display
-{
-	my $panel = shift;
-	my $template = $panel->{'template'};
-	my $cgi = $panel->{cgi};
-	my $theme = $panel->{theme};
-	my $config = $panel->{config};
-
-	$template->param( TITLE => sprintf( gettext( '%s\'s Panel' ), $config->get_host_name ) );
-	$template->param( THEME => $theme );
-
-	# Allow each theme to have its own Jscripts
-	my $jsglob = File::Spec->catfile($config->get_panel->{'themesdir'}, $theme, '/js/*.js');
-	my $jswebpath = '/themes/'.$theme.'/js/';
-	my @jscripts;
-	# Common scripts
-	push @jscripts, {SCRIPT => '/js/prototype.js'};
-	push @jscripts, {SCRIPT => '/js/commons.js'};
-	push @jscripts, {SCRIPT => '/js/tooltip.js'};
-	while( glob($jsglob) ) {
-		use File::Basename;
-		push @jscripts, {SCRIPT => $jswebpath.basename( $_ )};
-	}
-	$template->param( JSCRIPTS => \@jscripts );
-
-	$template->param( CONTENT => $panel->{content} );
-
-	binmode STDOUT , ':utf8';
-	print CGI->header( -cookie=>[ @{$panel->{cookies}} ], -type=>'text/html', -charset=>'utf-8' );
-	print $template->output;
-	return;
-}
-
-
-=pod
-
-=head2 redirect
-
-    $panel->redirect($page, $cookies);
-
-Issues a redirection header sending to $page
-(you can specify additional cookies to be sent).
-
-This function never returns.
-
-B<C<$page> should be an absolute path>
-
-B<C<$cookies>> can be a CGI::Cookie or a reference
-to a CGI::Cookie array.
-
-=cut
-sub redirect {
-    my ($panel, $dest, $cookies) = @_;
-
-    $dest = Encode::encode_utf8( $dest );
-
-    if(defined $cookies) {
-        if(ref($cookies)) {
-            foreach(@$cookies) {
-                print "Set-Cookie: $_\n";
-            }
-        } else {
-            print "Set-Cookie: $cookies\n";
-        }
-    }
-    print CGI::redirect($dest);
-    exit(0);
-}
-
-=pod
-
-=head2 create_service_index
-
-    my $webs = Vhffs::Panel::Web::get_per_group($main, $gid);
-    my $template = $panel->create_service_index('web', $webs);
-    print $template->output;
-
-Generates summary information for a given service using service_index.tmpl.
-
-=cut
-
-sub create_service_index($$$) {
-    my ($panel, $service, $services) = @_;
-    my %service_labels = (
-        cvs => 'CVS repositories',
-        dns => 'Domain names',
-        mail => 'Mail domains',
-        mailinglist => 'Mailing lists',
-        mysql => 'MySQL DBs',
-        pgsql => 'PostgreSQL DBs',
-        repository => 'Download repositories',
-        svn => 'SVN repositories',
-        git => 'Git repositories',
-        web => 'Webareas',
-	cron => 'Cron jobs',
-    );
-
-    my $vhffs = $panel->{'vhffs'};
-    my $cgi = $panel->{'cgi'};
-    my $templatedir = $panel->{templatedir};
-
-    my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
-
-    my $svclabel = $service_labels{$service};
-    my $template = new HTML::Template( filename => $templatedir.'/panel/misc/service_index.tmpl', global_vars => 1 );
-
-    my $format = sprintf( '%s for %%s', $svclabel );
-    $template->param( TEXT_TITLE => sprintf(gettext($format), $group->get_groupname) );
-    $template->param( SERVICE => $service );
-    $template->param( ADMIN_TEXT => gettext('Go to administration') );
-    $template->param( RESUBMIT_TEXT => gettext('Propose a new description') );
-    $template->param( DELETE_TEXT => gettext('Delete') );
-    $template->param( HISTORY_TEXT => gettext('History') );
-    $template->param( NEW => gettext('New') );
-    $template->param( NO_SERVICE_TEXT => gettext('None') );
-    $template->param( SERVICES => $services);
-    $template->param( GROUPNAME => $group->get_groupname );
-
-    my $serviceconfig = $vhffs->get_config->get_service($service);
-    if( defined $serviceconfig && defined ( my $url = $serviceconfig->{'url_doc'} ) )  {
-        $template->param( HELP_TEXT => gettext('Help') );
-        $template->param( HELP_URL => $url );        
-    }
-
-    return $template;
-}
-
-sub format_description($) {
-    use CGI qw{escapeHTML};
-    my $description = shift;
-    $description = escapeHTML($description);
-    $description =~ s!\n!<br/>!g;
-    return $description;
-}
-
 1;

Modified: branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Public.pm
===================================================================
--- branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Public.pm	2009-05-22 21:23:53 UTC (rev 1399)
+++ branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Public.pm	2009-05-23 13:14:44 UTC (rev 1400)
@@ -34,7 +34,7 @@
 
 package Vhffs::Panel::Public;
 
-use base qw(Vhffs::Panel::Main);
+use base qw(Vhffs::Panel);
 
 use locale;
 use Locale::gettext;
@@ -57,29 +57,6 @@
 	my ($self, $file, $vars) = @_;
 	my $conf = $self->{vhffs}->get_config;
 	
-	# TODO Should be in parent class when Template::Toolkit switch is over
-	my $create_vars = {
-		INCLUDE_PATH => $self->{templatedir}.'/public/',
-		FILTERS => {
-			i18n => \&gettext,
-			mail => sub {
-				return Vhffs::Functions::obfuscate_email($self->{vhffs}, $_[0]);
-			},
-			# Format filter accept only one argument
-			# pretty_print can 'sprintf' anything, use it as
-			# [% '%s is €%d' | pretty_print(article, price)]
-			pretty_print => [sub {
-				my $context = shift;
-				my @args = @_;
-				return sub {
-					my $format = shift;
-					return sprintf($format, @args);
-				}
-			}, 1]
-		}
-	};
-	
-	
 	$vars = {} unless(defined $vars);
 	
 	my $default_vars = {
@@ -87,8 +64,6 @@
 		left => 'parts/left-menu.tt',
 		right => 'parts/tags-cloud.tt',
 		top => 'parts/top-menu.tt',
-		panel_url => $conf->get_panel->{url},
-		help_url => $conf->get_panel->{url_help},
 		users_avatar => Vhffs::Functions::strtobool( $conf->get_panel->{'users_avatars'} ),
 		groups_avatar => Vhffs::Functions::strtobool( $conf->get_panel->{'groups_avatars'} )
 	};
@@ -96,23 +71,12 @@
 	$vars = {%$default_vars, %$vars};
 
 	# Handling ajax stuff
-	if($self->{is_ajax_request}) {
-		
-	} else {
-		$create_vars->{PROCESS} = 'layouts/public.tt';
+	unless($self->{is_ajax_request}) {
 		$vars->{popular_tags} = Vhffs::Tag::get_most_popular_tags($self->{vhffs});
 		$vars->{random_tags} = Vhffs::Tag::get_random_tags($self->{vhffs});
 	}
 	
-	my $template = new Template($create_vars);
-
-	binmode STDOUT , ':utf8';	
-	
-	print CGI->header( -cookie=>[ @{$self->{cookies}} ], -type=>'text/html', -charset=>'utf-8' );
-
-	$template->process($file, $vars) 
-		|| die('Error while processing template: '.$template->error());
-	
+	$self->SUPER::render($file, $vars, $self->{templatedir}.'/public/', 'layouts/public.tt');
 }
 
 1;

Copied: branches/vhffs-design/vhffs-api/src/Vhffs/Panel.pm (from rev 1369, branches/vhffs-design/vhffs-api/src/Vhffs/Panel/Main.pm)
===================================================================
--- branches/vhffs-design/vhffs-api/src/Vhffs/Panel.pm	                        (rev 0)
+++ branches/vhffs-design/vhffs-api/src/Vhffs/Panel.pm	2009-05-23 13:14:44 UTC (rev 1400)
@@ -0,0 +1,976 @@
+# Copyright (c) vhffs project and its contributors
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without 
+# modification, are permitted provided that the following conditions 
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright 
+#   notice, this list of conditions and the following disclaimer.
+#2. Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in 
+#   the documentation and/or other materials provided with the 
+#   distribution.
+#3. Neither the name of vhffs nor the names of its contributors 
+#   may be used to endorse or promote products derived from this 
+#   software without specific prior written permission.
+#
+#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+# POSSIBILITY OF SUCH DAMAGE.
+
+package Vhffs::Panel;
+require Exporter;
+@ISA    = qw(Exporter);
+@EXPORT = qw( display );
+
+use strict;
+use utf8;
+use POSIX qw(locale_h);
+use HTML::Template;
+use locale;
+use Locale::gettext;
+use CGI;
+use CGI::Session;
+use File::Spec;
+use Encode;
+
+use Vhffs::Main;
+use Vhffs::User;
+use Vhffs::Group;
+use Vhffs::Panel::Menu;
+use Vhffs::Panel::User;
+use Vhffs::Panel::Commons;
+use Vhffs::Panel::Admin;
+
+use Vhffs::Panel::Cvs;
+use Vhffs::Panel::DNS;
+use Vhffs::Panel::Mail;
+use Vhffs::Panel::MailingList;
+use Vhffs::Panel::Mysql;
+use Vhffs::Panel::Pgsql;
+use Vhffs::Panel::Repository;
+use Vhffs::Panel::Svn;
+use Vhffs::Panel::Git;
+use Vhffs::Panel::Web;
+use Vhffs::Panel::Cron;
+
+=pod
+
+=head1 NAME
+
+Vhffs::Panel - Provides acces to common VHFFS
+functionnalities from Vhffs Panel. Use Vhffs::Panel::Main
+or Vhffs::Panel::Public to do anything usefull.
+
+=head1 SYNOPSIS
+
+TODO
+
+=head1 METHODS
+
+=cut
+
+=pod
+
+=head2 check_public
+
+    $panel->check_public;
+
+Checks that public area is available, if it's not the case show a message and exits.
+
+=cut
+
+sub check_public {
+    my $panel = shift;
+    my $vhffs = $panel->{vhffs};
+    my $templatedir = $vhffs->get_config->get_templatedir;
+    if( $vhffs->get_config->get_panel->{'use_public'} ne 'yes' ) {
+        my $template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
+        $template->param( TEXT_CLOSE    => gettext('Public area not available') );
+        $template->param( TEXT_EXPLAIN  => gettext('Public area is not available on this platform.') );
+
+        $panel->light( $template );
+	$panel->display;
+        exit( 0 );
+    }
+}
+
+=pod
+
+
+=head2 is_open
+
+    $panel->is_open;
+
+Return 1 if panel is open, else return 0
+
+=cut
+
+sub is_open {
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	use Vhffs::Functions;
+	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'open'} );
+}
+
+=pod
+
+
+=head2 is_public
+
+    $panel->is_public;
+
+Return 1 if public part is enabled, else return 0
+
+=cut
+
+sub is_public {
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	use Vhffs::Functions;
+	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'use_public'} );
+}
+
+=pod
+
+
+=head2 use_avatars
+
+    $panel->use_avatars;
+
+Return 1 if either or both users or groups avatars are enabled, else return 0
+
+=cut
+
+sub use_avatars {
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	use Vhffs::Functions;
+	return ( Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'users_avatars'} )
+		|| Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'groups_avatars'} ) );
+}
+
+=pod
+
+
+=head2 use_users_avatars
+
+    $panel->use_users_avatars;
+
+Return 1 if users avatars are enabled, else return 0
+
+=cut
+
+sub use_users_avatars {
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	use Vhffs::Functions;
+	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'users_avatars'} );
+}
+
+=pod
+
+
+=head2 use_groups_avatars
+
+    $panel->use_groups_avatars;
+
+Return 1 if groups avatars are enabled, else return 0
+
+=cut
+
+sub use_groups_avatars {
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	use Vhffs::Functions;
+	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'groups_avatars'} );
+}
+
+=pod
+
+
+=head2 check_modo
+
+    $panel->check_modo
+
+Checks that logged in user is admin or moderator. If it is
+not the case, show a message and exits.
+
+=cut
+
+sub check_modo {
+    my $panel = shift;
+    my $user = $panel->{user};
+    unless($user->is_moderator || $user->is_admin) {
+        $panel->set_title( gettext('Access denied') );
+        $panel->add_error( gettext('You are not granted to access this page') );
+	$panel->build;
+	$panel->display;
+	exit 0;
+    }
+}
+
+=head2
+
+    $panel->check_admin
+
+Check that logged in user is an admin. If it is not
+the case, show a message and exits.
+
+=cut
+
+sub check_admin {
+    my $panel = shift;
+    my $user = $panel->{user};
+    unless($user->is_admin) {
+        $panel->set_title( gettext('Access denied') );
+        $panel->add_error( gettext('You are not granted to access this page') );
+        $panel->build;
+        $panel->display;
+        exit 0;
+    }
+}
+
+sub list_themes
+{
+	my $vhffs = shift;
+	return -1 unless defined $vhffs;
+
+	my @themes;
+	
+	my $dir = $vhffs->get_config->get_panel->{'themesdir'};
+	return undef unless defined $dir;
+
+	opendir( DIR , $dir) or return -2;
+	my @files = readdir( DIR );
+	foreach( @files )
+	{
+		next if( /\./);
+		if( -d $dir."/".$_ )
+		{
+			push @themes , $_;
+		}
+	}
+
+	closedir( DIR );
+	return @themes;
+}
+
+
+sub list_languages
+{
+	my $vhffs = shift;
+	return -1 if( ! defined $vhffs );
+
+    return $vhffs->get_config->get_available_languages;
+}
+
+
+
+sub select_lang {
+    my $self = shift;
+    my @langs = $self->{vhffs}->get_config->get_available_languages;
+    my $txt = '';
+	foreach my $l ( @langs )
+	{
+		$txt .= "<a href=\"auth.pl?lang=".$l."\"><img src=\"/themes/".$self->{theme}."/images/".$l.".png\" alt=\"".$l."language\"/></a>";
+	}
+	return $txt;
+}
+
+
+sub new
+{
+	my $class = ref($_[0]) || $_[0];
+	my $this = {};
+	$this->{errors} = {};
+	$this->{infos} = [];
+	$this->{cookies} = [];
+	bless( $this, $class );
+
+	my $cgi = new CGI;
+	$cgi->charset('UTF-8');
+	$this->{cgi} = $cgi;
+	$this->{url} = CGI::url();
+
+	my $vhffs = init Vhffs::Main;
+	$this->{vhffs} = $vhffs;
+	unless( defined $vhffs )  {
+		print CGI->header( -type=>'text/html', -charset=>'utf-8' ), 'Unable to open database connection\n';
+		exit 1;
+	}
+
+	my $config = $vhffs->get_config;
+	$this->{config} = $config;
+	my $templatedir = $config->get_templatedir;
+	$this->{templatedir} = $templatedir;
+
+	# lang cookie
+	my $lang = $cgi->param('lang');
+	$this->add_cookie( CGI->cookie( -name=>'language', -value=>$lang, -expires=>'+10y' ) ) if defined $lang;
+	$lang = CGI->cookie('language') unless defined $lang;
+	$lang = $vhffs->get_config->get_default_language() unless defined $lang;
+	$lang = 'en_US' unless defined $lang;
+	$this->{lang} = $lang;
+
+	setlocale(LC_ALL, $lang);
+	bindtextdomain('vhffs', '%localedir%');
+	textdomain('vhffs');
+
+	# theme cookie
+	my $theme = $cgi->param('theme');
+	$this->add_cookie( CGI->cookie( -name=>'theme', -value=>$theme, -expires=>'+10y' ) ) if defined $theme;
+	$theme = CGI->cookie('theme') unless defined $theme;
+	$theme = $config->get_panel->{'default_theme'} unless defined $theme;
+	$theme = 'vhffs' unless( defined $theme  &&  -f $config->get_panel->{'themesdir'}.'/'.$theme.'/main.css' );
+	$this->{theme} = 'vhffs';
+
+	my $template = new HTML::Template( filename => $templatedir.'/panel/main/main.tmpl' );
+	$this->{template} = $template;
+
+	if( $vhffs->is_valid() == 0 )
+	{
+		my $template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
+		$template->param( TEXT_CLOSE    => gettext("Platform temporary closed<br/>database error") );
+		$template->param( TEXT_EXPLAIN  => gettext("This platform is temporary closed. Administrators are performing some maintenances tasks or system has database errors. Please come back in a few minutes to log in.") );
+    
+		$this->light( $template );
+		$this->display;
+		exit 0;
+	}
+
+	if( $vhffs->get_config->get_panel->{'open'} ne 'yes' )
+	{
+		$template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
+		$template->param( TEXT_CLOSE    => gettext("Platform temporary closed.") );
+		$template->param( TEXT_EXPLAIN  => gettext("This platform is temporary closed. Administrators are performing some maintenances tasks. Please come back in a few minutes to log in.") );
+
+		$this->light( $template );
+		$this->display;
+		exit 0;
+	}
+	
+	$this->{is_ajax_request} = (defined $this->{cgi}->http('X-Requested-With')
+		and $this->{cgi}->http('X-Requested-With') eq 'XMLHttpRequest');
+
+	return $this;
+}
+
+
+
+sub get_session
+{
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	my $cgi = $panel->{cgi};
+
+	my $sid = $cgi->cookie( CGI::Session::name() );
+	unless( defined $sid )  {
+		$panel->add_error( gettext('No cookie found, please accept the cookie and then please login again !') );
+		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
+		exit 0;
+	}
+
+	my $session = new CGI::Session( undef, $sid, {Directory=>'/tmp'} );
+	unless( defined $session )  {
+		$panel->add_error( gettext('Cannot create or fetch session file, please check that /tmp is readable and writeable') );
+		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
+		exit 0;
+	}
+
+	my $username = $session->param('username');
+	my $uid = $session->param('uid');
+	unless(  defined $username  &&  defined $uid  &&  !$session->is_new()  )  {
+		$panel->add_error( gettext('Expired session ! Please login again') );
+		$session->delete();
+		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
+		exit 0;
+	}
+
+	my $user = Vhffs::User::get_by_uid($vhffs, $uid);
+	unless ( defined $user )  {
+		$panel->add_error( gettext('User does not exist') );
+		$session->delete();
+		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
+		exit 0;
+	}
+
+	unless( $user->get_status == Vhffs::Constants::ACTIVATED )  {
+		$panel->add_error( gettext('You\'re are not allowed to browse panel') );
+		$session->delete();
+		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
+		exit 0;
+	}
+
+	$panel->{session} = $session;
+	$panel->{user} = $user;
+	return $session;
+}
+
+
+=head2 generate_header
+
+    print $panel->generate_header;
+
+Generates panel header (account name, project label, contextuel menu, etc.).
+
+=cut
+
+sub generate_header {
+    my $panel = shift;
+    my $user = $panel->{user};
+    my $theme = $panel->{theme};
+    my $templatedir = $panel->{templatedir};
+    my $vhffs = $panel->{vhffs};
+    my $cgi = $panel->{cgi};
+
+    my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
+
+    my $menutemplate = new HTML::Template( filename => $templatedir.'/panel/menu/main.tmpl' );
+    $menutemplate->param( THEME => $theme );
+
+    $menutemplate->param( USERNAME          => $user->get_username() );
+    # Sets account type and admin link if needed
+    if( $user->is_admin == 1 ) {
+        $menutemplate->param( TEXT_ACCOUNT    => gettext('Admin account') );
+        $menutemplate->param( TEXT_ADMIN => gettext('Administration') ) 
+    } elsif( $user->is_moderator == 1 ) {
+        $menutemplate->param( TEXT_ACCOUNT    => gettext('Moderator account') );
+        $menutemplate->param( TEXT_ADMIN => gettext('Administration') ) 
+    } else {
+        $menutemplate->param( TEXT_ACCOUNT    => gettext('User account') );
+    }
+    $menutemplate->param( TEXT_HOME         => gettext('Home page') );
+    $menutemplate->param( TEXT_PREFS        => gettext("User Preferences") );
+    $menutemplate->param( TEXT_PROJECTS     => gettext('My Projects') );
+    $menutemplate->param( TEXT_HELP         => gettext("Help") );
+    $menutemplate->param( TEXT_SUBMITBUG    => gettext("Submit a bug") );
+    $menutemplate->param( TEXT_LOGOUT       => gettext("Logout") );
+    $menutemplate->param( HELP_URL          => $vhffs->get_config->get_panel->{'url_help'} || 'http://www.vhffs.org/' );
+
+    # Current project stuff (TODO stop handle it in session)
+    if( ( CGI::url( -absolute => 1) =~ /^\/admin\// ) || defined $cgi->param('admin_menu')) {
+        if( $user->is_admin ) {
+            $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_admin_ctxmenu( $vhffs->get_config ) );
+        } elsif( $user->is_moderator ) {
+            $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_moderator_ctxmenu( $vhffs->get_config ) );
+        }
+    } elsif( $group ) {
+        $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_project_ctxmenu( $vhffs->get_config , $group ) );
+    }
+
+
+    return $menutemplate->output();
+}
+
+sub has_errors
+{
+    my $panel = shift;
+    return (scalar(keys %{$panel->{errors}}) > 0);
+}
+
+sub set_title
+{
+    my ($panel, $title) = @_;
+    $panel->{title} = $title;
+}
+
+sub add_error
+{
+    my ($panel, $error, $key) = @_;
+    
+    $key = 'global' unless(defined $key);
+    
+    $panel->{errors}{$key} = [] unless(exists($panel->{errors}{$key})); 
+    
+   	push(@{$panel->{errors}{$key}}, {msg => $error});
+}
+
+sub add_info
+{
+    my ($panel, $info) = @_;
+    push(@{$panel->{infos}}, {msg => $info});
+}
+
+sub add_cookie
+{
+    my ($panel, $cookie) = @_;
+    push(@{$panel->{cookies}}, $cookie);
+}
+
+sub clear_infos
+{
+    my $panel = shift;
+    $panel->{infos} = [];
+}
+
+sub welcome
+{
+	my $panel = shift;
+	my $vhffs = $panel->{'vhffs'};
+	my $user = $panel->{'user'};
+	my $templatedir = $panel->{'templatedir'};
+
+	$panel->set_title( sprintf( gettext('Hello %s, welcome in VHFFS !'), $user->get_username() ) );
+
+	my $template = new HTML::Template( filename => $templatedir.'/panel/misc/welcome.tmpl' );
+	$template->param( TEXT_WELCOME => gettext('If you are new to VHFFS, you should start to read quickly the whole help available by clicking on the help button in the upper right of your screen') );
+
+	# check groups quota
+	my @overquota;
+	foreach my $group ( @{$user->get_groups} )  {
+		my $quota = $group->get_quota;
+		my $curused = $group->get_quota_used;
+		if( $curused > $quota-$quota/10 )  {
+			my %g = ( groupname => $group->get_groupname );
+			push @overquota, \%g;
+		}
+	}
+	if( @overquota )  {
+		$template->param( OVER_QUOTA_TEXT => gettext('The following projects have reached or are going to reach the disk quota limit, please take a look !') );
+		$template->param( OVER_QUOTA => \@overquota );
+	}
+
+	return $template;
+}
+
+
+sub project_info
+{
+	my $panel = shift;
+	my $vhffs = $panel->{vhffs};
+	my $cgi = $panel->{cgi};
+	my $templatedir = $vhffs->get_config->get_templatedir;
+	my $temp;
+	my $object;
+	my $objects;
+	my $template;
+	my $subtemplate;
+
+	my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
+		
+    if( ! defined( $group ) ) {
+        $template = new HTML::Template( filename => $templatedir."/panel/misc/simplemsg.tmpl" );
+        $template->param( MESSAGE  => gettext("Group error" ) );
+    } else {
+        $template = new HTML::Template( filename => $templatedir."/panel/group/info.tmpl" );
+        $panel->set_title( sprintf( gettext("Group %s") , $group->get_groupname ) );
+        $template->param( THEME => $panel->{theme} );
+
+        # Quota stuff
+        $template->param( QUOTA_TEXT => sprintf( gettext("Quota (used/total) : %s/%s") , $group->get_quota_used , $group->get_quota ) );
+        # Yes, sorry quota progress image has to be 300px width max
+        $template->param( QUOTA_WIDTH => ( ($group->get_quota_used / $group->get_quota) * 300 ) );
+
+        my $gid = $group->get_gid;
+        my $config = $vhffs->get_config;
+        my $services_list = '';
+
+        $template->param( TEXT_PREFS => gettext('Preferences') );
+        $template->param( TEXT_GENERAL => gettext('General') );
+        $template->param( TEXT_FULLHISTORY => gettext('Full history') );
+
+        $template->param( GROUPNAME => $group->get_groupname );
+
+	my $groupconfig = $config->get_groups;
+	if( defined $groupconfig && defined ( my $url = $groupconfig->{'url_doc'} ) )  {
+		$template->param( HELP_TEXT => gettext('Help') );
+		$template->param( HELP_URL => $url );
+	}
+
+        if($config->get_service_availability('web')) {
+            my $webs = Vhffs::Panel::Web::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('web', $webs)->output;
+        }
+
+        if($config->get_service_availability('mysql')) {
+            my $mysql = Vhffs::Panel::Mysql::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('mysql', $mysql)->output;
+        }
+
+        if($config->get_service_availability('pgsql')) {
+            my $pg = Vhffs::Panel::Pgsql::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('pgsql', $pg)->output;
+        }
+
+        if($config->get_service_availability('cvs')) {
+            my $cvs = Vhffs::Panel::Cvs::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('cvs', $cvs)->output;
+        }
+
+        if($config->get_service_availability('svn')) {
+            my $svn = Vhffs::Panel::Svn::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('svn', $svn)->output;
+        }
+
+        if($config->get_service_availability('git')) {
+            my $git = Vhffs::Panel::Git::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('git', $git)->output;
+        }
+
+        if($config->get_service_availability('mailinglist')) {
+            my $ml = Vhffs::Panel::MailingList::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('mailinglist', $ml)->output;
+        }
+
+        if($config->get_service_availability('mail')) {
+            my $mail = Vhffs::Panel::Mail::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('mail', $mail)->output;
+        }
+
+        if($config->get_service_availability('repository')) {
+            my $repos = Vhffs::Panel::Repository::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('repository', $repos)->output;
+        }
+
+        if($config->get_service_availability('dns')) {
+            my $dns = Vhffs::Panel::DNS::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('dns', $dns)->output;
+        }
+
+        if($config->get_service_availability('cron')) {
+            my $cron = Vhffs::Panel::Cron::getall_per_group( $vhffs, $gid );
+            $services_list .= $panel->create_service_index('cron', $cron)->output;
+        }
+
+        $template->param( SERVICES => $services_list );
+	}
+	return $template;
+}
+
+
+sub set_refresh_url
+{
+	my ( $panel , $url , $time ) = @_;
+
+	if( defined $url )  {
+		my $template = $panel->{template};
+		$template->param( REFRESH_URL => $url );
+		$template->param( REFRESH_TIME => $time || 3 );
+	}
+	return;
+}
+
+
+sub build
+{
+	my $panel = shift;
+	my $template = shift;
+	my $cgi = $panel->{cgi};
+	my $theme = $panel->{theme};
+	my $templatedir = $panel->{templatedir};
+
+	$panel->add_info( Encode::decode_utf8( $cgi->param('msg') ) ) if( defined $cgi->param('msg') );
+	$panel->add_error( Encode::decode_utf8( $cgi->param('error') ) ) if( defined $cgi->param('error') );
+
+	my $paneltemplate = new HTML::Template( filename => $templatedir.'/panel/main/panel.tmpl' );
+	$paneltemplate->param( THEME => $theme );
+	$paneltemplate->param( TITLE => $panel->{title} );
+	$paneltemplate->param( HEADER => $panel->generate_header );
+
+	if( @{$panel->{errors}{global}} > 0 ) {
+		my $tmplerrors = new HTML::Template( filename => $templatedir.'/panel/misc/errors.tmpl' );
+		$tmplerrors->param( ERRORS => $panel->{errors} );
+		$paneltemplate->param( ERRORS => $tmplerrors->output );
+	}
+
+	if( @{$panel->{infos}} > 0 ) {
+		my $tmplinfos = new HTML::Template( filename => $templatedir.'/panel/misc/infos.tmpl' );
+		$tmplinfos->param( INFOS => $panel->{infos} );
+		$paneltemplate->param( INFOS => $tmplinfos->output );
+	}
+
+	$paneltemplate->param( TEXT_HELP => gettext('Help') );
+	$paneltemplate->param( TEXT_HELP_CONTENT => gettext('Stay over an icon to see its description.') );
+
+	$paneltemplate->param( CONTENT => $template->output ) if( defined $template );
+
+	$panel->{content} = $paneltemplate->output;
+	return;
+}
+
+
+sub light
+{
+	my $panel = shift;
+	my $template = shift;
+	my $cgi = $panel->{cgi};
+	my $theme = $panel->{theme};
+	my $templatedir = $panel->{templatedir};
+
+	$panel->add_info( Encode::decode_utf8( $cgi->param('msg') ) ) if( defined $cgi->param('msg') );
+
+	$template->param( THEME => $theme ) if( ($template->query(name => 'THEME') || '') eq 'VAR' );
+
+	if( exists($panel->{errors}{global}) && @{$panel->{errors}{global}} > 0 ) {
+		my $tmplerrors = new HTML::Template( filename => $templatedir.'/panel/misc/errors.tmpl' );
+		$tmplerrors->param( ERRORS => $panel->{errors} );
+		$template->param( ERRORS => $tmplerrors->output );
+	}
+
+	if( @{$panel->{infos}} > 0 ) {
+		my $tmplinfos = new HTML::Template( filename => $templatedir.'/panel/misc/infos.tmpl' );
+		$tmplinfos->param( INFOS => $panel->{infos} );
+		$template->param( INFOS => $tmplinfos->output );
+	}
+
+	$panel->{content} = $template->output;
+	return;
+}
+
+
+sub display
+{
+	my $panel = shift;
+	my $template = $panel->{'template'};
+	my $cgi = $panel->{cgi};
+	my $theme = $panel->{theme};
+	my $config = $panel->{config};
+
+	$template->param( TITLE => sprintf( gettext( '%s\'s Panel' ), $config->get_host_name ) );
+	$template->param( THEME => $theme );
+
+	# Allow each theme to have its own Jscripts
+	my $jsglob = File::Spec->catfile($config->get_panel->{'themesdir'}, $theme, '/js/*.js');
+	my $jswebpath = '/themes/'.$theme.'/js/';
+	my @jscripts;
+	# Common scripts
+	push @jscripts, {SCRIPT => '/js/prototype.js'};
+	push @jscripts, {SCRIPT => '/js/commons.js'};
+	push @jscripts, {SCRIPT => '/js/tooltip.js'};
+	while( glob($jsglob) ) {
+		use File::Basename;
+		push @jscripts, {SCRIPT => $jswebpath.basename( $_ )};
+	}
+	$template->param( JSCRIPTS => \@jscripts );
+
+	$template->param( CONTENT => $panel->{content} );
+
+	binmode STDOUT , ':utf8';
+	print CGI->header( -cookie=>[ @{$panel->{cookies}} ], -type=>'text/html', -charset=>'utf-8' );
+	print $template->output;
+	return;
+}
+
+
+=pod
+
+=head2 redirect
+
+    $panel->redirect($page, $cookies);
+
+Issues a redirection header sending to $page
+(you can specify additional cookies to be sent).
+
+This function never returns.
+
+B<C<$page> should be an absolute path>
+
+B<C<$cookies>> can be a CGI::Cookie or a reference
+to a CGI::Cookie array.
+
+=cut
+sub redirect {
+    my ($panel, $dest, $cookies) = @_;
+
+    $dest = Encode::encode_utf8( $dest );
+
+    if(defined $cookies) {
+        if(ref($cookies)) {
+            foreach(@$cookies) {
+                print "Set-Cookie: $_\n";
+            }
+        } else {
+            print "Set-Cookie: $cookies\n";
+        }
+    }
+    print CGI::redirect($dest);
+    exit(0);
+}
+
+=pod
+
+=head2 create_service_index
+
+    my $webs = Vhffs::Panel::Web::get_per_group($main, $gid);
+    my $template = $panel->create_service_index('web', $webs);
+    print $template->output;
+
+Generates summary information for a given service using service_index.tmpl.
+
+=cut
+
+sub create_service_index($$$) {
+    my ($panel, $service, $services) = @_;
+    my %service_labels = (
+        cvs => 'CVS repositories',
+        dns => 'Domain names',
+        mail => 'Mail domains',
+        mailinglist => 'Mailing lists',
+        mysql => 'MySQL DBs',
+        pgsql => 'PostgreSQL DBs',
+        repository => 'Download repositories',
+        svn => 'SVN repositories',
+        git => 'Git repositories',
+        web => 'Webareas',
+	cron => 'Cron jobs',
+    );
+
+    my $vhffs = $panel->{'vhffs'};
+    my $cgi = $panel->{'cgi'};
+    my $templatedir = $panel->{templatedir};
+
+    my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
+
+    my $svclabel = $service_labels{$service};
+    my $template = new HTML::Template( filename => $templatedir.'/panel/misc/service_index.tmpl', global_vars => 1 );
+
+    my $format = sprintf( '%s for %%s', $svclabel );
+    $template->param( TEXT_TITLE => sprintf(gettext($format), $group->get_groupname) );
+    $template->param( SERVICE => $service );
+    $template->param( ADMIN_TEXT => gettext('Go to administration') );
+    $template->param( RESUBMIT_TEXT => gettext('Propose a new description') );
+    $template->param( DELETE_TEXT => gettext('Delete') );
+    $template->param( HISTORY_TEXT => gettext('History') );
+    $template->param( NEW => gettext('New') );
+    $template->param( NO_SERVICE_TEXT => gettext('None') );
+    $template->param( SERVICES => $services);
+    $template->param( GROUPNAME => $group->get_groupname );
+
+    my $serviceconfig = $vhffs->get_config->get_service($service);
+    if( defined $serviceconfig && defined ( my $url = $serviceconfig->{'url_doc'} ) )  {
+        $template->param( HELP_TEXT => gettext('Help') );
+        $template->param( HELP_URL => $url );        
+    }
+
+    return $template;
+}
+
+sub format_description($) {
+    use CGI qw{escapeHTML};
+    my $description = shift;
+    $description = escapeHTML($description);
+    $description =~ s!\n!<br/>!g;
+    return $description;
+}
+
+sub render {
+	use Template;
+	
+	my ($self, $file, $vars, $templatedir, $nonajaxtemplate) = @_;
+	
+	my $conf = $self->{vhffs}->get_config;
+	my $create_vars = {
+		INCLUDE_PATH => $templatedir,
+		FILTERS => {
+			i18n => \&gettext,
+			mail => sub {
+				return Vhffs::Functions::obfuscate_email($self->{vhffs}, $_[0]);
+			},
+			# Format filter accept only one argument
+			# pretty_print can 'sprintf' anything, use it as
+			# [% '%s is €%d' | pretty_print(article, price)]
+			pretty_print => [sub {
+				my $context = shift;
+				my @args = @_;
+				return sub {
+					my $format = shift;
+					return sprintf($format, @args);
+				}
+			}, 1]
+		}
+	};
+	
+	
+	$vars = {} unless(defined $vars);
+	
+	$vars->{theme} = $conf->get_panel->{default_theme} unless(defined $vars->{theme});
+	$vars->{errors} = $self->{errors};
+	$vars->{infos} = $self->{infos};
+
+	# Handling ajax stuff
+	unless($self->{is_ajax_request}) {
+		$create_vars->{PROCESS} = $nonajaxtemplate if(defined($nonajaxtemplate));
+	}
+	
+	my $template = new Template($create_vars);
+
+	binmode STDOUT , ':utf8';	
+	
+	print CGI->header( -cookie=>[ @{$self->{cookies}} ], -type=>'text/html', -charset=>'utf-8' );
+
+	$template->process($file, $vars) 
+		|| die('Error while processing template: '.$template->error());
+	
+}
+
+=head2 validate
+
+	$panel->validate($cgi, $rules, $use_global);
+
+C<$cgi> is the CGI object containing current request's info.
+
+C<$rules> is a HASHREF containing a key for each field to validate
+returning a HASHREF with C<mandatory> (true by default), C<regEx>
+(the validation regex) and C<message> (the error message to show
+if field value does not match regex) keys.
+
+C<$use_global> is a boolean indicating if errors should be put
+under a key corresponding to the name of the field or under
+the global key.
+
+=cut
+
+sub validate {
+	my ($self, $cgi, $rules, $use_global) = @_;
+	my $valid = 1;
+	
+	foreach my $k (keys %$rules) {
+		my $r = $rules->{$k};
+		my $value = Encode::decode_utf8($cgi->param($k));
+		
+		if(((!defined $r->{mandatory} || $r->{mandatory}) && !defined $value)
+			|| $value !~ /$r->{regEx}/) {
+			$self->add_error($r->{message}, $use_global ? undef : $k);
+			$valid = 0;
+		}
+	}
+	
+	# We do not rely on has_errors since the can be previously
+	# added errors (not related to our validation)
+	return $valid;
+}
+
+=head2 cgi
+
+Getter for C<CGI> object corresponding to the
+current request.
+
+=cut
+
+sub cgi {
+	$_[0]->{cgi};
+}
+
+=head2 vhffs
+
+Getter for the C<Vhffs::Main> object instanciated by
+the panel.
+
+=cut
+
+sub vhffs {
+	$_[0]->{vhffs};
+}
+
+1;


Property changes on: branches/vhffs-design/vhffs-api/src/Vhffs/Panel.pm
___________________________________________________________________
Name: svn:mergeinfo
   + 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/