From 14691cd854be3e9ee272c9619a6368c83d72267b Mon Sep 17 00:00:00 2001
From: Antonio Gallo <tonicucoz@gmail.com>
Date: Sat, 18 Feb 2012 00:07:50 +0000
Subject: upload new EasyGiant library and added added a new filter for the
 model name (part 2)

---
 h-source/Library/Controller.php             |  18 +-
 h-source/Library/Factory/Strings.php        |  38 ++++
 h-source/Library/Files/Upload.php           |  82 +++++++--
 h-source/Library/Helper/List.php            | 259 ++++++++++++++++++++++------
 h-source/Library/Helper/Menu.php            |  61 ++++---
 h-source/Library/Helper/Pages.php           |  21 ++-
 h-source/Library/Helper/Popup.php           |  40 ++++-
 h-source/Library/Image/Gd/Thumbnail.php     |  70 ++++++--
 h-source/Library/Lang/En/Generic.php        |  64 +++++++
 h-source/Library/Lang/En/UploadStrings.php  |   1 +
 h-source/Library/Lang/Eng/Generic.php       |  48 ++++++
 h-source/Library/Lang/Eng/UploadStrings.php |   1 +
 h-source/Library/Model/Base.php             |   5 +-
 h-source/Library/Params.php                 |   3 +
 h-source/Library/Scaffold.php               |  21 ++-
 15 files changed, 600 insertions(+), 132 deletions(-)
 create mode 100644 h-source/Library/Factory/Strings.php
 create mode 100644 h-source/Library/Lang/En/Generic.php
 create mode 100644 h-source/Library/Lang/Eng/Generic.php

(limited to 'h-source/Library')

