Understanding Noah's Classifieds/Multiple Image Extension

From Wikibooks, open books for an open world
Jump to navigation Jump to search


In Noah's classifieds an advert can only submit one image, we want to submit n images.

First you will need this new file, save it is image.php in your root folder of Noah. Image.php Source

Target Functionality[edit]

Now let's first talk about our target. We want the following features:

  • Obviously all created data must be deleted upon the removal of the advert
  • Use HTML Text as a spacer between images
  • Dynamically create the upload fields so submission is not cluttered
  • Remove a single image without deleting the ad
  • Allow for dynamic setting of maxImageCount, maxImageSize, maxImageThumb and whether single delete function is available

Here is a snapshot of the end result

Modifying gorum/dbproperty.php[edit]

Because any and all object_vars are automatically saved to the database it is problematic to use $this->data to pass data from one function to the next. To get around this the following modification needs to be made to dbproperty.php

function getCreateSetStr($base, $typ, $create=TRUE)
    $object_vars = get_object_vars($base);
    $firstField = TRUE;
    $query = "";
    $typ = $base->getTypeInfo();
    foreach( $object_vars as $attribute=>$value )
		if (!isset($typ["attributes"][$attribute]))

Modifying gorum/object.php[edit]

Change the function getVisibility as shown

function getVisibility( $typ, $attr )
    global $gorumroll;
	if (!isset($typ["attributes"][$attr]))
		return Form_hidden;

Adding New Database Fields[edit]

Firstly we need to add 7 new rows to our category database (Table:classifieds_classifiedscategory)

imagesAllowed, Type int(4), default = 10, Unsigned
ThumbSizeX, Type int(10), default = 64, Unsigned
ThumbSizeY, Type int(10), default = 100, Unsigned
imageMaxSizeX, Type int(12), default = 800, Unsigned
imageMaxSizeY, Type int(12), default = 600, Unsigned
imageSpacer, Type varchar(250), default = 'HTML TEXT'
imageRemove, Type int(2), default = '1'

These are the new rows that I added. From the information you can see that imagesAllowed will have a range of 0-16, thumbSize 0-1024 and imageSize 0-2048. If these are too little or too much adjust accordingly so that it doesn't hog database space.

Here is the SQL Script for adding these

ALTER TABLE `classifieds_classifiedscategory` 
ADD `imagesAllowed` INT( 4 ) UNSIGNED NOT NULL DEFAULT '10',
ADD `imageMaxSizeX` INT( 12 ) UNSIGNED NOT NULL DEFAULT '800',
ADD `imageMaxSizeY` INT( 12 ) UNSIGNED NOT NULL DEFAULT '600',
ADD `imageSpacer` VARCHAR( 250 ) NOT NULL DEFAULT '
<img src="i/spacer.gif" alt="." width="$thumbWidth" height="20" />', ADD `imageRemove` INT( 2 ) DEFAULT '1' NOT NULL ;

Modifying Category.php[edit]

Add these to the top of the file just below this one shown. These tell Noah that we have added new fields to the database

$category_typ["attributes"]["imagesAllowed"] =  
                "max" =>"16",
$category_typ["attributes"]["thumbSizeX"] =  
                "max" =>"1024",
$category_typ["attributes"]["thumbSizeY"] =  
                "max" =>"1024",
$category_typ["attributes"]["imageMaxSizeX"] =  
                "max" =>"2048",
$category_typ["attributes"]["imageMaxSizeY"] =  
                "max" =>"2048",
$category_typ["attributes"]["imageSpacer"] =  
                "max" =>"250",
				"default"=>'<br/><img src="i/spacer.gif" alt="." width="$thumbWidth" height="20" />'
$category_typ["attributes"]["imageRemove"] =  

Modify lang_en.php as to stay consistent with language scheme[edit]

Now we also need to add the following to lang_en.php (and all the other languages you plan on using). For consistency add it after the comment that says "Category"

// Dawid Joubert Image Editing
$lll["imagesAllowed"]="Number of Images Allowed";
$lll["thumbSizeX"]="Generated Thumbnails' size X";
$lll["thumbSizeY"]="Generated Thumbnails' size Y";
$lll["imageMaxSizeX"]="Max Image Size X";
$lll["imageMaxSizeY"]="Max Image Size Y";
$lll["imageSpacer"]="HTML Text to place after each image (use as spacer)";
$lll["imageFileNotLoaded"]='Image file not saved/created!';
$lll["imageRemoveEnabled"] = 'Enable Image Remove Button ';
$lll["removeImage"] = "Remove This Image";
$lll["missingImage"] = "Image does not exist, unable to remove it!";
$lll["detail_removeImage"] = "Image Removal";
$lll["imageRemove"] = "Image Remove Button Enabled?";

Consistency and Assumptions[edit]

Images are saved under "$adAttDir/$this->id".".".$ext and their thumbnails "$adAttDir/th_$this->id".".".$ext. This format is not a problem for storing single images but is for storing multiple images. So we will be modifying it.

First to maintain backward compatibility we will keep the current format for the first image in the sequence however the second, third and nth image will have this pattern.

Full Image:"$adAttDir/$this->id"."-$i.".$this->picture


Where $i is the image number starting from 0 so if a user had six jpeg images they will be named as follows:

