Understanding Noah's Classifieds/Multiple Image Extension


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 FunctionalityEdit

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.phpEdit

Because any and all object_vars are automatically saved to the database it is problomatic 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 )
                // NEW DAWID
                if (!isset($typ["attributes"][$attribute]))
                // NEW DAWID

Modifying gorum/object.phpEdit

Change the function getVisibility as shown

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

Adding New Database FieldsEdit

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.phpEdit

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 schemeEdit

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 AssumptionsEdit

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 compatibality 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 6 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 seperated 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 incomming images
  • showDetials()
    Shows the detailed view of the advertisement

delete in Advertisement.phpEdit

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.phpEdit

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');

hidding the original PICTURE element, advertisement.phpEdit

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.phpEdit

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
        // NEW CODE DAWID

valid(), advertisement.phpEdit

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. Just delete the entire thing.

storeAttachment(), advertisement.phpEdit

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.phpEdit

Change everything inside


To be

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

advertisement.php include image.phpEdit

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

Finally More Functions, advertisement.phpEdit

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 over 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 tempelate 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 )
        // DAWID
    if( !isset( $typ["attributes"][$attr] ) ) {
        return "";
        // DAWID
    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()
        // DAWID JOUBERT
        return $s;

Source CodeEdit

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

Trouble ShootingEdit

Having trouble copying source from wiki?

Wiki screws up on some of the characters.. many ' have been changed to ' and you need to change them back

Italian LanguageEdit

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

// If you don't find a languege 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["purchaseSuccessfull"]="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.";
Last modified on 17 June 2011, at 20:39