diff --git a/h-source/Library/Controller.php b/h-source/Library/Controller.php
index 5a9ec79..b0eef53 100755
--- a/h-source/Library/Controller.php
+++ b/h-source/Library/Controller.php
@@ -41,6 +41,9 @@ class Controller {
 
 	public $argKeys = array(); //the array of keys representing the status args of the view action of the controller (validate function after colon)
 	public $argDefault = array(); //the array containing the default values of the $viewArgs array
+
+	public $argFunc = array(); //the array containing the functions to be applied upon the $viewArgs array
+	
 	public $viewArgs = array(); //the associative array representing the status args of the main action of the controller. It is the combination of $argKeys and $queryString
 	public $viewStatus = ''; //string containing the additional url string to get the status of the view action of the controller (derived from $this->viewArgs)
 
@@ -220,6 +223,11 @@ class Controller {
 		$this->callInArgKeysFunc();
 		for ($i = 0; $i < count($this->argKeys); $i++)
 		{
+			if (isset($_GET[$this->argKeys[$i]]) and strcmp($_GET[$this->argKeys[$i]],'') !== 0)
+			{
+				$this->viewArgs[$this->argKeys[$i]] = $this->request->get($this->argKeys[$i],'',$this->argFunc[$i]);
+				continue;
+			}
 			if (!isset($this->_queryString[$i])) {
 				$this->viewArgs[$this->argKeys[$i]] = isset($this->argDefault[$i]) ? $this->argDefault[$i] : null;
 				continue;
@@ -240,8 +248,14 @@ class Controller {
 	//call the functions defined in $this->argKeys after the colon (ex- 'page:forceInt' => apply the forceInt() function upon the $page arg)
 	final public function callInArgKeysFunc() {
 		for ($i = 0; $i < count($this->argKeys); $i++) {
+			
+			$this->argFunc[$i] = 'none';
+			
 			if (strstr($this->argKeys[$i],':')) {
 				$temp = explode(':',$this->argKeys[$i]);
+
+				$this->argFunc[$i] = $temp[1];
+				
 				//exception
 				if (!in_array($temp[1],explode(',',params::$allowedSanitizeFunc))) {
 					throw new Exception('"'.$temp[1]. '" function not allowed in $this->argKeys');
@@ -293,10 +307,10 @@ class Controller {
 			
 			$here = $this->controller.'/'.$this->scaffold->params['mainAction'];
 			$this->helper('Pages',$here,$this->scaffold->params['pageVariable']);
-			$this->helper('List',$this->m[$this->modelName]->identifierName);
+			$this->helper('List',$this->m[$this->modelName]->identifierName,$here,$this->scaffold->params['pageVariable']);
 
 
-			$this->helper('Popup',$here,$popupArray,$this->scaffold->params['popupType'],$this->scaffold->params['pageVariable']);
+			$this->helper('Popup',$here,$popupArray,$this->scaffold->params['popupType'],$this->scaffold->params['pageVariable'],true);
 
 			$this->scaffold->pageList = $this->h['Pages'];
 			$this->scaffold->itemList = $this->h['List'];
diff --git a/h-source/Library/Factory/Strings.php b/h-source/Library/Factory/Strings.php
new file mode 100644
index 0000000..3e766bd
--- /dev/null
+++ b/h-source/Library/Factory/Strings.php
@@ -0,0 +1,38 @@
+<?php
+
+// EasyGiant is a PHP framework for creating and managing dynamic content
+//
+// Copyright (C) 2009 - 2011  Antonio Gallo
+// See COPYRIGHT.txt and LICENSE.txt.
+//
+// This file is part of EasyGiant
+//
+// EasyGiant is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// EasyGiant is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with EasyGiant.  If not, see <http://www.gnu.org/licenses/>.
+
+if (!defined('EG')) die('Direct access not allowed!');
+
+//return the string class
+class Factory_Strings {
+
+	//return an instance of the Lang_{language}_Generic class
+	public static function generic($lang = 'En') {
+		$stringClass = 'Lang_'.$lang.'_Generic';
+		if (!class_exists($stringClass))
+		{
+			$stringClass = 'Lang_En_Generic';
+		}
+		return new $stringClass();
+	}
+
+}
diff --git a/h-source/Library/Files/Upload.php b/h-source/Library/Files/Upload.php
index f06c1c8..7dbc7d1 100755
--- a/h-source/Library/Files/Upload.php
+++ b/h-source/Library/Files/Upload.php
@@ -60,10 +60,12 @@ class Files_Upload
 			'maxFileSize' 					=>	3000000,
 			'language' 						=>	'En',
 			'allowedExtensions'				=>	'jpg,jpeg,png,gif,txt',
+			'allowedMimeTypes'				=>	'',
 			'fileUploadKey' 				=>	'userfile',
 			'fileUploadBehaviour'			=>	'add_token', //can be none or add_token
 			'fileUploadBeforeTokenChar'		=>	'_',
 			'functionUponFileNane'			=>	'none',
+			'createImage'					=>	false,
 		);
 
 		//set the $this->scaffold->params array
@@ -226,15 +228,23 @@ class Files_Upload
 	//get the extension of the file
 	public function getFileExtension($file)
 	{
-		return strtolower(end(explode('.', $file)));
+		if (strstr($file,'.'))
+		{
+			return strtolower(end(explode('.', $file)));
+		}
+		return '';
 	}
 
 	//get the file name without the extension
 	public function getNameWithoutFileExtension($file)
 	{
-		$copy = explode('.', $file);
-		array_pop($copy);
-		return implode('.',$copy);
+		if (strstr($file,'.'))
+		{
+			$copy = explode('.', $file);
+			array_pop($copy);
+			return implode('.',$copy);
+		}
+		return $file;
 	}
 
 	//get a not existing file name if the one retrieved from the upload process already exists in the current directory
@@ -243,7 +253,10 @@ class Files_Upload
 		$fileNameWithoutExt = $this->getNameWithoutFileExtension($file);
 		$extension = $this->getFileExtension($file);
 		$token = $int === 0 ? null : $this->params['fileUploadBeforeTokenChar'].$int;
-		$newName = $fileNameWithoutExt.$token.".$extension";
+
+		$dotExt = strcmp($extension,'') !== 0 ? ".$extension" : null;
+		
+		$newName = $fileNameWithoutExt.$token.$dotExt;
 		if (!file_exists($this->base.$this->directory.$newName))
 		{
 			return $newName;
@@ -465,14 +478,22 @@ class Files_Upload
 			$ext = $this->getFileExtension($nameFromUpload);
 			$nameWithoutExtension = $this->getNameWithoutFileExtension($nameFromUpload);
 
+			$dotExt = strcmp($ext,'') !== 0 ? ".$ext" : null;
+
+			//check if the "functionUponFileNane" function exists
 			if (!function_exists($this->params['functionUponFileNane'])) {
 				throw new Exception('Error in <b>'.__METHOD__.'</b>: function <b>'.$this->params['functionUponFileNane']. '</b> does not exist');
 			}
 
+			//check if the fileinfo extension is loaded
+			if (strcmp($this->params['allowedMimeTypes'],'') !== 0 and !extension_loaded('fileinfo')) {
+				throw new Exception('Error in <b>'.__METHOD__.'</b>: no MIME type check is possible because the <b>fileinfo</b> extension is not loaded');
+			}
+			
 			$nameWithoutExtension = call_user_func($this->params['functionUponFileNane'],$nameWithoutExtension);
-								
-			$fileName = isset($fileName) ? $fileName.".$ext" : $nameWithoutExtension.".$ext";
-
+			
+			$fileName = isset($fileName) ? $fileName.$dotExt : $nameWithoutExtension.$dotExt;
+			
 			$this->fileName = $fileName;
 
 			switch($this->params['fileUploadBehaviour'])
@@ -490,26 +511,51 @@ class Files_Upload
 				{
 					//check the extension of the file
 					$AllowedExtensionsArray = explode(',',$this->params['allowedExtensions']);
-
-					if (in_array($ext,$AllowedExtensionsArray))
+					
+					if (strcmp($this->params['allowedExtensions'],'') === 0 or in_array($ext,$AllowedExtensionsArray))
 					{
-						//check if the file doesn't exist
-						if (!file_exists($this->base.$this->directory.$fileName))
+						if (strcmp($this->params['allowedMimeTypes'],'') !== 0)
+						{
+							//get the MIME type of the file
+							$finfo = finfo_open(FILEINFO_MIME_TYPE);
+							$MIMEtype = finfo_file($finfo, $_FILES[$userfile]["tmp_name"]);
+							finfo_close($finfo);
+						}
+						
+						$AllowedMimeTypesArray = explode(',',$this->params['allowedMimeTypes']);
+						
+						if (strcmp($this->params['allowedMimeTypes'],'') === 0 or in_array($MIMEtype,$AllowedMimeTypesArray))
 						{
-							if (@move_uploaded_file($_FILES[$userfile]["tmp_name"],$this->base.$this->directory.$fileName))
+							//check if the file doesn't exist
+							if (!file_exists($this->base.$this->directory.$fileName))
 							{
-								@chmod($this->base.$this->directory.$fileName, $this->params['filesPermission']);
-								$this->notice = $this->_resultString->getString('executed');
-								return true;
+								if (@move_uploaded_file($_FILES[$userfile]["tmp_name"],$this->base.$this->directory.$fileName))
+								{
+									if ($this->params['createImage'])
+									{
+										//create the image
+										$basePath = $this->base.$this->directory;
+										$thumb = new Image_Gd_Thumbnail($basePath);
+										$thumb->render($fileName,$this->base.$this->directory.$fileName);
+									}
+
+									@chmod($this->base.$this->directory.$fileName, $this->params['filesPermission']);
+									$this->notice = $this->_resultString->getString('executed');
+									return true;
+								}
+								else
+								{
+									$this->notice = $this->_resultString->getString('error');
+								}
 							}
 							else
 							{
-								$this->notice = $this->_resultString->getString('error');
+								$this->notice = $this->_resultString->getString('file-exists');
 							}
 						}
 						else
 						{
-							$this->notice = $this->_resultString->getString('file-exists');
+							$this->notice = $this->_resultString->getString('not-allowed-mime-type');
 						}
 					}
 					else
diff --git a/h-source/Library/Helper/List.php b/h-source/Library/Helper/List.php
index 51ed09c..ba59643 100755
--- a/h-source/Library/Helper/List.php
+++ b/h-source/Library/Helper/List.php
@@ -22,9 +22,11 @@
 
 if (!defined('EG')) die('Direct access not allowed!');
 
-//class to create the HTML for the view action
+//class to create the HTML of a list of records
 class Helper_List extends Helper_Html {
 
+	private $__rowArray = array(); //the current associative array representing the database record
+
 	protected $_itemsList = array(); //2-dimensional associative array containing the list items
 	//keys: type,table:field,controller/action,value
 	protected $_head = array(); //2-dimensional array containing the head of the table
@@ -32,28 +34,22 @@ class Helper_List extends Helper_Html {
 
 	protected $_recordNumber = null; //number of records from the table
 
-	protected $_allowedItems = array('simpleLink','simpleText','delForm','editForm','associateForm','moveupForm','movedownForm','Form'); //type of items allowed
+	protected $_allowedItems = array('simpleLink','simpleText','delForm','editForm','associateForm','moveupForm','movedownForm','Form','ledit','link','text'); //type of items allowed
+
+	//it can be: both, top, bottom, none
+	protected $_boundaries = 'none';
 
+	//array of filters
+	protected $_filters = array();
+	
 	//set if the submit buttons have to be images or not (it can be yse or not)
-	public $submitImageType = 'no';
+	public $submitImageType = 'yes';
 
 	//set the files of the images
-	public $submitImages = array(
-		'edit'		=>	null,
-		'del'		=>	null,
-		'up'		=>	null,
-		'down'		=>	null,
-		'link'		=>	null
-	);
+	public $submitImages = array();
 
 	//set the titles of the input:submit
-	public $submitTitles = array(
-		'edit'		=>	'edit the record',
-		'del'		=>	'delete the record',
-		'up'		=>	'move up the record',
-		'down'		=>	'move down the record',
-		'link'		=>	'associate the record'
-	);
+	public $submitTitles = array();
 
 	//properties of columns
 	public $colProperties = array();
@@ -63,13 +59,46 @@ class Helper_List extends Helper_Html {
 
 	//$position: array. First element: page number, second element: number of pages
 	public $position = array();
+
+	//instance of Lang_{language}_Generic
+	public $strings = null;
+
+	//the url (controller/action) of the current page
+	public $url = null;
+
+	public $pageArg = null; //the key of the viewArgs array representing the page number. $this->viewArgs[$this->pageArg] is set to 1 if $this->pageArg !== null
 	
-	//it can be: both, top, bottom, none
-	protected $_boundaries = 'none';
+	public function __construct() {
+		
+		//get the generic language class
+		$this->strings = Factory_Strings::generic(Params::$language);
+
+		$baseUrl = 'http://'.DOMAIN_NAME.'/Public/Img/Icons/elementary_2_5/';
+
+		//set the files of the images
+		$this->submitImages = array(
+			'up'	=>	$baseUrl.'up.png',
+			'down'	=>	$baseUrl.'down.png',
+			'edit'	=>	$baseUrl.'edit.png',
+			'del'	=>	$baseUrl.'delete.png',
+			'link'	=>	$baseUrl.'link.png',
+		);
+	
+		$this->submitTitles = array(
+			'edit'		=>	$this->strings->gtext('edit'),
+			'del'		=>	$this->strings->gtext('delete'),
+			'up'		=>	$this->strings->gtext('move up'),
+			'down'		=>	$this->strings->gtext('move down'),
+			'link'		=>	$this->strings->gtext('associate')
+		);
 
-	public function build($identifierName = 'identifier')
+	}
+	
+	public function build($identifierName = 'identifier', $url = null, $pageArg = null)
 	{
 		$this->_identifierName = $identifierName;
+		$this->url = $url;
+		$this->pageArg = $pageArg;
 	}
 
 	public function setIdentifierName($identifierName)
@@ -116,8 +145,24 @@ class Helper_List extends Helper_Html {
 		}
 	}
 
+	//set the filters
+	//$filters: array whose elements are the viewArgs to be used for the filters forms
+	public function setFilters($filters)
+	{
+		$this->_filters = $filters;
+	}
 
-	//$method to extract the field name from the $action string (;table:field;)
+	//check that the ViewArgs array is complete
+	public function checkViewArgs()
+	{
+		foreach ($this->_filters as $field)
+		{
+			if (!array_key_exists($field,$this->viewArgs) and strcmp($field,null) !== 0) return false;
+		}
+		return true;
+	}
+	
+	//$method to extract the field name from the $action string (;table:field;). Used for the head
 	public function extractFieldName($string) {
 		$string = str_replace(';','',$string);
 		return $string;
@@ -125,41 +170,50 @@ class Helper_List extends Helper_Html {
 
 	//replace the strings wrapped by ; with their correspondent value taken by the $recordArray associative array (a row of the select query)
 	public function replaceFields($string,$rowArray) {
-		$stringArray = explode(';',$string);
-		for ($i = 0; $i < count($stringArray); $i++) {
-			if (strstr($stringArray[$i],':') or strstr($stringArray[$i],'.')) {
-				if (strstr($stringArray[$i],':'))
-				{
-					$char = ':';
-				}
-				else
-				{
-					$char = '.';
-				}
-				//check if a function has been indicated
-				if (strstr($stringArray[$i],'|'))
-				{
-					//get the function
-					$firstArray = explode('|',$stringArray[$i]);
-					$func = $firstArray[0];
-					//replace the fields
-					$temp =  explode($char,$firstArray[1]);
-					$stringArray[$i] = $rowArray[$temp[0]][$temp[1]];
-					
-					if (!function_exists($func)) {
-						throw new Exception('Error in <b>'.__METHOD__.'</b>: function <b>'.$func.'</b> does not exists..');
-					}
-					//apply the function
-					$stringArray[$i] = call_user_func($func,$stringArray[$i]);
-				}
-				else
-				{
-					$temp = explode($char,$stringArray[$i]);
-					$stringArray[$i] = $rowArray[$temp[0]][$temp[1]];
+		$this->__rowArray = $rowArray; //used by the replaceField  method
+
+		$string = preg_replace_callback('/(\;)(.*?)(\;)/', 'Helper_List::replaceField' ,$string);
+
+		return $string;
+	}
+
+	//replace a single string wrapped by ; with its correspondent value taken by the $recordArray associative array (a row of the select query)
+	public function replaceField($match)
+	{
+		$string = $match[2];
+		
+		if (strstr($string,':') or strstr($string,'.')) {
+			if (strstr($string,':'))
+			{
+				$char = ':';
+			}
+			else
+			{
+				$char = '.';
+			}
+			//check if a function has been indicated
+			if (strstr($string,'|'))
+			{
+				//get the function
+				$firstArray = explode('|',$string);
+				$func = $firstArray[0];
+				//replace the fields
+				$temp =  explode($char,$firstArray[1]);
+				$string = $this->__rowArray[$temp[0]][$temp[1]];
+
+				if (!function_exists($func)) {
+					throw new Exception('Error in <b>'.__METHOD__.'</b>: function <b>'.$func.'</b> does not exists..');
 				}
+				//apply the function
+				$string = call_user_func($func,$string);
+			}
+			else
+			{
+				$temp = explode($char,$string);
+				$string = $this->__rowArray[$temp[0]][$temp[1]];
 			}
 		}
-		return implode('',$stringArray);
+		return $string;
 	}
 
 	//call the method replaceFields upon the $items array using the associative array $rowArray
@@ -204,9 +258,42 @@ class Helper_List extends Helper_Html {
 			
 			$count++;
 		}
+
 		return $htmlHead;
 	}
 
+	//method to create the HTML of the head of the table
+	public function createFilters() {
+		$htmlFilters = null;
+
+		if (count($this->_filters) > 0)
+		{
+			if ($this->checkViewArgs())
+			{
+				$count = 0;
+				foreach ($this->_head as $item) {
+
+					$prop = $item['type'];
+					if (isset($this->colProperties[$count]))
+					{
+						$prop = $this->colProperties[$count];
+					}
+
+					$html = '&nbsp';
+					if (isset($this->_filters[$count]))
+					{
+						$html = $this->filterForm($this->_filters[$count]);
+					}
+					$htmlFilters .= $this->wrapColumn($html,$prop);
+
+					$count++;
+				}
+			}
+		}
+		
+		return $htmlFilters;
+	}
+
 	//create the HTML of a single row (values taken from the associative array $rowArray)
 	public function getRowList($rowArray) {
 		$htmlList = null;
@@ -266,6 +353,8 @@ class Helper_List extends Helper_Html {
 		$htmlList = null;
 		//create the HTML of the head of the record list
 		$htmlList .= $this->wrapRow($this->createHead(),'listHead');
+		//create the HTML of the filters
+		$htmlList .= $this->wrapRow($this->createFilters(),'listFilters');
 		for ($i = 0; $i < count($queryResult); $i++)
 		{
 			$this->ifInBoundaries($i);
@@ -281,18 +370,21 @@ class Helper_List extends Helper_Html {
 		$name = (strcmp($itemArray['name'],'') !== 0) ? $itemArray['name'] : $submitName;
 		$value = (strcmp($itemArray['value'],'') !== 0) ? $itemArray['value'] : $submitValue;
 
+		$oldValue = $value;
+		$value = $this->strings->gtext($value);
+		
 		if (strcmp($itemArray['title'],'') !== 0)
 		{
 			$title = "title='".$itemArray['title']."'";
 		}
 		else
 		{
-			$title = isset($this->submitTitles[$value]) ? "title='".$this->submitTitles[$value]."'" : null;
+			$title = isset($this->submitTitles[$oldValue]) ? "title='".$this->submitTitles[$oldValue]."'" : null;
 		}
 		
-		if (strcmp($this->submitImageType,'yes') === 0 and isset($this->submitImages[$value]))
+		if (strcmp($this->submitImageType,'yes') === 0 and isset($this->submitImages[$oldValue]))
 		{
-			$imgSrc = $this->submitImages[$value];
+			$imgSrc = $this->submitImages[$oldValue];
 			
 			$string .= "<input type='image' $title src='".$imgSrc."' value='$value'>\n";
 			$string .= "<input type='hidden' name='".$name."' value='$value'>\n";
@@ -343,9 +435,62 @@ class Helper_List extends Helper_Html {
 		return $string;
 	}
 
+	public function text($itemArray)
+	{
+		return $this->simpleText($itemArray);
+	}
+	
 	public function simpleLink($itemArray) {
-		$string = "<a class='linkItem' href='".Url::getRoot(null).$itemArray['action'].$this->viewStatus."'>".$itemArray['name']."</a>\n";
+		$string = "<a title='".$itemArray['field']."' class='linkItem' href='".Url::getRoot(null).$itemArray['action'].$this->viewStatus."'>".$itemArray['name']."</a>\n";
+		return $string;
+	}
+
+	public function link($itemArray)
+	{
+		return $this->simpleLink($itemArray);
+	}
+
+	public function ledit($itemArray)
+	{
+		$text = isset($this->submitImages['edit']) ? "<img src='".$this->submitImages['edit']."'>" : $itemArray['name'];
+		$title = isset($this->submitTitles['edit']) ? $this->submitTitles['edit'] : $itemArray['field'];
+		$string = "<a title='".$title."' class='linkItem' href='".Url::getRoot(null).$itemArray['action'].$this->viewStatus."'>$text</a>\n";
 		return $string;
 	}
+
+	//create the HTML of the filter
+	public function filterForm($viewArgsName)
+	{
+		$cleanName = str_replace('n!',null,$viewArgsName);
+		$cleanName = str_replace('-',null,$cleanName);
+
+		if (isset($this->viewArgs[$this->pageArg]))
+		{
+			$this->viewArgs[$this->pageArg] = 1;
+		}
+		
+		$temp = $value = $this->viewArgs[$viewArgsName];
+		//set the viewArg to the null query value
+		if (Params::$nullQueryValue)
+		{
+			$this->viewArgs[$viewArgsName] = Params::$nullQueryValue;
+			$viewStatus = Url::createUrl(array_values($this->viewArgs));
+			if (strcmp($value,Params::$nullQueryValue) === 0) $value = '';
+		}
+		$this->viewArgs[$viewArgsName] = $temp;
+		
+		$action = Url::getRoot($this->url).$viewStatus;
+		$imgSrc = Url::getRoot('Public/Img/Icons/elementary_2_5/find.png');
+		$title = $this->strings->gtext('filter');
+		$clearLinkTitle = $this->strings->gtext('clear the filter');
+		
+		$html = "<form class='list_filter_form list_filter_form_$cleanName' action='".$action."' method='GET'>\n";
+		$html .= "<input class='list_filter_input list_filter_input_$cleanName' type='text' name='$viewArgsName' value='".$value."'>";
+		$html .= "<a class='list_filter_clear_link list_filter_clear_link_$cleanName' title='$clearLinkTitle' href='$action'><img src='".Url::getRoot()."/Public/Img/Icons/elementary_2_5/clear_filter.png' /></a>";
+		$html .= "<input class='list_filter_submit list_filter_submit_$cleanName' type='image' title='$title' src='".$imgSrc."' value='trova'>\n";
+		$html .= "</form>\n";
+
+		return $html;
+	}
 	
 }
\ No newline at end of file
diff --git a/h-source/Library/Helper/Menu.php b/h-source/Library/Helper/Menu.php
index 608795f..8fd4bf4 100755
--- a/h-source/Library/Helper/Menu.php
+++ b/h-source/Library/Helper/Menu.php
@@ -29,30 +29,46 @@ class Helper_Menu extends Helper_Html
 	public $panelController; //panel controller
 	public $controller;
 
-	public $links = array(
+	public $links = array();
+
+	//instance of Lang_{language}_Generic
+	public $strings = null;
 	
-		'back'	=>	array(
-			'title'	=>	'back',
-			'class'	=>	'mainMenuItem',
-			'text'	=>	'Back',
-			'url'	=>	'main'
-		),
-		
-		'add'	=>	array(
-			'title'	=>	'add a new record',
-			'class'	=>	'mainMenuItem',
-			'text'	=>	'Add',
-			'url'	=>	'form/insert'
-		),
+	public function __construct()
+	{
+		$baseUrl = "http://".DOMAIN_NAME.'/Public/Img/Icons/elementary_2_5/';
 
-		'panel'	=>	array(
-			'title'	=>	'back to the Panel',
-			'class'	=>	'mainMenuItem',
-			'text'	=>	'Panel',
-			'url'	=>	'main'
-		)
+		//get the generic language class
+		$this->strings = Factory_Strings::generic(Params::$language);
 		
-	);
+		$this->links = array(
+
+			'back'	=>	array(
+				'title'	=>	$this->strings->gtext('back'),
+				'class'	=>	'mainMenuItem',
+				'text'	=>	$this->strings->gtext('Back'),
+				'url'	=>	'main',
+				'icon'	=>	$baseUrl."left.png",
+			),
+
+			'add'	=>	array(
+				'title'	=>	$this->strings->gtext('add a new record'),
+				'class'	=>	'mainMenuItem',
+				'text'	=>	$this->strings->gtext('Add'),
+				'url'	=>	'form/insert',
+				'icon'	=>	$baseUrl."add.png",
+			),
+
+			'panel'	=>	array(
+				'title'	=>	$this->strings->gtext('back to the Panel'),
+				'class'	=>	'mainMenuItem',
+				'text'	=>	$this->strings->gtext('Panel'),
+				'url'	=>	'main',
+				'icon'	=>	$baseUrl."panel.png",
+			)
+
+		);
+	}
 	
 	public function build($controller = null, $panelController = null)
 	{
@@ -75,6 +91,7 @@ class Helper_Menu extends Helper_Html
 				{
 					$title = isset($this->links[$linkName]['title']) ? "title='".$this->links[$linkName]['title']."'" : null;
 					$class = isset($this->links[$linkName]['class']) ? "class='".$this->links[$linkName]['class']."'" : null;
+					$icon = isset($this->links[$linkName]['icon']) ? "<img class='top_menu_icon' src='".$this->links[$linkName]['icon']."'> " : null;
 					
 					//choose the controller (current or panel)
 					$controller = (strcmp($linkName,'panel') === 0) ? $this->panelController.'/' : $this->controller.'/';
@@ -82,7 +99,7 @@ class Helper_Menu extends Helper_Html
 					
 					$href = Url::getRoot($controller.$this->links[$linkName]['url'].$viewStatus);
 					$text = $this->links[$linkName]['text'];
-					$menu .= "<div $class><a $title href='$href'>$text</a></div>\n";
+					$menu .= "<div $class>$icon <a $title href='$href'>$text</a></div>\n";
 				}
 			}
 		}
diff --git a/h-source/Library/Helper/Pages.php b/h-source/Library/Helper/Pages.php
index a6e3287..64e2649 100755
--- a/h-source/Library/Helper/Pages.php
+++ b/h-source/Library/Helper/Pages.php
@@ -22,7 +22,7 @@
 
 if (!defined('EG')) die('Direct access not allowed!');
 
-//Helper class to create the HTML of the page division list
+//Helper class to create the HTML of the page list
 class Helper_Pages extends Helper_Html
 {
 
@@ -31,17 +31,24 @@ class Helper_Pages extends Helper_Html
 	protected $_numbOfPages; //number of pages
 	protected $_variableArg = ''; //value of the $viewArgs key that has to be modified
 
-	public $previousString; //string of the link to the previous page
-	public $nextString; //string of the link to the next page
+	public $previousString = null; //string of the link to the previous page
+	public $nextString = null; //string of the link to the next page
+
+	//instance of Lang_{language}_Generic
+	public $strings = null;
+	
+	public function __construct()
+	{
+		//get the generic language class
+		$this->strings = Factory_Strings::generic(Params::$language);
+	}
 	
 	public function build($urlViewAction = '' , $variableArg = 'page', $previousString = 'previous', $nextString = 'next')
 	{
-
 		$this->_variableArg = $variableArg;
 		$this->_urlViewAction =$urlViewAction; //url of the controller and (/) main action
-		$this->previousString = $previousString;
-		$this->nextString = $nextString;
-		
+		$this->previousString = $this->strings->gtext($previousString);
+		$this->nextString = $this->strings->gtext($nextString);
 	}
 
 	//return the number of pages
diff --git a/h-source/Library/Helper/Popup.php b/h-source/Library/Helper/Popup.php
index 017e873..18bb00d 100755
--- a/h-source/Library/Helper/Popup.php
+++ b/h-source/Library/Helper/Popup.php
@@ -34,16 +34,31 @@ class Helper_Popup extends Helper_Html {
 	//the type of the popup. If type !=exclusive, than each voice selected is added to the where clause. If type=exclusive, the selection of a popup voice causes the unselection of the other voices
 	public $type = null;
 
-	public $allString = 'All';
+	public $allString = null;
 	
 	//list of popup names
 	public $popupItems = array();
+
+	//if it has to print the filter legend
+	public $printLegend = false;
+
+	//popup legend
+	public $legend = array();
+
+	public function __construct()
+	{
+		//get the generic language class
+		$this->strings = Factory_Strings::generic(Params::$language);
+		
+		$this->allString = $this->strings->gtext('All');
+	}
 	
-	public function build($url, $popupArray = null, $type = 'exclusive', $pageArg = null) {
+	public function build($url, $popupArray = null, $type = 'exclusive', $pageArg = null, $printLegend = false) {
 		$this->url = $url;
 		$this->popupArray = $popupArray;
 		$this->pageArg = $pageArg;
 		$this->type = $type;
+		$this->printLegend = $printLegend;
 		
 		foreach ($this->popupArray as $field => $popup)
 		{
@@ -70,6 +85,7 @@ class Helper_Popup extends Helper_Html {
 		}
 	}
 
+	//create the HTML of the popup
 	public function render() {
 		$returnString = null;
 		if ($this->checkViewArgs())
@@ -80,15 +96,26 @@ class Helper_Popup extends Helper_Html {
 			}
 			foreach ($this->popupArray as $field => $popup)
 			{
+				//default legend
+				$this->legend[$field] = Params::$nullQueryValue;
+				
 				if ($this->type === 'exclusive') $this->unselect($field);
 				//save the value of the current ViewArg
 				$tempArg = $this->viewArgs[$field];
+				$this->legend[$field] = $tempArg;
+				
 				$returnString .= "<ul onMouseOver='DisplayTag(this,\"block\");' onMouseOut='DisplayTag(this,\"none\");' id='menuBlock'><li class='innerItem'>".$popup->name."<ul class='innerList'>\n";
 				for ($i = 0; $i < count($popup->itemsValue); $i++)
 				{
 					$this->viewArgs[$field] = $popup->itemsValue[$i];
 					$viewStatus = Url::createUrl(array_values($this->viewArgs));
 					$returnString .=  "<li><a href='".Url::getRoot($this->url).$viewStatus."'>".$popup->itemsName[$i]."</a></li>\n";
+
+					//set the legend
+					if (strcmp($popup->itemsValue[$i],$this->legend[$field]) === 0)
+					{
+						$this->legend[$field] = $popup->itemsName[$i];
+					}
 				}
 				$this->viewArgs[$field] = Params::$nullQueryValue;
 				$viewStatus = Url::createUrl(array_values($this->viewArgs));
@@ -96,6 +123,15 @@ class Helper_Popup extends Helper_Html {
 				$returnString .= "</ul>\n</li>\n</ul>\n";
 				$this->viewArgs[$field] = $tempArg;
 			}
+			if ($this->printLegend)
+			{
+				$returnString .= "<div class='popup_legend'>\n";
+				foreach ($this->popupArray as $field => $popup)
+				{
+					$returnString .= "<div class='popup_legend_item'>".$this->legend[$field]."</div>";
+				}
+				$returnString .= "</div>\n";
+			}
 			if (count($this->popupArray)>0) {
 				$returnString .= "<script type=\"text/javascript\" src=\"http://".DOMAIN_NAME."/Public/Js/DisplayTag.js\"></script>\n";
 			}
diff --git a/h-source/Library/Image/Gd/Thumbnail.php b/h-source/Library/Image/Gd/Thumbnail.php
index 137c287..22e501e 100644
--- a/h-source/Library/Image/Gd/Thumbnail.php
+++ b/h-source/Library/Image/Gd/Thumbnail.php
@@ -38,14 +38,15 @@ class Image_Gd_Thumbnail
 		$this->basePath = $basePath;
 		
 		$defaultParams = array(
-			'imgWidth'		=>	100,
-			'imgHeight'		=>	100,
+			'imgWidth'		=>	null,
+			'imgHeight'		=>	null,
 			'defaultImage'	=>	null,
 			'cropImage'		=>	'no',
 			'horizAlign'	=>	'left',
 			'vertAlign'		=>	'top',
 			'resample'		=>	'yes',
 			'function'		=>	'none',
+			'outputFormat'	=>	'jpeg',
 		);
 
 		//set the $this->scaffold->params array
@@ -61,28 +62,45 @@ class Image_Gd_Thumbnail
 	
 	//create the thumbnail
 	//$imageName: the name of the file inside $this->basePath
-	public function render($imageFile)
+	//$outputFile: the name of the output file
+	public function render($imageFile, $outputFile = null)
 	{
 		$imagePath = $this->basePath . basename($imageFile);
 		
 		if (!file_exists($imagePath) and isset($this->params['defaultImage'])) $imagePath = $this->params['defaultImage'];
-		
+
 		$img = null;
-		$ext = strtolower(end(explode('.', $imagePath)));
+		$type = 'jpeg';
+		$contentType = 'image/jpeg';
 		
-		if (strcmp($ext,'jpg') === 0 or strcmp($ext,'jpeg') === 0) {
-			$img = @imagecreatefromjpeg($imagePath);
-		} else if (strcmp($ext,'png') === 0) {
-			$img = @imagecreatefrompng($imagePath);
-		} else if (strcmp($ext,'gif') === 0) {
-			$img = @imagecreatefromgif($imagePath);
+		if (file_exists($imagePath))
+		{
+			$ext = strtolower(end(explode('.', $imagePath)));
+
+			if (strcmp($ext,'jpg') === 0 or strcmp($ext,'jpeg') === 0) {
+				$img = @imagecreatefromjpeg($imagePath);
+				$type = 'jpeg';
+				$contentType = 'image/jpeg';
+			} else if (strcmp($ext,'png') === 0) {
+				$img = @imagecreatefrompng($imagePath);
+				$type = 'png';
+				$contentType = 'image/png';
+			} else if (strcmp($ext,'gif') === 0) {
+				$img = @imagecreatefromgif($imagePath);
+				$type = 'gif';
+				$contentType = 'image/gif';
+			}
 		}
 		
 		//If an image was successfully loaded, test the image for size
-		if ($img) {
+		if ($img)
+		{
 			//image size
 			$width = imagesx($img);
 			$height = imagesy($img);
+
+			if (!isset($this->params['imgWidth']))	$this->params['imgWidth'] = $width;
+			if (!isset($this->params['imgHeight']))	$this->params['imgHeight'] = $height;
 			
 			if ($this->params['cropImage'] === 'no')
 			{
@@ -92,7 +110,7 @@ class Image_Gd_Thumbnail
 			{
 				$scale = max($this->params['imgWidth']/$width, $this->params['imgHeight']/$height);
 			}
-			
+
 			if ($scale < 1) {
    
 				$xSrc = 0;
@@ -170,15 +188,33 @@ class Image_Gd_Thumbnail
 			
 		}
 		
-		if (!$img) {
-			$img = imagecreate($this->params['imgWidth'], $this->params['imgHeight']);
+		if (!$img)
+		{
+			$imgWidth = isset($this->params['imgWidth']) ? $this->params['imgWidth'] : 100;
+			$imgHeight = isset($this->params['imgHeight']) ? $this->params['imgHeight'] : 100;
+			
+			$img = imagecreate($imgWidth, $imgHeight);
 			imagecolorallocate($img,200,200,200);
 		}
 
 		//print the image
-		header("Content-type: image/jpeg");
-		imagejpeg($img,null,90);
+		if (!isset($outputFile))
+		{
+			header("Content-type: $contentType");
+		}
 		
+		if (strcmp($type,'png') === 0)
+		{
+			imagepng($img,$outputFile,9);
+		}
+		else if (strcmp($type,'gif') === 0)
+		{
+			imagegif($img,$outputFile);
+		}
+		else
+		{
+			imagejpeg($img,$outputFile,90);
+		}
 	}
 	
 }
\ No newline at end of file
diff --git a/h-source/Library/Lang/En/Generic.php b/h-source/Library/Lang/En/Generic.php
new file mode 100644
index 0000000..3268270
--- /dev/null
+++ b/h-source/Library/Lang/En/Generic.php
@@ -0,0 +1,64 @@
+<?php
+
+// EasyGiant is a PHP framework for creating and managing dynamic content
+//
+// Copyright (C) 2009 - 2011  Antonio Gallo
+// See COPYRIGHT.txt and LICENSE.txt.
+//
+// This file is part of EasyGiant
+//
+// EasyGiant is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// EasyGiant is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with EasyGiant.  If not, see <http://www.gnu.org/licenses/>.
+
+if (!defined('EG')) die('Direct access not allowed!');
+
+//generic strings
+class Lang_En_Generic
+{
+
+	//English to English
+	public $translations = array(
+		'edit'		=>	'edit',
+		'delete'	=>	'delete',
+		'move up'	=>	'move up',
+		'move down'	=>	'move down',
+		'associate'	=>	'associate',
+		'up'		=>	'su',
+		'down'		=>	'down',
+		'link'		=>	'link',
+		'del'		=>	'del',
+		'back'		=>	'back',
+		'Back'		=>	'Back',
+		'add a new record'	=>	'add a new record',
+		'Add'		=>	'Add',
+		'back to the Panel'	=>	'back to the Panel',
+		'Panel'		=>	'Panel',
+		'previous'	=>	'previous',
+		'next'		=>	'next',
+		'All'		=>	'All',
+		'pages'		=>	'pages',
+		'filter'	=>	'filter',
+		'clear the filter'	=>	'clear the filter',
+	);
+
+	public function gtext($string)
+	{
+		if (array_key_exists($string,$this->translations))
+		{
+			return $this->translations[$string];
+		}
+
+		return $string;
+	}
+
+}
diff --git a/h-source/Library/Lang/En/UploadStrings.php b/h-source/Library/Lang/En/UploadStrings.php
index cc4129e..61bc0c5 100644
--- a/h-source/Library/Lang/En/UploadStrings.php
+++ b/h-source/Library/Lang/En/UploadStrings.php
@@ -38,6 +38,7 @@ class Lang_En_UploadStrings extends Lang_ResultStrings {
 		"no-upload-file" => "<div class='alert'>There is no file to upload</div>\n",
 		"size-over" => "<div class='alert'>The size of the file is too big</div>\n",
 		"not-allowed-ext" => "<div class='alert'>The extension of the file you want to upload is not allowed</div>\n",
+		"not-allowed-mime-type" => "<div class='alert'>The MIME type of the file you want to upload is not allowed</div>\n",
 		"file-exists" => "<div class='alert'>The file is already present in the current folder</div>\n"
 	);
 	
diff --git a/h-source/Library/Lang/Eng/Generic.php b/h-source/Library/Lang/Eng/Generic.php
new file mode 100644
index 0000000..bb0ab99
--- /dev/null
+++ b/h-source/Library/Lang/Eng/Generic.php
@@ -0,0 +1,48 @@
+<?php
+
+// EasyGiant is a PHP framework for creating and managing dynamic content
+//
+// Copyright (C) 2009 - 2011  Antonio Gallo
+// See COPYRIGHT.txt and LICENSE.txt.
+//
+// This file is part of EasyGiant
+//
+// EasyGiant is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// EasyGiant is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with EasyGiant.  If not, see <http://www.gnu.org/licenses/>.
+
+if (!defined('EG')) die('Direct access not allowed!');
+
+//generic strings
+class Lang_Eng_Generic
+{
+
+	//English to English
+	public $translations = array(
+		'edit'		=>	'edit',
+		'delete'	=>	'delete',
+		'move up'	=>	'move up',
+		'move down'	=>	'move down',
+		'associate'	=>	'associate',
+	);
+
+	public function gtext($string)
+	{
+		if (array_key_exists($string,$this->translations))
+		{
+			return $this->translations[$string];
+		}
+
+		return $string;
+	}
+
+}
diff --git a/h-source/Library/Lang/Eng/UploadStrings.php b/h-source/Library/Lang/Eng/UploadStrings.php
index 00809f6..2ae4c9b 100644
--- a/h-source/Library/Lang/Eng/UploadStrings.php
+++ b/h-source/Library/Lang/Eng/UploadStrings.php
@@ -38,6 +38,7 @@ class Lang_Eng_UploadStrings extends Lang_ResultStrings {
 		"no-upload-file" => "<div class='alert'>There is no file to upload</div>\n",
 		"size-over" => "<div class='alert'>The size of the file is too big</div>\n",
 		"not-allowed-ext" => "<div class='alert'>The extension of the file you want to upload is not allowed</div>\n",
+		"not-allowed-mime-type" => "<div class='alert'>The MIME type of the file you want to upload is not allowed</div>\n",
 		"file-exists" => "<div class='alert'>The file is already present in the current folder</div>\n"
 	);
 	
diff --git a/h-source/Library/Model/Base.php b/h-source/Library/Model/Base.php
index 57d769a..4162a56 100755
--- a/h-source/Library/Model/Base.php
+++ b/h-source/Library/Model/Base.php
@@ -121,7 +121,7 @@ abstract class Model_Base
 	protected $_arraySoftCheck; //Array_Validate_Soft object
 	
 	public $db; //reference to the database layer class
-	protected $_lang = 'En'; //language of notices
+	protected $_lang = null; //language of notices
 
 
 	public function __construct() {
@@ -136,6 +136,9 @@ abstract class Model_Base
 		
 		$this->identifierName = $this->_idFieldsArray[0];
 
+		//set the language of notices
+		$this->_lang = Params::$language;
+
 		//create the $_resultString object (result strings of the db queries)
 		$modelStringClass = 'Lang_'.$this->_lang.'_ModelStrings';
 		if (!class_exists($modelStringClass))
diff --git a/h-source/Library/Params.php b/h-source/Library/Params.php
index 488c8b2..c0c7ece 100644
--- a/h-source/Library/Params.php
+++ b/h-source/Library/Params.php
@@ -57,4 +57,7 @@ class Params
 	//subfolder of the View folder where to look for view files
 	public static $viewSubfolder = null;
 
+	//global website language used by the models and by the helpers
+	public static $language = 'En';
+
 }
\ No newline at end of file
diff --git a/h-source/Library/Scaffold.php b/h-source/Library/Scaffold.php
index ec0dc49..7e43134 100755
--- a/h-source/Library/Scaffold.php
+++ b/h-source/Library/Scaffold.php
@@ -51,6 +51,9 @@ class Scaffold
 	//the list of fields of the select query
 	public $fields = null;
 
+	//instance of Lang_{language}_Generic
+	public $strings = null;
+	
 	public function __construct($type,$controller,$model,$viewArgs,$params = null) {
 
 		$this->_type = $type;
@@ -58,6 +61,9 @@ class Scaffold
 		$this->model = $model;
 		$this->viewArgs = $viewArgs;
 
+		//get the generic language class
+		$this->strings = Factory_Strings::generic(Params::$language);
+		
 		$autoParams = array(
 			'mainAction'		=>	'main',
 			'modifyAction'		=>	'form/update',
@@ -120,19 +126,22 @@ class Scaffold
 				switch ($el)
 				{
 					case 'moveup':
-						$this->itemList->addItem('moveupForm',$this->_controller.'/'.$this->params['mainAction'],$primaryKey);
+						$this->itemList->addItem('moveupForm',$this->_controller.'/'.$this->params['mainAction'],";".$primaryKey.";");
 						break;
 					case 'movedown':
-						$this->itemList->addItem('movedownForm',$this->_controller.'/'.$this->params['mainAction'],$primaryKey);
+						$this->itemList->addItem('movedownForm',$this->_controller.'/'.$this->params['mainAction'],";".$primaryKey.";");
 						break;
 					case 'link':
-						$this->itemList->addItem('associateForm',$this->_controller.'/'.$this->params['associateAction'],$primaryKey);
+						$this->itemList->addItem('associateForm',$this->_controller.'/'.$this->params['associateAction'],";".$primaryKey.";");
 						break;
 					case 'edit':
-						$this->itemList->addItem('editForm',$this->_controller.'/'.$this->params['modifyAction'],$primaryKey);
+						$this->itemList->addItem('editForm',$this->_controller.'/'.$this->params['modifyAction'],";".$primaryKey.";");
 						break;
 					case 'del':
-						$this->itemList->addItem('delForm',$this->_controller.'/'.$this->params['mainAction'],$primaryKey);
+						$this->itemList->addItem('delForm',$this->_controller.'/'.$this->params['mainAction'],";".$primaryKey.";");
+						break;
+					case 'ledit':
+						$this->itemList->addItem('ledit',$this->_controller.'/'.$this->params['mainAction'].'/;'.$primaryKey.';','Edit','Edit');
 						break;
 				}
 			}
@@ -274,7 +283,7 @@ class Scaffold
 				$popupHtml = "<div class='verticalMenu'>\n".$this->html['popup']."\n</div>\n";
 			}
 
-			$this->html['all'] = "<div class='mainMenu'>".$this->html['menu']."</div>\n".$this->model->notice."\n $popupHtml \n<div class='recordsBox'>\n".$this->html['main']."\n</div>\n"."<div class='viewFooter'>\n<div class='pageList'>\n".$this->html['pageList']."</div>\n</div>\n\n";
+			$this->html['all'] = "<div class='mainMenu'>".$this->html['menu']."</div>\n".$this->model->notice."\n $popupHtml \n<div class='recordsBox'>\n".$this->html['main']."\n</div>\n"."<div class='viewFooter'>\n<div class='pageList'>\n<span class='page_list_legend'>".$this->strings->gtext('pages').":</span> ".$this->html['pageList']."</div>\n</div>\n\n";
 
 		}
 		else if ($this->_type === 'form')
-- 
cgit v1.2.3