pictures/listings/5.jpg		// First image. Shown in advert listing
pictures/listings/5-0.jpg	// Second Image. Shown in details view (when viewing the advert)
pictures/listings/5-1.jpg	//	""
pictures/listings/5-2.jpg	//	""
pictures/listings/5-3.jpg	//	""
pictures/listings/5-4.jpg	//	""

The function extensions will be saved into the picture row of the advertisement in a comma separated format "jpg,gif,jpg" we will then split this format into an array like this one array("jpg","gif","jpg").

So we will need to modify these functions and some others:

  • delete()
    This function is called when you remove the advertisement
  • showListVal()
    This function is called for every piece of information that is shown both in the advert listing and in the advert's details itself. We need this function so that it now lists all the pictures when viewing the advert details
  • activateVariableFields()
    This function needs to be modified so that it displays options for uploading n amount of images
  • storeAttatchment()
    Modify so that it actually stores all incoming images
  • showDetials()
    Shows the detailed view of the advertisement

delete in Advertisement.php[edit]

Replace everything inside

if ($this->picture) 
.. Old Code ..

With this so that the entire block looks like (Now any1 just dare tell me this doesn't look cleaner!!!)

	if( $this->picture )
		$limit = count($this->imageExtensions);				
		for ($i=0;$i < $limit;$i++)

showListVal() in advertisement.php[edit]

Replace everything in

elseif ($attr=="showpic") 
 ..old source code...


 	 elseif ($attr=="showpic") 
	$s="<img src='$adAttDir/no.png'>";	// Will be overwritten later
	if($this->picture && $this->imagesAllowed)	// Do we have any extensions to work with?
		// Create the image extensions for use
		// Are we in the details view?
		if ($gorumroll->method == "showdetails")
			$limit = count($this->imageExtensions);				
			$s = '';					
			for ($i=0;$i < $limit;$i++)
				if (strlen($this->imageExtensions[$i]) > 2)
					$s .= $this->getImageHTML($i)."<br />";						
			$tempRoll = $gorumroll;
			$tempRoll->list = $itemClassName;
			$tempRoll->method = "showdetails";
			$tempRoll->rollid = $this->id;		
			// Just make the output equal to a single image
			$s= $this->getImageHTML($0,tempRoll->makeUrl(),'_self');

hiding the original PICTURE element, advertisement.php[edit]

At the top of advertisement.php is $item_typ["attributes"]["picture"] = {..}; Add this to the array "form invisible", this will make sure that it is not added to the form when modifying/creating adds. The above-mentioned declaration will now look like this.

$item_typ["attributes"]["picture"] =  
                "max" ='>'"250",
		"form hidden" // NEW LINE

// Fixed on 2007-01-16

ActivateVariableFields() in advertisement.php[edit]

Modify the function as shown

	// Create new input boxes for each picture, but only if we are creating a new advert or modifying an existing one
	if (($gorumroll->method == "modify_form") || ($gorumroll->method == "create_form"))
		$i = 0;
		$lll["picture0"]=$lll["pictureTemp"];	// Creates language thingies
 		$temp = "";
		for ($i = 0;$i	<	$this->imagesAllowed;$i++)
			// Generate remove text
			if (($gorumroll->method == "modify_form") && ($this->imageRemove))
				$tempRoll = $gorumroll;
				$tempRoll->list = $itemClassName;
				$tempRoll->method = "remove_image";
				$tempRoll->rollid = $this->id;			
				$tempRoll->imageID = $i;
				$remText = $tempRoll->generAnchor($lll["removeImage"]);
			} else $remText = "";
			// Just make the output equal to a single image
			$temp2 = (file_exists($this->getImageName($i)) ? $this->getImageHTML($i) : "");
			if ($temp2 != "") 
				$temp2 .='<br/>'.$remText;
			$temp[$i] = '<br />'.$temp2;		
		if ($showCount == 0) $showCount = 1;
		$item_typ["attributes"]["picture0"] =  
					"multiple file",
					"max" =>"250",
					"count" => $this->imagesAllowed,
					"extraLabel" => $temp,
					"showCount_dj" => $showCount

valid(), advertisement.php[edit]

This function validates the single image that is uploaded before the image is stored. The rest of the validation is done by the class this one inherits from. Delete it all.

storeAttachment(), advertisement.php[edit]

This function has been modified almost entirely, just copy over the new function.

 function storeAttachment()
    global $HTTP_POST_FILES;
    global $whatHappened, $lll, $infoText;
    global $adAttDir, $applName, $itemClassName;
    global $maxPicSize;
	// New code
    // Load this class
	$this->getImageLimits();		// Get the dimensions and stuff allowed
	$parsedAtleastOne = false;
	$count = 0;
	// Loop for every image allowed
	for ($i = 0;$i	<	$this->imagesAllowed;$i++)
		if ((isset($this->imageExtensions[$count]) == false))
			$this->imageExtensions[$count] = ".";
		if (strlen($this->imageExtensions[$count]) > 2) 
			$hasImage = true;
		} else $hasImage = false;
		$ind = "picture$i";
	    if (!isset($HTTP_POST_FILES[$ind]["name"]) || $HTTP_POST_FILES[$ind]["name"]=="")

		if (!file_exists($HTTP_POST_FILES[$ind]["tmp_name"]))
			// This should never happen
			handleError("Temp Image doesn't exists?? WTF");			

		if (strstr($HTTP_POST_FILES[$ind]["name"]," "))
        	$infoText .= $lll["spacenoatt"].'<br />';
	    if ($HTTP_POST_FILES[$ind]["tmp_name"]=="none")
	    if ($HTTP_POST_FILES[$ind]["size"] > $maxPicSize) 
	        $infoText .= sprintf($lll["picFileSizeToLarge2"], $maxPicSize).'<br />';
		$size = getimagesize($fname);
		if (!$size) 
			$infoText.=$lll["notValidImageFile"].'<br />';
		$type = $size[2];
		global $g_Extensions;	// Found in image.php
		if (!isset($g_Extensions[$type])) 
			$infoText .=$lll["notValidImageFile"].'<br />';
	// We are checking dimensions anymore as we might as well resize the image
/*		if( $size[0]>$this->imageMaxSizeX || $size[1]>$this->imageMaxSizeY )
			$infoText .=sprintf($lll["picFileDimensionToLarge"], $this->imageMaxSizeX, $this->imageMaxSizeY).'<br />';
			$whatHappened = "invalid_form";
		}	*/	
		if ($hasImage) $count--;
		// Instanciate a new image
		$image = new myImage;
		// Read the image

		// Remove old pictures and thumbnails
		// Save the image extension
		$this->imageExtensions[$count] = $g_Extensions[$type];					

		// Now create our image
		if ($image->CreateLocal($this->getImageName($count),$this->imageMaxSizeX$,this->imageMaxSizeY))
			// Create the thumb
			$parsedAtleastOne = true;			
			// Why wasn't it created, could it be because the file format doesn't support resizing
			if ($image->supported == false)
				$infoText .=sprintf($lll["picFileDimensionToLarge"], $this->imageMaxSizeX, $this->imageMaxSizeY).'<br />';
				else $infoText.=$lll["imageFileNotLoaded"].'<br />';
			$this->imageExtensions[$count] = ".";			
	if ($parsedAtleastOne)
    return ok;

showDetails(), advertisement.php[edit]

Change everything inside


To be

		$s.="<tr><td valign='top' align='left' rowspan='30' class='cell'>\n";

advertisement.php include image.php[edit]

at the top of the file call include("./image.php");

Finally More Functions, advertisement.php[edit]

Add these new functions to the top of the file (advertisement.php) This first set can go anywhere before the class declaration

// Advertisement specific image functions
function cleanDelete($name)
	if (file_exists($name))
		// Attempt to delete
		if(!$ret) $infoText=sprintf($lll["cantdelfile"],$name);
		return $ret;
	return true;

function getImageExtensionsFromString($string)
	return	split('[,]', $string);

function createImageExtensionsStringFromArray($arr)
	$out = "";
	foreach ($arr as $value)
		$out .= $value.',';
	return $out;


These second functions must be placed within the class. Place them just after

class Advertisement extends Item


// Advertisement specific image functions

	function getImageExtensions()
		if (isset($this->picture))
			$this->imageExtensions = getImageExtensionsFromString($this->picture);

	function getImageName($i)
		if (!isset($this->imageExtensions[$i])) return "";
		global $adAttDir;
		if ($i != 0)
			return	$fileName = "$adAttDir/$this->id"."-$i.".$this->imageExtensions[$i];
		else return	$fileName = "$adAttDir/$this->id".".".$this->imageExtensions[$i];

	function getThumbName($i)
		if (!isset($this->imageExtensions[$i])) return "";
		global $adAttDir;
		if ($i != 0)
			return	$thumbName = "$adAttDir/th_$this->id"."-$i.".$this->imageExtensions[$i];
		else return	$thumbName = "$adAttDir/th_$this->id".".".$this->imageExtensions[$i];

	function getImageHTML($i$,link = false$,target='_blank')
		if (!isset($this->imageExtensions[$i])) return "";
		if (strlen($this->imageExtensions[$i]) < 2) return "";
		$picName = $this->getImageName($i);	// Get the first image
		$thName = $this->getThumbName($i);	// Get the first thumb

		// If the thumbnail doesn't exists use the original picture's name instead.
		if (!file_exists($thName)) $thName = $picName;
		if (!file_exists($picName)) return "";

		// Okay now we need to find the dimensions of the thumbnail and scale them for viewing.
		// If it really is a thumbnail we won't have to scale using html. If it isn't then we have no
		// other choice as the reason no thumb exists is because this format is not supported by php
		$size = getimagesize( $thName );
		$size = RatioImageSize($size,$this->thumbSizeX,$this->thumbSizeY,true);
		if ($link == false)
			return "<a href='$picName' target='$target'><img src='$thName' width='$size[0]' height='$size[1]' border='0'></a>$this->imageSpacer";
		else return "<a href='$link' target='$target'><img src='$thName' width='$size[0]' height='$size[1]' border='0'></a>$this->imageSpacer";

	// Get the image settings from this advert's category	
	function getImageLimits()
		//if (!isset($this->imageLimitsLoaded)) return;
	    global $categoryClassName;
        $c = new $categoryClassName;
        $c->id = $this->cid;
        $this->imagesAllowed = $c->imagesAllowed;
		$this->imageRemove = $c->imageRemove;
        $this->thumbSizeX = $c->thumbSizeX;
        $this->thumbSizeY = $c->thumbSizeY;
        $this->imageMaxSizeX= $c->imageMaxSizeX;		
        $this->imageMaxSizeY= $c->imageMaxSizeY;		
		$this->imageLimitsLoaded = true;
		// Construct the image spacer
		$this->imageSpacer = 
		// Quick validation test
		if ($c->imagesAllowed)
			if ($c->thumbSizeX * $c->thumbSizeY * $c->imageMaxSizeX * $c->imageMaxSizeY <= 0)
				die('Image dimensions impossible');
	function Debug($text=false)
		if (false)
			echo $text;
			if (isset($this->imageExtensions))
				echo array_to_str($this->imageExtensions);
			if (isset($this->picture))
				echo array_to_str($this->picture);

	 	function renameImage($from$,to)
		if (!isset($this->imageExtensions[$from]) || (strlen($this->imageExtensions[$from]) < 2)) 
			$this->imageExtensions[$to] = "";
		$this->Debug('Before Rename<br/>');
		$s = "";
		// Collect the names
		$thumbNameFrom = $this->getThumbName($from);
		$imageNameFrom = $this->getImageName($from);

		// Rename the image		
		if (file_exists($imageNameFrom))
			$tempExt = $this->imageExtensions[$to];
			$this->imageExtensions[$to] = $this->imageExtensions[$from];		
			$thumbNameTo = $this->getThumbName($to);
			$imageNameTo = $this->getImageName($to);		
			if (rename($imageNameFrom,$imageNameTo))
				if (file_exists($thumbNameFrom))
					if (rename($thumbNameFrom,$thumbNameTo) == false)
						$s .= " Thumbnail $thumbNameFrom couldn't be renamed to $thumbNameTo<br/>";
				$s .= " Image $imageNameFrom couldn't be renamed to $imageNameTo<br/>";
				$this->imageExtensions[$to]	= $tempExt;
		$this->Debug("After Rename:$s<br/>");		
		return $s;

	function updatePictureField()
		global $applName, $itemClassName;
		$newPic = addslashes(createImageExtensionsStringFromArray($this->imageExtensions));
		if ($newPic == $this->picture) return;
		$this->picture = $newPic;
		// Create the extensions string
		$query = "UPDATE $applName"."_$itemClassName SET picture='$this->picture'".
				 " WHERE id=$this->id";
		executeQuery( $query );
 function removeImage(&$s)
     global $whatHappened, $charLimit, $infoText, $lll$,gorumroll;
     global $immediateAppear, $allowModify, $adminEmail, $itemClassName;
     // Load this class
     $this->id = $gorumroll->rollid;
     global $mainBoxWidth$,mainBoxPadding;
     if (!isset($mainBoxWidth)) $mainBoxWidth="100%";
     if (!isset($mainBoxPadding)) $mainBoxPadding="2";
     if( !$isAdm && !$allowModify )
 	 $infoText = "fdsaafsd";
 	if (!isset($_GET['imageID'])) $_GET['imageID'] = 0;
 	// Remove image and let user know
 	if (is_numeric($_GET['imageID']))
 		$i = abs($_GET['imageID']);	
 		 $infoText = "$i";		
 		// Delete this image
 		if( $this->picture )
 			if (!isset($this->imageExtensions[$i])) 
 				$infoText = $lll["missingImage"];
 			$imgName = $this->getImageName($i);
 			if (file_exists($imgName))
 				$infoText = "Image $i has been deleted. ";
 				// Now move down any other images by renaming them. This is the difficult part!
 				$limit = count($this->imageExtensions);
 				for ($i=$i+1;$i < $limit;$i++)
 					$infoText .= $this->renameImage($i$,i-1);	
 				// Now we must update this $->Picture	
 			else $infoText = $lll["missingImage"];
 		else $infoText = $lll["missingImage"];
 	else $infoText =$lll["missingImage"];
 // Map Functionality	


Open gorum/form.php and modify generForm(..) by adding this to the massive if branch.

elseif( in_array("file",$val))
            $s.=generFileField($attr$,txt, $expl,
                               $inputLength, $fieldLength,
                               "cell", "", $afterField);
		// DAWID
		elseif( in_array("multiple file",$val))
			$count = $val["count"];
			$s.=generFileField($attr$,txt, $expl,
							   $inputLength, $fieldLength,
							   "cell", "", $afterField,$count,
							   isset($val["extraLabel"]) ? $val["extraLabel"] : false,
							   isset($val["showCount_dj"]) ? $val["showCount_dj"] : false);
		// DAWID
        elseif( in_array("text",$val) )
            $s.=generTextField("text",$attr$,txt, $expl, 
                               "cell", "", TRUE, $afterField);


Open gorum/generformlib_filebutton.php and go to generFileField(..) and copy the changes (or replace the entire function)

function generMultipleFileJavascript($count,$postText,$idUsed,$theHiddenValue,$shownCount="1",$preText="my",$style='')

	// The big problem is getting init events to load with the page...
	return "\n<script type=\"text/javascript\">
var maxElements$idUsed = $count;
var currentID$idUsed = -1;
var addTextLine;

function addEvent$idUsed()
	if ((currentID$idUsed < 0) || (currentID$idUsed >= maxElements$idUsed)) 
		addTextLine.className = \"hiddenRow\";	
	var ni = document.getElementById(\"$preText\"+currentID$idUsed+\"$postText\");
	ni.className = \"$style\";
	if ((currentID$idUsed < 0) || (currentID$idUsed >= maxElements$idUsed)) 
		addTextLine.className = \"hiddenRow\";	
function initEvents$idUsed()
	var start =$shownCount;
	for (i = start;i	<	maxElements$idUsed;i++)
		var ni = document.getElementById(\"$preText\"+i+\"$postText\");
		ni.className = \"hiddenRow\";
	currentID$idUsed = start;
	addTextLine = document.getElementById(\"$preText"."addText"."$postText\");
	addTextLine.className = \"$style\";	
	return true;
<style type=\"text/css\">

// DAWID JOUBERT: Count is used and it represents how many consecutive files the user may upload.
// If this is more than one it will add so many fields, including dynamic html (javascript for it).
// It will take the field's name and parse a number to it at the end, removing the last current character.
// So if you want to use this feature make sure your $name=image0 because 0 will be replaced with the integer count
function generFileField($name,$label,$explText,$size="",$maxlength="",
                        $tdCl="", $spanCl="", $afterField="",$count=1,$extraLabel = false,$showCount = 1)
    global $list2Colors, $jsElementCount;
    if (isset($list2Colors)) 
        if ($list2Colors && $tdCl=="cell") {
        $list2Colors = ($list2Colors + 1) % 2;
	// Dawid Joubert
	if ($count > 1)
		$addMore = true;
		$preText = 'my';
		$postText = $name;
		$idUsed = $preText$.postText;
		$newName = substr($name,0,-1);	// Remove last character
		// Okay now generate our javascript!
	} else $addMore = false;
	// Dawid joubert
	// First construct our template field
	for ($i = 0;$i < $count;$i++)
		// First Cache the new field
			if ($tdCl!="") $t.=" class='$tdCl'";
			if ($addMore) $t.=" id='$preText$i$postText'";
			if ($tdCl!="") $t.=" class='$labelCl'";
			if ($spanCl!="") $t.="<span class='$spanCl'>";
			if ($i == 0) $t.=$label;
			if (isset($extraLabel[$i])) $t.=$extraLabel[$i];		
			if ($spanCl!="") $t.="</span>";
			if($explText && $i = 0) $t.=generExplanation($label,$explText);        
			if ($addMore) $name = $newName$.i;
			$t.="<input type='FILE' name='$name'";
			if ($size!="") $t.=" size='$size'";
			if ($maxlength!="") $t.=" maxlength='$maxlength'";
		// Done caching
	// Dawid
	if ($addMore)
		if ($showCount != $count) 
			// Show the add more button
			if ($tdCl!="") $t.=" class='hiddenRow'";
			$t.=" id='$preText"."addText"."$postText'";
			if ($tdCl!="") $t.=" class='$labelCl'";
			if ($spanCl!="") $t.="<span class='$spanCl'>";
			$t.="<a href=\"javascript:;\" onclick=\"addEvent$idUsed();\">Add another File</a>";	
			if ($spanCl!="") $t.="</span>";
			$s.= $t;
		// Insert the javascript just before </head>
		global $g_Extras$,g_extraDoOnLoad;
		$g_Extras.= generMultipleFileJavascript($count$,postText$,idUsed$,name+time(),$showCount$,preText$,tdCl);
		$g_extraDoOnLoad .= "initEvents$idUsed();\n";
    return $s;


Modify it to this

function getDefault( $typ, $attr )
    if( !isset( $typ["attributes"][$attr] ) ) {
        return "";
    else $attrInfo = & $typ["attributes"][$attr];
    //if (!isset($attrInfo["type"])) echo "attr:$attr ";
    if( isset($attrInfo["default"]) ) {
        return $attrInfo["default"];
    //if(!isset($attrInfo["type"])) echo $attr;
    if( ereg("INT", $attrInfo["type"]) ) {
        return 0;
        // Note: even if min==1 !!!
    if( ereg("CHAR", $attrInfo["type"]) ) {
        return "";
        // Note: even if min==1 !!!
    if( ereg("TEXT", $attrInfo["type"]) ) {
        return "";


Add this anywhere in constants.php

$allowedMethods["remove_image"] = '$base->removeImage(&$s);';


Add this to the bottom of function showHtmlHead()

    elseif ($language=="lt") {
        $s.="<META HTTP-EQUIV='content-type' CONTENT='text/html;".
            " charset=windows-1257'>";
	// DAWID JOUBERT HOOK—needed for javascript hooking
	global $g_Extras$,g_extraDoOnLoad;
<script type=\"text/javascript\">
function doOnLoad()
	return $s;

Source Code[edit]

Download here: http://www.noah.inv.pl/forum/index.php?topic=228.msg656#msg656

Trouble Shooting[edit]

Having trouble copying source from wiki?

Wiki errs on some of the characters.. many ' have been changed to ' and should be reverted

Italian Language[edit]

The Italian language file has been translated. Here it is:

// If you don't find a language file in your language in this directory,
// you should translate this file and save as 'lang_xx.php' (where xx
// is the country abbreviation). For how to translate, you can take the 
// already translated files as an example.
// Some instructions: don't insert any new line breaks in the file however long
// a line is! Don't rewrite anything else, only what you translate! Don't
// change the order of the lines! Don't write any spaces or new lines after the last line of the file
// (careful! some text editors put new lines at the end of the files automatically)!
// Translate the other language file, too: 'gorum/lang/lang_en.php'!
// If you are ready with the files, you must write the following line 
// in 'constants.php' to activate the new language:

// $language="xx";

// (of course without the leading '//' comment tag)
// If you are ready with the translation, please, send us the translated
// language files (classifieds@phpoutsourcing.com), so that we can release
// them in the next version!
// New for translation:------------------------------------
$lll["settings_showSubmitAd_expl"]="If this is unchecked, only admin can submit an ad";
$lll["settings_expiration_expl"]="0 means that the ads never expire - i.e. expiration disabled.<br><br>Warning: Once you disable ad expiration, don't re-enable it again later any more!";
$lll["u_maintitle"]="Noah's Classifieds update process";
$lll["secure_copy"]="It is recommended to save a rescue copy from the old version of Noah's Classifieds before the update.<br>Copy the program files in a separate directory and make a data base dump for sure!<br>Click OK to continue, or Cancel to abort the update process!";
$lll["ready_to_update"]="Ready to update data base %s to version %s?<br>";
$lll["invalid_version"]="The given version is invalid: %s";
$lll["updateSuccessful"]="The update successfully completed.<br>Hint: As admin, click on the 'Check' menu point to view the state of the classifieds system!";
$lll["updating"]="Updating from version %s to version %s...";
$lll["already_installed"]="The given software version %s is already installed.";
$lll["backToForum"]="Return to the classifieds.";
$lll["settings_showChangePassword"]="Mostra 'Cambia password'";
$lll["settings_showLogout"]="Mostra 'Logout'";
$lll["settings_showLogin"]="Mostra 'Login'";
$lll["settings_showRegister"]="Mostra 'Registra'";
$lll["settings_showMyProfile"]="Mostra 'Il Mio Profilo'";
$lll["settings_showMyAds"]="Mostra 'I Miei Annunci'";
$lll["settings_showSubmitAd"]="Mostra 'Invia Annuncio'";
$lll["settings_showRecentAds"]="Mostra 'Annunci Recenti'";
$lll["settings_showMostPopularAds"]="Mostra 'Annunci Popolari'";
$lll["settings_showSearch"]="Mostra 'Cerca'";
$lll["settings_showHome"]="Mostra 'Home'";
$lll["menuPointsSep"]="Impostazioni Menu";
$lll["expirationProperties"]="Impostazioni scadenze";
$lll["imageProperties"]="Limiti upload immagini";
$lll["otherProperties"]="Altre Configurazioni";
$lll["settings_renewal"]="Numero volte che un utente puo' prolungare la scadenza del suo annuncio";
$lll["settings_allowModify"]="L'utente puo' modificare il suo annuncio";
// ShoppingCart:
$lll["addToChart"]="Aggiungi al carrello";
$lll["shoppingCartLink"]="Link al carrello";
$lll["addedToTheCart"]="The item has been added to the end of the cart. Increase the amount if you want to purchase more items!";
$lll["shoppingcart"]="shopping cart item";
$lll["shoppingcart_ttitle"]="My shopping cart";
$lll["shoppingcart_recent_ttitle"]="Most recent purchases";
$lll["shoppingcart_track_ttitle"]="My purchases";
$lll["shoppingcart_title"]="Item title";
$lll["myCart"]="My shopping cart";
$lll["total"]="Prezzo totale";
$lll["amountModified"]="The amount has been successfully modified.";
$lll["loginToPurchase"]="You must log in first to add an item to your shopping cart.";
$lll["viewOrders"]="View orders";
$lll["usersShoppingCart"]="Orders of %s";
$lll["shoppingcart_orderNumber"]="Order #";
$lll["shoppingcart_orderDate"]="Purchase-shippment date";
$lll["ordered"]="p: %s";
$lll["shipped"]="s: %s";
$lll["recentPurchases"]="Recent purchases";
$lll["trackPurchases"]="My purchases";
$lll["classifiedsuser_fullName"]="Full name";
$lll["classifiedsuser_zipCode"]="Zip code";
$lll["purchaseSuccessful"]="Your purchase has been successfully completed";
$lll["purchaseFailed"]="Your purchase has been failed";
$lll["purchaseFailedNetworkError"]="Your purchase has been failed, since VeriSign couldn't access the MIJ site. Please, contact the site administrator!";
$lll["mailok"]="Il test di invio e.mail e' stato superato brillantemente.";
$lll["mailerr"]="Ho riscontrato i seguenti errori durante il test di invio e.mail:<br>%s";
$lll["mailerr_expl"]="There are some features in Noah's Classifieds that necessitates sending out mails. Our program applies standard mail headers which are readable by the majority of mail servers. However, there are some mail servers (mostly Windows based) that would require a non-standard mail header. With these mail servers (yours seems to be amongst (or you might not have a mail server at all!), unfortunately), Noah's Classifieds may not be able to send out mails.";
$lll["here1"]="click qui";
$lll["confpreerr"]="There are some characters before the <? in the config file! Please delete these characters (newlines and spaces too)!";
$lll["confposterr"]="There are some characters after the ?> in the config file! Please delete these characters (newlines and spaces too)!";
$lll["conffileok"]="The config file seems to be ok.";
$lll["congrat"]="Congratulazioni! Hai installato con successo bachecaweb!";
$lll["confcheck"]="System configuration checking...";
$lll["confdisapp"]="If you want to begin to work with the software and you want this page to disappear";
$lll["confclicheck"]="You can access this configuration checking page whenever you want if you click on the 'Check' link in the menubar.";
$lll["chadmemail"]="Your current email adress is admin@admin.admin. Please set it correctly clicking on the 'My profile' link on the menubar!";
$lll["chsyspass"]="Your current system email adress is system@system.system. Please set it correctly clicking on the 'Settings' link on the menubar!";
$lll["chadmpass"]="The default admin password is not changed yet! Please change it clicking on the 'Change password' link on the menu bar!";
$lll["settings_adminEmail"]="System email";
$lll["nogd"]="Warning: your server doesn't have an installed GD library.";
$lll["nogd_expl"]="(This library is responsible in php programs for the image manipulation, so it might be anyway useful if you put it on your server. In our program it is called for creating thumbnail images to the full sized uploaded pictures. Without this support the program can't generate thumbnails, this way the browser have to shrink 'on-the-fly' each big image in each pages where thumbnails can appear. This method works, but it is far from effective (the page have to download every time every big image). )";
$lll["nopermission"]="The server process has no write permission under the 'pictures/listings' and/or 'pictures/cats' directories.<br>You should go in 'pictures' and execute the following Unix command (in Unix systems, of course):<br><i>chmod 777 listings cats</i>";
$lll["nopermission_expl"]="(Noah's Classifieds tries to save the advertisement pictures under 'pictures/listings' and the category pics under 'pictures/cats'. You have to make sure the program has enough permission to do this.)";
//user overwritten:
$lll["paymentSection"]="Informazioni Pagamento";
$lll["loggedinas"]="Sei entrato come %s.";
$lll["regorlog"]="Registrati o fai il login!";
$lll["my_profile"]="Il Mio Profilo";
$lll["classifiedscategory_allowAd"]="Consenti annunci";
$lll["classifiedscategory_ttitle"]="Categorie Annunci";
$lll["cat_main_tit"]="Categorie Annunci";
$lll["modcat"]="Modifica questa Categoria";
$lll["delcat"]="Cancella questa Categoria";
$lll["directsubcats"]="Sottocategorie dirette";
$lll["directitemnum"]="Annunci diretti";
// Dawid Joubert Image Editing
$lll["imagesAllowed"]="Numero di immagini permesse";
$lll["thumbSizeX"]="anteprima size X";
$lll["thumbSizeY"]="Anteprimasize Y";
$lll["imageMaxSizeX"]="Massima dimensione dell'immagine asse X";
$lll["imageMaxSizeY"]="Massima dimensione dell'immagine asse Y";
$lll["imageSpacer"]="Testo HTML da inserire dopo ogni immagine (usato come spazio)";
$lll["imageFileNotLoaded"]='Immagine non salvata/creata!';
$lll["removeImage"] = "Rimuovi questa immagine";
$lll["missingImage"] = "L'immagine non esiste, impossibile rimuoverla!";
$lll["detail_removeImage"] = "Rimuovi immagine";
$lll["imageRemove"] = "Abilitare il bottone di rimozione immagine?";

$lll["advertisement_newitem"]="Invia Annuncio";
$lll["advertisement_create_form"]="Invia Annuncio";
$lll["advertisement_modify_form"]="Modifica Annuncio";
$lll["advertisement_ttitle"]="Annunci in questa Categoria";
$lll["advertisement_my_ttitle"]="I Miei Annunci";
$lll["advertisement_expirationTime"]="Giorni rimanenti prima della scadenza";
$lll["keepPrivate"]="Nascondi i campi Privati";
$lll["expirationProlonged"]="La data di scadenza e' stata prolungata con successo.";
$lll["lastRenewal"]="<br>Questo era l'ultimo prolungamento possibile.";
$lll["advertisement_my_title"]="I Miei Annuci";
$lll["advertisement_inactive_title"]="Immissioni inattive";
$lll["ad_limit_exc"]="Il limite massimo e' di %s caratteri. Tu hai scritto %s caratteri! Abbrevia il tuo annuncio, grazie!";
$lll["inactives"]="Annunci inattivi";
$lll["new_resp"]="Rispondi a questo annuncio";
$lll["response_create_form"]="Rispondi a questo annuncio";
$lll["yourname"]="Il tuo nome";
$lll["youremail"]="La tua Email";
$lll["friendsname"]="Il nome del tuo amico";
$lll["friendsemail"]="La Email del tuo amico";
$lll["response_mess"]="Il tuo messaggio";
$lll["friendmail_mess"]="Il tuo messaggio";
$lll["mail_sent"]="L'annuncio e' stato inviato correttamente.";
$lll["mail_fr_sent"]="Abbiamo inviato l'Email al tuo amico.";
$lll["clickclose"]="Chiudi questa finestra.";
$lll["new_frie"]="Invia annuncio ad un amico";
$lll["friendmail_create_form"]="Invia annuncio ad un amico";
$lll["advertisementActive"]="Annuncio Approvato";
$lll["advertisementInactive"]="Annunci in Attesa";
$lll["advertisement_active_ttitle"]="Annunci Approvati";
$lll["advertisement_inactive_ttitle"]="Annunci in Attesa";
$lll["adApproved"]="L'annuncio e' stato approvato";
$lll["adScheduled"]="e' in attesa di approvazione. Riceverai una e.mail di notifica.";
$lll["popular"]="Piu' popolari";
$lll["advertisement_popular_ttitle"]="Lista Annunci Popolari";
// picture upload
$lll["picFileSizeToLarge1"]="Errore! Non posso aprire l'immagine allegata, o l'immagine e' troppo grande.";
$lll["picFileSizeNull"]="L'immagine allegata presenta degli errori.";
$lll["picFileSizeToLarge2"]="L'immagine scelta come allegato supera il massimo consentito di %s byte";
$lll["picFileDimensionToLarge"]="Le dimensioni dell'immagine scelta come allegato superano il massimo consentito di %s x %s";
$lll["notValidImageFile"]="Il file scelto non e' una immagine valida (deve essere gif, jpg, o png).";
$lll["cantOpenFile"]="Errore nell'apertura del file!";
$lll["cantdelfile"]="Alcune immagini caricate potrebbero non essere state cancellate.";
$lll["settings_expiration"]="Giorni alla scadenza dell'annuncio";
$lll["settings_expNoticeBefore"]="Numero di giorni antecedenti in cui l'utente viene avvisato della scadenza del suo annuncio";
$lll["settings_charLimit"]="Numero dei caratteri massimi consentiti per un annuncio";
$lll["settings_immediateAppear"]="Un nuovo annuncio appare immediatamente";
$lll["settings_blockSize"]="Annunci mostrati per pagina";
$lll["settings_maxPicSize"]="Pesantezza massima dell'immagine in bytes";
$lll["settings_maxPicWidth"]="Larghezza massima dell'immagine in pixels";
$lll["settings_maxPicHeight"]="Altezza massima dell'immagine in pixels";
$lll["settings_thumbnailWidth"]="Larghezza Thumbnail";
$lll["settings_thumbnailHeight"]="Altezza Thumbnail";
$lll["classifiedssearch_relationBetweenFields_".search_allFields]="tutte le condizioni";
$lll["classifiedssearch_relationBetweenFields_".search_anyFields]="qualsiasi condizione";
$lll["classifiedssearch_create_form"]="Cerca Annunci";
$lll["classifiedssearch_relationBetweenFields"]="Cerca risultati che includono";
$lll["classifiedssearch_title"]="Contenuto del titolo";
$lll["allCategories"]="Tutte le categorie";
$lll["advertisement_search_ttitle"]="Risultati della Ricerca";
$lll["advancedSearch"]="Ricerca avanzata nella catagoria - cerca annuncio che:";
$lll["contains"]=" contiene";
$lll["is"]=" e'";
$lll["forAddvancedSearch"]="Per una ricerca avanzata in una specifica Categoria, entra nella Categoria prescelta e clicca su 'Cerca'!";
// Variable Fields // fatto sino a qui guido
$lll["variableFields"]="Definisci variabili";
$lll["varfields_modify_form"]="Definisci le variabili per gli annunci di questa categoria";
$lll["varfields_modifydetails_form"]="Dettagli dei campi variabili";

$lll["defineTheValues"]="Definisci i valori possibili del campo di selezione.";
$lll["defineTheName"]="Definisci il nome dei campi attivi.";
$lll["mustBeCommaSeparated"]="I valori possibili devono essere separati da virgola";
$lll["invalidDefaultValue"]="Il valore di Default deve essere uno dei valori separati da virgola del campo di selezione.";
$lll["showCreationTime"]="Mostra data di Creazione nella Lista";
$lll["showExpirationTime"]="Mostra data di Scadenza nella Lista";
global $variableFieldsNum;
for( $i=0; $i<$variableFieldsNum; $i++ )
    $lll["type_$i"."_".varfields_multipleselection]="Seleziona Multipla";
    $lll["type_$i"."_expl"]="Note: To avoid type conflicts, if you have ever set this column to active and there are already advertisements in this category, you can't change the type any more. If you insist on changing the type anyway, you have to remove all advertisements from the category first.";
    $lll["default_$i"]="Valore di Default";
    $lll["separator_$i"]="Colonna ".($i+1).".";
    $lll["list_$i"]="Appare nella lista";
    $lll["values_$i"]="Valori Possibili";
    $lll["innewline_$i"]="Inserisci in una nuova linea";
    $lll["badwords_$i"]="Applica Bad Words";
    $lll["allowHtml_$i"]="Consenti HTML";
    $lll["private_$i"]="Consenti Annuncio Privato";
    $lll["hidden_$i"]="Visibile solo da Admin";
    $lll["format_$i"]="Display format";
    $lll["format_$i"."_expl"]="You can use it a C-style sprintf format string";
// Ha ez be van allitva akkor a formokban a privatta teheto mezok neve 
// utan irodik:

// Menu points:
$lll["advertisement_my"]="I Miei Annunci";
$lll["advertisement_Active"]="Annunci Approvati";
$lll["advertisement_Inctive"]="Annunci in Attesa";
$lll["advertisement_recent"]="Annunci Recenti";
$lll["advertisement_popular"]="Annunci Popolari";
$lll["myads"]="I Miei Annunci";
$lll["allemails_tit"]="Tutte le Email nel sistema";
$lll["recentadded"]="Annunci Recenti";
$lll["advertisement_all_ttitle"]="Annunci aggiunti di recente";
$lll["registerOrLoginToSubmit"]="Registrati e fai il login per inviare i tuoi annunci!";
$lll["selectSubcat"]="Seleziona una sottocategoria per inserirvi il tuo annuncio!";
$lll["loggedas"]="Sei entrato come %s.";
$lll["logorreg"]="Registrati o fai il login.";