[ amitkic @ 26.12.2008. 01:05 ] @
Naucio sam html i css. Naucio osnove PHP i MYSQL, ono sto mi treba je preporuka neke knjige, moze i na engleskom, o samom postupku pisanja neke web aplikacije. Znaci od pocetka pa do kraja pravljenja neke aplikacije, da na primer opisuje sam raspored foldera, pisanje klasa, funkcija itd., nadam se da ste razumeli kakva mi knjiga treba.
[ b0ris @ 26.12.2008. 17:02 ] @
Ako si vec naucio sve osnove zasto ne pocnes sam da pravis, tako ces najbolje da naucis.
Ako zelis, "uz dopustenje admina", mozemo da iskoristimo ovu temu da napravimo jedan sajt od pocetka do kraja :)
Znaci da definisemo sve sto je potrebno i da sve napravimo ovde.
Najbolje da sve bude iz naseg rukava, pa da posle iskoristimo vec postojece klase da unapredimo aplikaciju.
Sta mislis o tome?
[ Mister_rap @ 26.12.2008. 22:30 ] @
Ovo nije bas za advanced PHP...

Generalno mozes da preuzmes neku od popularnih OpenSource aplikacija i da analiziras kod da vidis kako se snalazis i primenis neke od tih principa, takodje moze da se pozabavis ucenjem ili analizom nekog frejmworka za PHP.

Ova knjiga nije bas za PHP ali ti moze koristiti ako te zanima web:

Software Engineering for Modern Web Applications: Methodologies and Technologies,
Daniel M. Brandon


Takodje (nisam je citao ali sam pregledao i deluje ok za to sto ti treba):

Advanced PHP Programming - George Schlossnagle

U svakom slucaju Borisova ideja je ok i mozete tako nesto da radite...
[ amitkic @ 27.12.2008. 01:30 ] @
sto se tice knjiga nabavio sam :
http://www.apress.com/book/view/1590599063
http://www.manning.com/reiersol/
http://www.apress.com/book/view/1590599098
http://www.amazon.com/Object-O...-Techniques-Code/dp/1593270771

a evo kod koji sam danas napravio za registracionu formu, koji radi, ali treba da se sredi pa recite sta treba da uradim ili gde gresim
[ dakipro @ 27.12.2008. 11:11 ] @
evo nekoliko principa organizacije projekta sa kojima sam se susretao i koji su mi ok. Sa nekima i radim svakodnevno.
Potpuno modularni sistem
Code:

/admin/index.php      --admin specific logika
/class/                    --mesto za generalne klase, mailere, adodb, smarty, seo, config, validacija...

/modules/               --mesto gde svaki modul drzi svoje fajlove, tako da se lako dodaju/brisu moduli, samo se ceo folder doda

//pojedinacni moduli:
/modules/banner/admin/index.php  --admin logika za taj modul
/modules/banner/class              --objekti koji cine taj modul, handleri za objekte modula
/modules/banner/templates        --templejti module, public i admin
/modules/banner/images            --slike koje taj module koristi, ikonica za admin meni, neke specificne za public
/modules/banner/css                
/modules/banner/translations      --prevodi labela modula
/modules/banner/js                   --specificni js za taj modul, 
/modules/banner/sql                  --sql za instalaciju i deinstalaciju modula
/modules/baner/index.php          --public logika modula


/themes/           --teme celog sajta

/uploads/ime_modula                  --svi uploadi kroz aplikaciju

/scripts                  --js i css generalnog dela

/config.php

index.php     --public related logika



drugi inspirisan zend frameworkom koji je malo manje modularan po strukturi, jer su svi moduli dinamicki kontrollisani iz baze. Imaju svoje prednosti (brzinu) i imaju ogranicenja po neka, jer svi koriste iste resurse pa je malo tricki menjati nesto. naravno, posto nasledjuju generalni objekat, samo se dopise metoda i svi moduli pice kako njima odgovara.
Code:

/www/index.php       --folder kome se pristupa iz browsera, svi ostali fajllovi su skriveni u folderu ispod www root-a
/www/scripts/         --svi jsovi, editori i css fajlovi sajta, podfolder po temama
/logic/          admin.php i public.php        --specificna logika za admin ipublic
/logic/admin/  (/public/)       --svi kontroler fajlovi za logiku sajta (tu se ustvari pozivaju metode objekata, recimo users_log.php, category_log.php)
/class/           --sve klase koje se koriste na sajtu
/templates/    --svi templejti sajta, uglavnom imenovani po modulima, pod folder sa nazivom teme


Gornji princip instalira odredjeni modul veoma lako, samo se copy-paste folder iz repository, kroz superadmin se instalira i poveze se menijima, a donji princip ne moze tek tako da instalira nov modul, vise se menja po bazi recimo nego po fajlovima, fajlovi se dodaju na puno razlicitih mesta pa je zaista tricky. iako mislim da bi se nakon malo ulaganja u instalciju modula, slicno moze postici i donjim principom.

Takodje je dobra Aleksandrova preporuka, skini neki projekat i vidi kako tamo organizuju to, i tako pici. Mozes procitati i zend framework jer tamo dobro opisuju organizaciju zasto i kako. nemoras da je usvojis, ali ces imati ideju. Naravno, probaj nesto da menjas po kodu, cisto da imas uvid u to kako to zaista radi i gde je sta, sto se funkcionalnosti tice.
A jos bolje bi bilo da nadjes nekog mentora koji ce to da ti objasni uzivo i na nekom primeru ;)
AKo te zanimaju konkretniji delovi aplikacija, ti pisi.


Pogledao sam tvoj kod, i sad pricam o organizaciji.
U oba ova slucaja gore se koristi fuze-in-box metoda, tj sve ide kroz jedan index.php fajl, hvataju se neka podesavanja pa se posle logika grana prema potrebama.
Znaci url koji kaze /index.php?module=blog vodi na taj blog, /index.php?module=blog&section=post_new grana do dela koji prikazuje formu. U tvom slucaju:


index.php

Code:

//uvuci neke config parametre, konekciju na bazu, definisi konstante sajta (napravi neki BASE_PATH, potrazi forum cemu sluzi), naziv, seo, menije, najcesce koriscene funckije itd.

//switch koji odredjuje koja logika sajta je trenutno aktuelna (koji modul se koristi)

switch (get[module]){


//razni casovi, tj moduli
case "kontakt" :
//require  kontakt logika
break;



}



kontakt_log.php
Code:

//neka podesavanja za trenutni modul, seo, selektovani meni, naziv sajta itd

//switch sekcije modula

switch (section){

default:
case "post_form"


//akoje forma submitovana, ubaci je u bazu
if (post-hiddenField==1){
  //znaci forma ima neki hidden field kojim znamo da je forma submitovana
  //obradimo i ubacimo kontakt u bazu ili posaljemo na mail
  //ako je sve ok, redirektujemo na hvala stranicu, ako nesto ne valja, samo pustimo kod dalje koji ce da prikaze formu
}

//izvadis templejt i prikazes ga korisniku. ako nesto ima u postu, prosledis to templejtu, tako da ako je nesto pogresno uneo, naprivmer email format, ostala polja ce mu biti sacuvana


break;



case "hvala_na_kontaktu"
   //prikaze se obavestenje da je forma poslata
break;

}




Ovo je kratko kratko, ako te zanima ovakav pristup ili nesto iz njega, pisi.
[ b0ris @ 27.12.2008. 11:19 ] @
Hvala Mister_rap
Posto smo dobili zeleno svetlo da napravimo aplikaciju onda je bitno da krenemo iz pocetka.
Baziracemo se na pukoj osnovi bez koriscenja ikakvih sporednih alata.
Kad aplikacija bude gotova, onda ce mo je unaprediti dodatnim alatima i pokazati njihovu moc u odnosu na ono sto smo do tad koristili.

Zadatak:
Napraviti aplikaciju/sajt koji ima dinamicko dodavanje strana, vise jezicku podrsku i administraciju texta i slika koje se nalaze na sajtu.

Redosled pravljenja aplikacije:
1. Analiza sajta i ocena broja sati za pravljenje istog.
2. Izbor alata potrebnih za pravljenje sajta.
3. Postavljanje kostura.
4. Zapocnimo pravljenje klasa a zatim i stranica :)

Rad
1. Analiza sajta
dinamicko dodavanje strana - ovo ce mo realizovati preko baze podataka putem tabele pages.
administracija texta i slika - relaizovati takodje preko baze podataka putem tabele paragraph.
vise jezicka podrska - realizovati preko baze podataka putem tabele languages, i napraviti vezu sa 1-M sa tabelom pages i paragraph.

Broj sati potrebnih za konstrukciju sajta:
Buduci da ce mo pisati iz pocetka (od 0) citavu aplikaciju bez koriscenja ikakvih pomagala bice potrebno dosta vremena da ovo napravimo.
Mnogo vise nego sto se to moze postici sa koriscenjem dodatnih alata.
Recimo da ce nam trebati oko 80 sati da ovako nesto napravimo.


2.Izbora alata
Buduci da ce mo sajt praviti od 0 ovaj korak mozemo da preskocimo.
Iskoristicu ovaj deo da napomenem par stvari koje ce biti osnovne u radu.
Koriscenje engleskog jezika je "a must" :)
Koristicemo phpDocumentator (http://www.phpdoc.org) za komentarisanje.
To su neke osnove koje ce mo koristiti tokom rada.


3. Postavljanje kostura

- cms (ovde ce mo staviti sve sto je potrebno za kreiranje cms sistema)
-- base (osnova u koju ce mo staviti sve klase koje su potrebne da se ucitaju na pocetku)
-- pages (ovde ce mo staviti sve strane koje ce biti koriscene u procesu)
-- tools (folder u kome se nalaze ostali alati potrebni za rad)
- base (osnova u koju ce mo staviti sve klase koje su potrebne da se ucitaju na pocetku)
- pages (ovde ce mo staviti sve strane koje ce biti koriscene u procesu)
- tools (folder u kome se nalaze ostali alati potrebni za rad)
- uploads (cuvanje svih uplodovanih fajlova)
-- users (fajlovi koje ce korinik stavljati)
-- sys (sistemeski fajlovi koje ce mo mi postaviti)


4. Zapocinjanje pravljenja klasa i same aplikacije
Klase potreben za rad
- DB: klasa za kontrolu data base sistema NAPRAVLJENA http://www.elitesecurity.org/t348963-0#2149953
- Session: klasa za kontrolisanje sesije
- UrlHandler: klasa koja ce kontrolisati sve sto se tice url-a.


Za sad ce mo postaviti samo ovo sto je gore navedeno zatim ce mo tokom procesa kreiranja sajta dodavati nove klase i verovatno povecati kostur.
Ovaj post ce biti menjan shodno promenama koje mi budemo pravili. Svaka promena ce biti obelezena drugom bojom i datumom promene.


Za sad toliko od mene a uskoro slede postovi sa osnovnim kodom za gore navedene klase. Ti postovi ce biti takodje menjani kako budu klase rasle, a svaka promena ce biti oznacena bojom i datumom.

[Ovu poruku je menjao b0ris dana 28.12.2008. u 13:03 GMT+1]

[Ovu poruku je menjao b0ris dana 28.12.2008. u 13:03 GMT+1]

[Ovu poruku je menjao b0ris dana 28.12.2008. u 13:03 GMT+1]

[Ovu poruku je menjao b0ris dana 28.12.2008. u 13:04 GMT+1]

[Ovu poruku je menjao b0ris dana 28.12.2008. u 13:05 GMT+1]
[ b0ris @ 27.12.2008. 11:26 ] @
Cool objasnjenje pristupa kreiranju sajta. Mislim da bi bilo bolje da objasnimo sve od pocetka i napisemo ovde, buduci da to nama nije neki problem.
Sve sto vidim na forumu je postovanje linkova knjiga i govorkanje kako je google najbolji prijatelj.
Ajde da napisemo sve od pocetka sa detaljnim objasnjenima i na taj nacin pomognemo svima a i prosirimo nase znanje.
Ako preterujem sa ovim molim vas da mi na to skrenete paznju.
[ b0ris @ 28.12.2008. 12:02 ] @
DB klasa

Code:

<?php
/**
* Class for DB management. In here we will create connection to our DB and execute queries. 
* This is just basic class which will be changed later. All errors will be handled later.
* @version 0.1 beta
* @author www.elitesecurity.org (written by member b0ris)
*/

class DB{
    /**
    * Connection parameter which holdes information about host account
    * @access private
    * @name host
    */
    private $db_host = "";
    
    /**
    * Connection parameter which holdes information about password
    * @access private
    * @name password
    */
    private $db_password = "";
    
    /**
    * Connection parameter which holdes information about data base to which we are going to connect.
    * @access private
    * @name database
    */
    private $db_database = "";
    
    /**
    * Connection parameter which holdes user information.
    * @access private
    * @name user
    */
    private $db_user = "";
    
    /**
    * MYSQL Link indentifier
    * @access private
    * @name linkId
    */
    private $db_linkId = 0;    
                   
    /**
    * In here we will set up inital settings for database and connect to our DB
    * @param string host host to define
    * @param string user username used to connect to database
    * @param password password used for connection
    * @param databse database name used for connection
    * @return bool|MYSQL_Link returns bool if something went wrong or MYSQL Link if everything went ok 
    */
    function DB($host, $user, $password, $database){
      /**
      * Setting up parameters
      */
      $this->db_host = $host;
      $this->db_user = $user;
      $this->db_password = $password;
      $this->db_database = $database;
      
      /**
      * Establishing connection
      */
      return $this->connect();   
    }
    
    /**
    * Creating mysql connection.
    * @return bool connection established or not
    */
    function connect(){
      /**
      * Checking if everything is filled up so we can establish connection.
      * We can also use empty() function in this if statment.
      */
      if(($this->db_host != "") && ($this->db_user != "") &&  ($this->db_password != "") && ($this->db_database != "")){
        $this->db_linkId = mysql_connect($this->db_host, $this->db_user, $this->db_password);
        if(!$this->db_linkId){
          /**
          * Handle error.
          */
          return false;
        }else{
          if(!@mysql_selectdb($this->db_database, $this->db_link)){
            /**
            * Handle error.
            */
            return false;  
          }
        }
        return true;
      }else return false;
    }
    
    /**
    * Executing query.
    * @param string query Query for mysql
    * @return mysql_result|die_msg Return result of query or error message 
    */
    function query($query){
        return mysql_query($query, $this->db_linkId) or die(mysql_error());        
    }
    
    /**
    * Executing query.
    * @param string query Query for mysql
    * @return array Returns result of query in array
    */
    function getrows($query){
      /**
      * Query result array
      */
      $myRes = array();
      /**
      * Running thorough results and storing them in our result array
      */
      while($row = mysql_fetch_array($this->query($query))){
        $myRes[] = $row;
      }  
      return $myRes;
    }
}  
?>
[ MilanRS @ 05.01.2009. 17:54 ] @
Hajde izmijeni svoj post.
Ono "ce mo" spoji, izgleda mnogo ruzno.

Ja ću
Ti ćeš
On će.
Mi ćemo.
Vi ćete.
Oni će.

Kada bi bilo ispravno "će mo", onda bi bilo i "će š", a ne postoje riječi "mo" i "š".

S poštovanjem.
[ centaur @ 05.01.2009. 20:21 ] @
@b0ris
Svaka čast ako nađeš vremena i isteraš ovo što si počeo do kraja.
Sigurno da bi bilo veoma korisno svima koji počinju da rade PHP i OOP.

Mala sugestija:
Ako se već ovo radi u advanced PHP forumu, bilo bi korisno upotrebiti i neke, da kažem advanced, mogućnosti OOP.
Ova klasa za DB može da implementira singleton design pattern (dobra praksa mada ne i neophodno) i da ima statičke metode (omogućava se pozivanje metoda iz bilo kog opsega bez ikakve "gimnastike").
Takođe, bilo bi lepo da ima i metodu za eskejpovanje promenjivih koje se upisuju u bazu kako bi sve bilo na jednom mestu.

U svakom slučaju, respect i za ideju i za volju za da se ideja sprovede u delo :)





[ b0ris @ 06.01.2009. 11:26 ] @
@MilanRS Znam za "ce mo" ali ne mogu da editujem poruke koje su tu duze od 48h :|. U svakom slucaju hvala na zamerci.
@centaur Planiram da ubacim i singletone objekte. Mislio sam prvo da napravim najosnovniji model a da posle to nadogradimo, kako bi ljudi mogli da vide razliku. Odradi cu do kraja posto mi je muka da vidim kako neko nesto zapocinje a ne zavrsava. Mozda malo potraje, posto imam i drugih obaveza, ali cu isterati do kraja.

Sve sto vidite da sam pogresio i lose napisao molim vas da mi skrenete paznju. Jos jednom hvala MilanRS na zamerci, zao mi je sto ne mogu to da ispravim.
[ b0ris @ 06.01.2009. 11:58 ] @
Session klasa
Code:

<?php
/**
* Class for session management. It will be used to put in and take out values from session.
* This is just basic class which will be changed later. All errors will be handled later.
* @version 0.1 beta
* @author www.elitesecurity.org (written by member b0ris)
*/

class Session{
    
    /**
    * @desc To be defined later.
    */
    function Session(){
    }
    
    /**
    * @desc Places value under desired name into session. This will be an array.
    * @param string name Name under which value will be remembered.
    * @param string|int value Value which will be saved under name.
    */
    function addValue($name, $value){
        $_SESSION[$name][] = $value;
    }
    
    /**
    * @desc Returns value or array, depending on how many values are stacked under same name.
    * If name does not exist program will be terminated.
    * @param strin name Name under which value or values are stacked.
    * @return string|int|array
    */
    function getValue($name){
        /**
        * Does given name exists?
        */
        if(isset($_SESSION[$name])){
            /**
            * If there is only one value in array we will return it. If more we will return whole array.
            */
            if(count($_SESSION[$name]) == 1) return $_SESSION[$name][0];
            else return $_SESSION[$name];
        }
        /**
        * No! We should handle an error here.
        */
        else return false;
    }
    
    /**
    * @desc This method will remove all the values under given name.
    */
    function removeValue($name){
        unset($_SESSION[$name]);
    }
    
    /**
    * @desc This method will start up session. It should only be called after all the classes are loaded, and before any output begins.
    */
    function startSession(){
        session_start();
    }
}
?>


Izmena umesto linije "else exit(1);" postavljena je "else return false;"

[Ovu poruku je menjao b0ris dana 07.01.2009. u 17:22 GMT+1]
[ dakipro @ 06.01.2009. 12:56 ] @
jedno kratko, zasto se cuva niz za vrednosti po defaultu?
Nekako bi mi bilo logicnije da ako zelis niz u nekoj vrednosti, njoj i dodelis niz, ponajvise zbog kljuceva niza i kasnijem pristupu. Recimo

$_SESSION['user_details']['username']. Ovo niti se moze dodeliti u sesiju niti iz nje uzeti ovako, ili mozda gresim?

Iskreno, nikad nisam koristio klasu za rad sa sesijama pa mozda ne vidim celu sliku odmah, nekako mi dodje nepotrebno. Koristim samo getSESSION($value, $default) koji proverava isset() i vrati default ako je prazno polje koje trazim, inace nista naprednije. Jedino sto vidim kao korisno ako kasnije premestis sesije u bazu ili u fajl pa rucno managujes to, ali me opet buni predjasnji pristup dodeli promenjivih
[ dakipro @ 06.01.2009. 13:04 ] @
Takodje, razmisli da u getValue ne ide bas na kraju ako vrednost ne postoji

else exit(1);

, mozda bolje da vrati false ili drugi parametar kao defaultnu vrednost, ali ne bas da cela aplikacija stane jer korisnik nema nesto setovano u sesiji. Ili mozda opet nesto ne pratim kao i malopre?
[ b0ris @ 07.01.2009. 08:47 ] @
Pisem klase iz glave.
Upotreba session klase je nista drugo do dobra praksa, pritom se moze pokazati kao korisna kasnije. Moze se prosiriti da radi i sa cookie. Onda imas i dalje jednu metodu za dodavanje promenljive i ne mora da razmisljas o tome.
Sto se tice dodavanja promenljive tu si upravu. Mogao bi malo vise da razmislim o tome i napravim nesto malo fleksibilnije.
exit(1) sam stavio jer trenutno nema nikakve obrade greski, to sam mislio da dodam naknadno.
Mada sad kad razmislim, bolji je tvoj predlog da se vrati false nego da ubijam izvrsavanje tu. Moze da dodje do toga da korisniku istekne sesija :|

Hvala na komentarima. Promisli cu o novom dodavanju vrednosti pa cu to da izmenim.


[ b0ris @ 18.01.2009. 13:09 ] @
URL handler

Code:

<?php
/**
* Class for url management. This class will take all the parameters and give them back in one unified way.
* Functions which will process all $_SERVER data should be created here.
* This is just basic class which will be changed later. All errors will be handled later.
* @version 0.1 beta
* @author www.elitesecurity.org (written by member b0ris)
*/

class urlHandler{

    /**
    * @desc Contains all POST values in an array.
    * @access private
    * @name post_vars 
    */
    private $post_vars;
    
    /**
    * @desc Contains all GET values in an array.
    * @access private
    * @name get_vars 
    */
    private $get_vars;
    
    /**
    * @desc In here we will catch all the post and get variables and process them. 
    * We will add this checkups when we create security class.
    */
    function __construct(){
    }
    
    /**
    * @desc Will be processed upon creation of security class.
    */
    private function processGet(){
    }
    
    /**
    * @desc Will be processed upon creation of security class.
    */
    private function processPost(){
    }

    /**
    * @desc Returns value this regarding the method. 
    * If values have the same name, then second parameter can be used to define a method.
    * @param string name Takes name of the value
    * @param post|get method Type of parameter which you want to take. Can be Post or Get.
    * @return string
    */
    function getValue($name, $method=""){
        if(!$method){
          if(isset($_POST[$name])) return $_POST[$name];
          if(isset($_GET[$name])) return $_GET[$name];
        }
        else{
          $var = '_'.$method;
          if(isset($$var[$name])) return $$var[$name];
        }
    }
    
    /**
    * @desc Process domain name and returns domain name.
    * @return string Domain name
    */
    function getDomainName(){
        return $_SERVER['HTTP_HOST'];
    }
    
    /**
    * @desc Used to create url links. To be build up more later. 
    * For now it is good to use it because all links will be created through this function, so when we do some changes to url
    * we will only do it in this function.
    * @param string page_name Name of the page.
    * @return string Url 
    */
    function createUrl($page_name){
        return $page_name;
    }
}
?>

[ amitkic @ 27.03.2009. 21:04 ] @
e a bas smo dobro poceli i vi stadoste, ajde nastavak, posto je tema veoma interesatna i za ostale korisnike.
Znaci imamo neke klase, ajmo jos neke.

Hvala za dosadasnje objasnjenje i klase.
[ iizuzetan @ 29.03.2009. 22:00 ] @
Ja kad sam naucio koliko toliko PHP i Html pre nekih 3 meseca, i kad sam hteo da krenem sa izradom sajta isto sam se susreo sa tim problemom kako primeniti znanje. U globalu ja sam znao kako napraviti PHP "web mehaniku i dinamiku" sajta ali nisam odmah skontao kako da povezem to sa "web statikom". Najprostije receno kako PRIKAZATI PHP rezultate u HTML-u.

Citao sam nesto malo o tome i znam da postoje nekoliko pristupa, ali nigde nije dato detaljno objašnjenje bilo kog pristupa (ili bar ja nisam uspeo da naletim na tako nešto), i zato sam krenuo sam da se snalazim.

Kao prvo, nisam krenuo odmah u izradu ovog sajta koga sad imam (zbog koga sam i krenuo da ucima PHP) vec sam krenuo da izradjujem najprostiji nazovimo to sajtom, kako bi skontao i uvezbao mehanizam prikaza. Hocu da kazem da pocetnik u "gradjevinarstvu" ne treba odma da počne da gradi "nebodere", vec neka sagradi najpre "ŠUPU".

Naravno ja sad nemam namere da pišem taj mini sajt ali cu da ga opišem kakav je bio.

Pošto sam pre svega toga izradio sve delove vezane za registraciju, logovanje i ostalo, ubacio sam registraciju. Želeo sam da napravim najprostije da se moze registrovati i ulogovati, i da taj registrovani "napiše - objavi" nešto online na sajtu. E sad kad napise kroz html formu to nesto, da mu se kreira dinamicki dugme na sajtu, i kad se klikne na to dugme da se na sredini strane ispise taj njegov tekst. Znaci to je ceo sajt. Medjutim kad sam sve to napravio i kad sam poceo da ubacujem razne tekstove ali kroz sajt, kao sto mi svi ubacujemo ove teme ovde na forumu, shvatio sam principe dinamičkih sajtova.

E sad da pokušam da objasnim taj princip.

Zapravo PHP je glavan na sajtu i pokretac svega. To znači da moj sajt nema ni jedan fajl koji se zavrsava ekstenzijom .htm !!! Šta to znači? To znači da su svi HTML kodovi zapravo smešteni kao stringovi u PHP promenjljivima !!!!!!! Drugo, moje cele html tabele, ili ti delovi stranica su smestene u funkcijama. Na primer jedna funkcija takva se zove clanovidugme(). Nadam se da i pomoću imena funkcije otprilike shvatate sta hocu da objasnim. I kad pozivam tu funkciju zapravo to ne znaci direktno prikazivanje strane na sajtu vec ja funkciji prosledjujem promenjljive koje sadrže rezultate utkane kao html kod ali kroz string. I ta indeks funckcija te promenjljive zapravo postavi na ona mesta u html tabeli gde hocu da vidim te rezultate. Tu promenjljivu koju je vratila funkcija ja dodajem na primer kao parametra za prikaz u novoj funkciji koja prikazuje na primer index stranu ovako:

Code:

echo indekstrana($dugmeclanovi, $tabelasve, $korisnikid);exit;


A jedna promenjljiva u koja sadrži HTML kodove kao string izgleda ovako:

Code:

$navigacija='  <table cellpadding="0" cellspacing="0" width="657" height="41">
                       <tr>
             <td valign="middle">&nbsp;</td>
             <td bgcolor="#00FFFF"><p align="center"><b><font face="Arial">Strane:</font></b></td>
             <td bgcolor="#00FFFF">&nbsp;</td>
             <td bgcolor="#00FFFF" height="28"><p align="left">'.$s.'</td>
        </tr>

                <tr>
             <td width="422"></td>
             <td width="81"></td>
             <td width="13"></td>
             <td width="141" height="13"></td>
        </tr>
                    </table>
                    </p><table cellpadding="0" cellspacing="0" width="669" height="120"></table></p>
                 ';  


Promenjljiva $s sadrži neke podatke koje ubacujem u HTML kod a sve to zajedno "nosi" promenjljiva $navigacia, koju posle na primer mogu proslediti nekoj funkciji koja ce i tu promenjljivu utkati u neki html koga sadrži neka promenjljiva za prikaz, na primer za prikaz cele jedne stranice sajta.

Naravno neko ce reci da je ovakvo programiranje uz pomoc funkcija staromodno, neekonomicno i sta ti ja znam kakvo sve ali licno mislim da je pocetnicima najbolje da prvo shvate kroz funkcija kako sve funkcionise. Da naprave neke mini sajtove da bi videli kako komponovati sajtove. Kasnije u njima da dodaju malo dizajna, pa da krenu da dodaju jos delove sajta i malo sve da usložnjavaju itd itd. Pa tek kad steknu rutinu sa web objektima tek onda da ih grupisu u klase i da objektno programiraju. Jer po meni glavna stvar u objektnom programiranju je da se najpre dobro shvati i razbistri u glavi sta su to objekti, kako prepoznati slicne objekte i grupisati ih itd itd.

[Ovu poruku je menjao iizuzetan dana 30.03.2009. u 00:54 GMT+1]
[ Zmaj @ 30.03.2009. 09:30 ] @
Citat:
iizuzetan: Ja kad sam naucio koliko toliko PHP i Html pre nekih 3 meseca

vec na nekoliko temo vidim da si sklon da delis savete, nakon toliko meseci iskustva. Ovde na forumu ima ljudi koji se godinama bave PHPom pa ne dele tako olako savete. Ovo ti kazem cisto dobronamerno jer nemas dosat iskustva i prakse da bi mogao bilo koga da savetujes.

Citat:
Zapravo PHP je glavan na sajtu i pokretac svega. To znači da moj sajt nema ni jedan fajl koji se zavrsava ekstenzijom .htm !!! Šta to znači? To znači da su svi HTML kodovi zapravo smešteni kao stringovi u PHP promenjljivima !!!!!!!

Da si malo citao po internetu onda bi nasao da je ovo usporava izvrsenje stranice. Zato je dobra praksa MVC (potrazi po forumu ovaj pojam), gde ces u view delu staviti sav kod koji se tice ispisa i to van promenljivih. Drugo ovo je ekstremno losa praksa da imas bilo kakav html kod u tvojim funkcijama jer kad budes resio da menjas izgleda tvog sajta moraces da menjas funkcije.

Citat:
Na primer jedna funkcija takva se zove clanovidugme(). Nadam se da i pomoću imena funkcije otprilike shvatate sta hocu da objasnim.

Ovo ti je isto losa praksa, da promenljive i funkcije krstis na nasem jeziku, razlog sto ima mnogo padeza, Zato je najbolje koristi engleski i neko drugi ce moci da menja tvoj kasnije, makar taj neko ziveo u kini.

Citat:
Naravno neko ce reci da je ovakvo programiranje uz pomoc funkcija staromodno, neekonomicno i sta ti ja znam kakvo sve ali licno mislim da je pocetnicima najbolje da prvo shvate kroz funkcija kako sve funkcionise. Da naprave neke mini sajtove da bi videli kako komponovati sajtove. Kasnije u njima da dodaju malo dizajna, pa da krenu da dodaju jos delove sajta i malo sve da usložnjavaju itd itd.

Kao sto sam rekao, nemoj davati savete pocetnicima o tome kako da urade neku stvar, pomozi im tako sto ces odgovoriti na pitanje kao da rese problem, neki sa kojim si se susreo, a ne da pocinjes temu da bi nekog nesto naucio ili kao sto je ovde slucaj da prekidas temu u kojoj ljudi daju korisne savete. Bolje se ne javljai citaj sta se ovde pise.

Citat:
Pa tek kad steknu rutinu sa web objektima tek onda da ih grupisu u klase i da objektno programiraju. Jer po meni glavna stvar u objektnom programiranju je da se najpre dobro shvati i razbistri u glavi sta su to objekti, kako prepoznati slicne objekte i grupisati ih itd itd.

Da bi namestio dobar sajt nemoras da znas objektno programiranje, a ni da i h programiras objektno. Iza sebe imam nekoliko desetina sajtova koja sam odradio bez objekata, i dalje mogu da ih radim tako. PRoblem je sto kod takvih sajtova, kod se se razvija vremenom i vec sam poceo da gubim nit sta je na kom sajtu uradjeno bolje, pa kad krecem nov projekat da se to kopira u nov na jednom mestu. Iz tog razloga sam presao na CodeIgnitier, php framework koji je lagan i brz za ucenje, storen za male projekte. Koga zali da se bije sa teskom artiljerijom tu je ZendFramework, koji ima mnogo tutorijala po netu ali relativno glomazan, sto vraca svojim mogucnostima.
[ Nikola Poša @ 30.03.2009. 09:50 ] @
Citat:
iizuzetan:E sad da pokušam da objasnim taj princip.

Taj princip, odnosno, stil pisanja web aplikacije još i može da prođe na nekim manjim ili one-man projektima. A zamisli samo kad bi trebao da radiš u nekom timu ljudi, ili ne mora to, nego samo pomisli šta bi sve morao da uradiš kad bi hteo da promeniš izgled sajta, recimo da promeniš templejt... Ja ne smem ni da pomislim.

Danas se već uveliko koristi tkz. troslojna arhitektura pri izradi sajtova. Evo Predrag ti je spomenuo MVC (Model View Controler), na kome je zasnovana većina Framework-ova za PHP. To ne znači da ti sad moraš da koristiš neki Framework, ali bi bar trebao da imaš u vidu to razdvajanje slojeva pri kreiranju nekog sajta. U tom cilju, možda bi bilo dobro da za početak probaš Smarty, najpoznatiji (po mom mišljenju i najbolji ) template engine za PHP. Probaj recimo da taj sajt koji si spomenuo u poruci odradiš sa Smarty-jem, i koristeći taj prinicip razdavajanja logičkog i prezentacionog sloja. Videćeš koliko će kod da ti bude mnogo "čistiji", jasniji i lakši za održavanje. A kad jednom probaš Smarty, verovatno više nikad nećeš moći bez njega. Tako je barem bilo u mom slučaju.

A i naravno, OOP - bez toga ništa...
[ iizuzetan @ 30.03.2009. 11:14 ] @
Citat:
Nikola Poša: Taj princip, odnosno, stil pisanja web aplikacije još i može da prođe na nekim manjim ili one-man projektima. A zamisli samo kad bi trebao da radiš u nekom timu ljudi, ili ne mora to, nego samo pomisli šta bi sve morao da uradiš kad bi hteo da promeniš izgled sajta, recimo da promeniš templejt... Ja ne smem ni da pomislim. :)

Danas se već uveliko koristi tkz. troslojna arhitektura pri izradi sajtova. Evo Predrag ti je spomenuo MVC (Model View Controler), na kome je zasnovana većina Framework-ova za PHP. To ne znači da ti sad moraš da koristiš neki Framework, ali bi bar trebao da imaš u vidu to razdvajanje slojeva pri kreiranju nekog sajta. U tom cilju, možda bi bilo dobro da za početak probaš Smarty, najpoznatiji (po mom mišljenju i najbolji :)) template engine za PHP. Probaj recimo da taj sajt koji si spomenuo u poruci odradiš sa Smarty-jem, i koristeći taj prinicip razdavajanja logičkog i prezentacionog sloja. Videćeš koliko će kod da ti bude mnogo "čistiji", jasniji i lakši za održavanje. A kad jednom probaš Smarty, verovatno više nikad nećeš moći bez njega. Tako je barem bilo u mom slučaju. :)

A i naravno, OOP - bez toga ništa...


Koliko znam objektno programiranje uglavnom nije korisceno do PHP 4 a mnogi sajtovi koji su nastajali do tada itekako su bili kompleksni i slozeni. E sad nemojte pogresno da me shvatite, ja ne kazem da je funkcijsko programiranje bolje. Naravno cim je izmisljeno objektno posle funkcijskog naravno da je bolje objektno. Ali kao vezbu mislim da je pocetnicima bolje da prvo naprave neki prostiji sajt pomocu funkcijskog programiranja. A jos bolje zbog dizajna i uvezbavanja mozda je najbolje da prvo naprave neki statican sajt samo u cistom HTML i CSS.

Mali sajtovi za vesti tipa blic.rs gde nema ni registracije ili obicni portali u kojima administrator unosi samo neke tekstove i slike na pojedinim polozajima na sajtu, je sasvim dovoljno i ekonomicno i funkcijsko programiranje ja bar mislim. Naravno pocetnici kad savladaju funkcijsko programiranje onda sve te male sajtove da prebace u objektno programirani sajt.

Znaci bolje je naravno koristiti objektno programiranje, ali ne verujem da pocetnik moze odma da krene sa takvim programiranjem jer nema iskustva. Kako da on pravi klase ako ne rasclani lepo objekte ?? Mozda nisam u pravu ali mislim da bi "objektni" program pravilno napravili treba dobro rasčlaniti i grupisati objekte. Kasnije je lako praviti klase i razmestati te objekte na sajtu. E sad smatram (naravno mozda nisam u pravu) da bi pocetnici naucili kako da uocavaju objekte i da ih grupisu najbolje je da prvo krenu sa funkcijskim programiranjem. Jer prakticno svaka funkcija moze da se nazove objektom. Pa ako na primer nekoliko funkcija ima iste metode i izvrsavaju slicne radnje, da ih grupisu u klase itd.

Naravno da funkcijsko programiranje i rasparcavanje html kodova u promenjljivima nije idealno, a ko zna mozda i najgori nacin, ali pocetnicima je bolje predloziti bilokakve principe da bi krenuli u konkretne stvari, a ne da im ne damo nikakve savete.

Predloziste neke programe ili sta??? Ja sam sve radio u noteped. Naravno slazem se da kad god mozes da koristis neki alat koji olaksava zivot bilo kako onda ga treba koristiti. Ali za pocetnike je mislim opet bolji noteped kako bi stekli rutinu. A kasnije da krenu sa pomagalima.

Volim da dajem savete jer sam i ja bio u takvoj situaciji kad pomoci niotkuda a moram resiti problem. U tim trenucima mi je bilo vazno da dobijem bilo kakvo resenje mog problema pa i ono najgore ali da ipak odradi poso nego ne dobiti nikakvo resenje.

A konstatacija da funkcijskim programiranjem ne mozes na jednom mestu menjati neke delove sajta vec to moras da menjas na veci broj mesta apsolutno nije tacno !!!! Sta god da pozlim da promenim sad na sajtu menjam to samo na jednom mestu u jednoj promenjljivoj koja "nosi" prikaz toga necega. Bilo to da je pozadina, dugme, neki tekst ili bilo sta.

Objektno programiranje nije nastalo iz potrebe da bi se na "jednom mestu" menjale stvari na sajtu, jer i funkcijsko programiranje to omogucava, vec je objektno programiranje nastalo iz potrebe da se program vremenom brzo, jednostavno nadogradjuje. Ali ne da se nadogradjuje tipa promena dugmeta, pozadine ili bilo kog manjeg dela, nego da se nadogradjuje program. Mozda gresim ali to je moje msljenje. Nadam se da je ovo slobodan forum na kome se mogu izneti sva razmisljenja.

[Ovu poruku je menjao iizuzetan dana 30.03.2009. u 12:57 GMT+1]
[ dakipro @ 30.03.2009. 11:45 ] @
Totalno je ok to sto zelis da dajes savete, samo po stazu i po iskustvu koje imas i ti si i sam pocetnik te previse cesto dajes pogresne savete umesto da radis kao i svi pocetnici, citas i skupljas fore.
Diskutabilno je da li bi neko mogao odma da krene sa oo programiranjem ili ne, nakon nekog osnovnog koda uz dobre tutore i tutorijale. Ja sam recimo odmah krenuo sa malo mesovitim stilom, odmah sa objektima i smartijem i MVC, pa sam tek posle bio prinudjen da radim u "klasicnom" kodu, tako da tvoja tvrdnja ne stoji bas.

I definitivno nije bolje pocetnicima davati bilokakav savet, a pooogotovo ne pogresan, jer ovo sto se pise na forumu stoji tu i za buduce posetioce, pa i one pasivne koji ljudi dodju i citaju i pretrazuju i citaju jos a kojih nema malo. ES forumi se odlikuju po svom kvalitetu diskusija, a ovo sto ti vec neko vreme i nekoliko puta pises je primer kako NE treba raditi.

Nacin koji ti predlazes je jedino bolji od nacina da se u .html fajlovima ubacuje php kod (cak i ovo je bolje u nekim situacijama staticnih sajtova).

Uopste ne kontam sta si tvojim prvim postom ovde hteo da kazes, jer se tema odnosi na pomoc naprednom pocetniku, i lepo se razvila u pisanje klasa i rad sa njima, i ti odjednom tu ulices sa nekim tvojim 'iskustvima' iz nijednog napisanog sajta kako treba raditi, da se razmisljam da prilikom sredjivanja tema lepo obrisem poslednjih par postova.

Tema sa predlozima editora postoji, cak je to i TOP tema, citaj malo po forumu, nemoj da si lenj. Vec sam ti jednom napisao za ovu temu.

A deo oko menjanja templejta ti je Nikola lepo objasnio, znaci to moze teoretski, ali samo u one-man-show projektima, cim sedne neki koder za tvoj kod iz ozbiljnije firme, znace koliko je sati.

Totalno ti je pogresan stav da posle 3 meseca pisanja php koda i html-a vise nisi pocetnik, a ovako neke napredno-osnovne stvari neznas. To zakljucujem na osnovu tvog texta
"Ali za pocetnike je mislim opet bolji noteped kako bi stekli rutinu. A kasnije da krenu sa pomagalima."

Opet, sve ovo su gore dobronamerni saveti (sto kazu, konstruktivna kritika), kako bi izbegao da ti teme budu obrisane pa da mislis da ljudi na forumu imaju nesto licno protiv tebe, daleko od toga, sumnjam da te neko poznaje licno ovde. A i da ti se ne bi desavali biseri kao kad si poslednji put poceo da teoretises o nicim izazvanim 'zagonentim' nizovima i problemima, pa kad si ukapirao da gresis povukao si se cutanjem umesto da lepo priznas (sebi, ne drugima) da gresis i da ne znas jos uvek dovoljno. AKo hoces da se pokazes, cinis to na pogresan nacin, u reputaciji moze da se ode i u 'minus'
Ako nemas sta pametno da kazes, nekad je bolje precutati
Znaci prati nove postove i teme, i kad vidis neki pocetnicki laksi problem, na koji sugurno znas dobar odgovor, tad se pokazi. Prihvati zajednicu da bi te prihvatila lepo.

P.S. vidim da si dodao, pa da dodam i ja: Uvek mozes iznositi svoje misljenje, normalno, ali na odgovarajucu temu.
[ dakipro @ 30.03.2009. 11:50 ] @
Anex posta na deo
"Jer prakticno svaka funkcija moze da se nazove objektom. Pa ako na primer nekoliko funkcija ima iste metode i izvrsavaju slicne radnje, da ih grupisu u klase itd."

Ne moze to tako, nije poenta OOP-a da sve funckije budu u jednoj klasii da su iste ili slicne, vec u mnogo drugih stvari kao sto su recimo nasledjivanje (da ne nabrajam, pisalo se o tome). OOP ne moze tek tako da se skonta iz pisanja funkcija, to je totalno drugaciji pristup problemima i resenjima, mozda je bolje za pocetak sa OOP citati recimo literaturu predvidjenu za oop, nevezano za php, recimo za Javu, ja sam odatle dosta skontao o ideji OOP-a.
Prvo pricitas znaci teoriju o metodama i funckijama, kao i razlikama izmedju njih (ne moze recimo funkcija ili nekoliko funckija da ima metode, pa i iste). Babe i zabe, postoji razlog sto se metoda ne zove funckija ili klasa...
[ iizuzetan @ 30.03.2009. 12:06 ] @
A jeste covek je napisao napredni pocetnik. Procitao sam ali smisao "napredni" mi je na pocetku promako. Ok onda ako zna funkcijsko programiranje ili ga to ne zanima neka preskoci ova tri moja odgovora na temu.

Ok moderatore skontao sam sta je to sto ti bode oci vezano za moje pisanje, tako da u buduce neces imati vise "problema" samnom.
[ Tudfa @ 30.03.2009. 13:15 ] @
Primetio sam ovu temu ranije, i mislim da je odlična i da bi bila korisna, naročito ako bi se priključivalo više ljudi svojim savetima i idejama.
No pre nego što krenem da iskomentarišem nešto što sam primetio,
hteo bi da predložim nešto u vezi same teme, čisto da ne bude da tema ide u off.

Evo npr. možda bi mogli da napravimo i klasu Configuration za rad sa konfiguracinim parametrima tipa max_email_chars, max_username_chars itd...

Ideja bi bila sledeća :

- imamo tabelu u kojoj čuvamo konfiguracione parametre (tabela se sastoji od dva polja - config_name i config_value koji predstavljaju složen primarni ključ)
- imamo singleton klasu Configuration koja nam omogućava manipulaciju tim parametrima

Eto, to je ideja, pa ako se autor teme složi da je tako nešto potrebno(mozda je planirano da se drugačije odradi config), priložiću klasu.

A sad off

Citat:
iizuzetan:
Takodje sam reko da je bolje naravno koristiti objektno programiranje, ali ne verujem da pocetnik moze odma da krene sa takvim programiranjem jer nema iskustva.


Nešto nisam baš siguran u vezi ovoga...

Generalna razlika je stil samog programiranja plus OOP je fleksibilniji po nekim pitanjima, daje više mogućnosti, pa zbog toga treba da se nauči više pravila ,
ali nikako ne bih rekao da je problem naučiti OOP bez učenja proceduralnog programiranja. Ja sam učio prvo proceduralno, ali znam i neke ljude koji
su odmah krenuli od OOP-a.

@izuzetan

I još nešto...Mešanje logike i prezentacije je nešto najgore što možeš sebi da uradiš.
Mislim, tebi će sve raditi, ali je menjanje dizajna i razumljivost koda u tom slučaju je veoma otežano.
Cilj je da programer radi programiranje a dizajner dizajn nebitno da li si ti u ovom trenutku i jedno i drugo.
To razdvajanje mozeš da izvedeš zavisno od veličine sajta i ličnih sklonosti pomoću Smarty-a kao
što je već rečeno ili pomoću samog php-a. E sad ne može se reći koristi Smarty ili nemoj,
samo se može reći treba ti Smarty ili ne s'obzirom na obim projekta koji radiš.

Pošto ovo nije tema neću više da komentarišem a evo jedne dobre teme o ovome,
gde se govori o tome šta je Smarty, da li je potreban i koje su alternative
u razdvajanju logike od prezentacije samo pomoću php-a :

http://www.elitesecurity.org/t...0-Ovaj-Smarty-je-odlicna-stvar
[ Tudfa @ 02.04.2009. 14:00 ] @
Evo one Configuration klase u nekom osnovnom obliku, koji može posle po potrebi da se doradjuje.
U prethodnom postu sam rekao da je potrebna tabela koja sadrzi samo dva polja - config_name i config_value,
gde zapravo samo config_name treba da bude primarni ključ(a ne kako sam prvi put slučajno naveo oba polja).
Naravno ako neko od Vas ima neke sugestije,primedbe ili predloge neka kaže da bi prepravili.

Code:

<?php

class Configuration
{
    private static $instance;
    private $arrConfiguration = array();
    
    private function __construct()
    {
         //izgled ovog reda zavisi od toga kako manipulišete bazom podataka
        $rows = SingletonDatabase::getInstance()->get_rows('SELECT * FROM configuration');
        
        //ovde moze neka provera sta je povuceno iz baze tipa is_array i sizeof tj. count
        
        foreach($rows as $row)
        {
            $this->arrConfiguration[$row['config_name']] = $row['config_value'];
        }
    }
    
    private function __clone(){}
    
    public static function getInstance()
    {
        if (!self::$instance instanceof self)
        {
            self::$instance = new self;
        }
        return self::$instance;
    }
    
    public function getParameter($parameter)
    {
        return (isset($this->arrConfiguration[$parameter]) ? $this->arrConfiguration[$parameter] : false);
    }
    
    public function __destruct(){unset($this->arrConfiguration);}
    
}
?>


Eto to bi bio jedan od načina za manipulaciju konfiguracionim parametrima,
a drugi bi bili preko nekog ini fajla ili xml fajla ili možda čuvanja svih
konfiguracionih parametara u jednom nizu u .php fajlu.

Samo par komentara što se tiče samog koda...

Klasa funkcioniše tako što se pomoću Configuration::getInstance()->getParameter('ime_parametra') dobije vrednost
trazenog parametra ako takav postoji, u suprotnom vraća false. Isto tako singleton patern obezbedjuje da u okviru
jednog skripta imamo samo jednu instancu objekta klase Configuration.

Izostavio sam metodu setParameter('config_name','config_value')koja bi updejtovala vrednost postojeceg parametra,
jer bi izgled te metode zavisi od klase za upravljanje bazom podataka. Takodje mogla bi
da se doda i metoda tipa addParameter('config_name','config_value') koja dodaje novi parametar,
ako za tim ima potrebe.
[ amitkic @ 02.04.2009. 20:43 ] @
ajde sada nastavak


P.S. Izgleda da ovde leba ima samo od borisa
[ amitkic @ 06.04.2009. 17:17 ] @
Poslo mi čovek kako kaže "školski" primer sajta. Ajd neka ga neko (iskusniji) pogleda i da mi kaže šta misli o njemu.
[ b0ris @ 09.05.2009. 21:28 ] @
Nastavljam sad. Malo sam se bio smorio jer niko nije nista postovao.
Sad cu da odradim ostatak, samo caskom da procitam ovih par postova :)
[ b0ris @ 10.05.2009. 12:54 ] @
Cao. Evo odradio sam frontend. Ovih dana cu da odradim backend.
Naravno ovo je sve jos uvek u startnoj fazi.
Posto budem odradio backend, pocecu da prosirujem.
@Tudfa: Config klasa je naravno dobro dosla, samo mislio sam da prvo idemo polako sa onim najosnovnijim, i onda da polako dodajemo malo interesantnije stvari :) (kao sto je config :) )
Dok sam pravio front naleteo sam na par greski u prethodnim klasama tako da cu ih ponovo postovati.
Unapred se izvinjavam na ponovnom postovanju istih klasa.

Tree construction
Code:

- base
-- class.db.php
-- class.session.php
-- class.urlhandler.php
- css
-- content.css
-- global.css
-- menu.css
- pages
-- skelet
--- footer.php
--- header.php
--- menu.php
-- gallery.php
-- home.php
-- contact.php
- uploads
-- pictures
--- test_photo_1.png
- contact.php
- gallery.php
- index.php


./base/class.db.php File
Code:

<?php
/**
* Class for DB management. In here we will create connection to our DB and execute queries. 
* This is just basic class which will be changed later. All errors will be handled later.
* @version 0.2 beta
* @author www.elitesecurity.org (written by member b0ris)
*/

class DB{
    /**
    * Connection parameter which holdes information about host account
    * @access private
    * @name host
    */
    private $db_host = "";
    
    /**
    * Connection parameter which holdes information about password
    * @access private
    * @name password
    */
    private $db_password = "";
    
    /**
    * Connection parameter which holdes information about data base to which we are going to connect.
    * @access private
    * @name database
    */
    private $db_database = "";
    
    /**
    * Connection parameter which holdes user information.
    * @access private
    * @name user
    */
    private $db_user = "";
    
    /**
    * MYSQL Link indentifier
    * @access private
    * @name linkId
    */
    private $db_linkId = 0;    
                   
    /**
    * In here we will set up inital settings for database and connect to our DB
    * @param string host host to define
    * @param string user username used to connect to database
    * @param password password used for connection
    * @param databse database name used for connection
    * @return bool|MYSQL_Link returns bool if something went wrong or MYSQL Link if everything went ok 
    */
    function DB($host, $user, $password, $database){
      /**
      * Setting up parameters
      */
      $this->db_host = $host;
      $this->db_user = $user;
      $this->db_password = $password;
      $this->db_database = $database;
      
      /**
      * Establishing connection
      */
      return $this->connect();   
    }
    
    /**
    * Creating mysql connection.
    * @return bool connection established or not
    * @version 1.01 Removed checkup for password since password can also be empty. :| Yea ppl use this sometimes also.
    */
    function connect(){
      /**
      * Checking if everything is filled up so we can establish connection.
      * We can also use empty() function in this if statment.
      */
      if(($this->db_host != "") && ($this->db_user != "")  && ($this->db_database != "")){
        $this->db_linkId = mysql_connect($this->db_host, $this->db_user, $this->db_password);
        if(!$this->db_linkId){
          /**
          * Handle error.
          */
          return false;
        }else{
          if(!@mysql_select_db($this->db_database, $this->db_linkId)){
            
            /**
            * Handle error.
            */
            return false;  
          }
        }
        return true;
      }else return false;
    }
    
    /**
    * Executing query.
    * @param string query Query for mysql
    * @return mysql_result|die_msg Return result of query or error message 
    * @version 1.01 Removed die. It was returning bool instead of mysql_result
    */
    function query($query){
        return mysql_query($query, $this->db_linkId);        
    }
    
    /**
    * Executing query.
    * @param string query Query for mysql
    * @return array Returns result of query in array
    * @version 1.01 Update in while statement. We were executing query each time we went through while (Infinite loop)
    */
    function getrows($query){
      /**
      * Query result array
      */
      $myRes = array();
      /**
      * Running thorough results and storing them in our result array
      */         
      $res = $this->query($query);
      while($row = mysql_fetch_array($res)){
        $myRes[] = $row;
      }  
      return $myRes;
    }
}  
?>


./base/class.session.php File
Code:
<?php
/**
* Class for session management. It will be used to put in and take out values from session.
* This is just basic class which will be changed later. All errors will be handled later.
* @version 0.1 beta
* @author www.elitesecurity.org (written by member b0ris)
*/

class Session{
    
    /**
    * @desc To be defined later.
    */
    function Session(){
    }
    
    /**
    * @desc Places value under desired name into session. This will be an array.
    * @param string name Name under which value will be remembered.
    * @param string|int value Value which will be saved under name.
    */
    function addValue($name, $value){
        $_SESSION[$name][] = $value;
    }
    
    /**
    * @desc Returns value or array, depending on how many values are stacked under same name.
    * If name does not exist program will be terminated.
    * @param strin name Name under which value or values are stacked.
    * @return string|int|array
    */
    function getValue($name){
        /**
        * Does given name exists?
        */
        if(isset($_SESSION[$name])){
            /**
            * If there is only one value in array we will return it. If more we will return whole array.
            */
            if(count($_SESSION[$name]) == 1) return $_SESSION[$name][0];
            else return $_SESSION[$name];
        }
        /**
        * No! We should handle an error here.
        */
        else return false;
    }
    
    /**
    * @desc This method will remove all the values under given name.
    */
    function removeValue($name){
        unset($_SESSION[$name]);
    }
    
    /**
    * @desc This method will start up session. It should only be called after all the classes are loaded, and before any output begins.
    */
    function startSession(){
        session_start();
    }
}
?>


./base/class.urlhandler.php File
Code:
<?php
/**
* Class for url management. This class will take all the parameters and give them back in one unified way.
* Functions which will process all $_SERVER data should be created here.
* This is just basic class which will be changed later. All errors will be handled later.
* @version 0.1 beta
* @author www.elitesecurity.org (written by member b0ris)
*/

class urlHandler{

    /**
    * @desc Contains all POST values in an array.
    * @access private
    * @name post_vars 
    */
    private $post_vars;
    
    /**
    * @desc Contains all GET values in an array.
    * @access private
    * @name get_vars 
    */
    private $get_vars;
    
    /**
    * @desc In here we will catch all the post and get variables and process them. 
    * We will add this checkups when we create security class.
    */
    function __construct(){
    }
    
    /**
    * @desc Will be processed upon creation of security class.
    */
    private function processGet(){
    }
    
    /**
    * @desc Will be processed upon creation of security class.
    */
    private function processPost(){
    }

    /**
    * @desc Returns value this regarding the method. 
    * If values have the same name, then second parameter can be used to define a method.
    * @param string name Takes name of the value
    * @param post|get method Type of parameter which you want to take. Can be Post or Get.
    * @return string
    */
    function getValue($name, $method=""){
        if(!$method){
          if(isset($_POST[$name])) return $_POST[$name];
          if(isset($_GET[$name])) return $_GET[$name];
        }
        else{
          $var = '_'.$method;
          if(isset($$var[$name])) return $$var[$name];
        }
    }
    
    /**
    * @desc Process domain name and returns domain name.
    * @return string Domain name
    */
    function getDomainName(){
        return $_SERVER['HTTP_HOST'];
    }
    
    /**
    * @desc Used to create url links. To be build up more later. 
    * For now it is good to use it because all links will be created through this function, so when we do some changes to url
    * we will only do it in this function.
    * @param string page_name Name of the page.
    * @return string Url 
    */
    function createUrl($page_name){
        return $page_name;
    }
}
?>


./css/content.css File
Code:
#content{
  clear:both;
  text-align:left;
}


./css/global.css File
Code:
BODY, TD {
  font-family: Verdana;
  font-size:11px;
  text-align:center;
  background-color: #F2F2F2;
}

A {
  text-decoration:none;
  color:#FFB900;
}

A:Hover {
  color:silver;
}


./css/menu.css File
Code:
#menu{
  clear:both;
  margin: 0 auto;
  text-align: left;
  width:300px;
}
#menu_option{
  float:left;
  width:100px;
}
#menu A{
  font-weight: bold;
}


./pages/skelet/footer.php File
Code:
<?php echo "\n"; ?>
<!-- We can place some code here which is needed on every page (for example google analytics code -->
</body>
</html>


./pages/skelet/header.php File
Code:
<?php
  /**
  * @desc Here we will include everything we need for any page. Attention to SEO (search engine optimization)
  * will be established latter when we move page display into data base. NOTE: Short tags are not used on purpose.
  */
  // Including all the classes we need to display a page. Instead of including this classes one by one each time
  // we could also use _autoload method which php provides
  include "./base/class.urlhandler.php";
  include "./base/class.db.php";
  include "./base/class.session.php";
  
  // Creating instance of urlHandler which we will use later.
  $url = new urlHandler();
  // Creating instance of db (connection to data base)
  if(!$db = new DB("localhost", "root", "", "elitesecurity")){ echo "Could not connect to database!";exit(1);}
  // Creating instance of session and starting up the session (note: session must start before any display happens.
  // Be sure that you dont have enter (\n) as startup char. This can create errors.) 
  $session = new Session();
  $session->startSession();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="content-language" content="sr">
<meta name="author" content="elitesecurity">
<!-- <meta http-equiv="Reply-to" content="@.com"> -->
<meta name="generator" content="Elitesecurity CMS <boris vujicic>">
<meta name="description" content="Home page, test page for basic CMS">
<meta name="keywords" content="">
<meta name="creation-date" content="09/20/2007">
<meta name="revisit-after" content="15 days">
<title>Home</title>
<link rel="stylesheet" type="text/css" href="./css/global.css">
<link rel="stylesheet" type="text/css" href="./css/menu.css">
<link rel="stylesheet" type="text/css" href="./css/content.css">
</head>
<body>


./pages/skelet/menu.php File
Code:
<?php
/**
* @desc Creating menu. Latter we will create dynamic page creation.
*/
?>
<div id="menu">
  <div id="menu_option"><a href="index.php">Home</a></div>
  <div id="menu_option"><a href="gallery.php">Gallery</a></div>
  <div id="menu_option"><a href="contact.php">Contact</a></div>
</div>
<br/><br/>


./pages/contact.php File
Code:
<?php
  /**
  * @desc Simple page which is using urlhandler class.
  */
  
  // Getting email and msg values which are posted and storing those values in corresponding variables.
  $email = $url->getValue("email");
  $msg = $url->getValue("msg");
  
  // Checking if values aer empty
  if($msg != "" && $email != ""){
    // Do something. For example send email
    /*
    if(mail("[email protected]", "Contact", "Email:$email<br/>\n".$msg)){
      echo "Message sent.";                                           
    }else{
      // Handle error.
    }
    */
    echo "Message sent.";
  }
?>
<div id="content">
  <form action="contact.php" method="post">
    Email: <input type="text" name="email" id="email" /><br/><br/>
    Message: <br/>
    <textarea cols="50" rows="5" name="msg"></textarea><br/><br/>
    <input type="submit" value="Ask us?" />
  </form>
</div>


./pages/gallery.php File
Code:
<?php
  /**
  * @desc Simple page which is using db class.
  */
?>
<div id="content"> 
<?php
  //  Setting up parameter which will tell us if we have any pictures in database.
  $haspictures = false;
  // Executing query
  $pictures = $db->getrows("SELECT * FROM pictures");
  // did we got something back?
  if($pictures) $haspictures = true;
  // We did. Ooo looky looky we have some photos :) Lets display them.
  if($haspictures){
    foreach($pictures as $key => $value){
      echo "<div id=\"img\"> <img src=\"./uploads/pictures/{$pictures[$key]['picture_name']}\" alt=\"{$pictures[$key]['picture_name']}\"/></div>";
    }
  }else{?>
<p> Currently there are no pictures. </p>
<?php }?>
</div>



./pages/home.php File
Code:
<?php
/**
* @desc Just some content without any php.
*/
?>
<div id="content">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dictum pellentesque sem. Praesent purus dui, cursus eu gravida sit amet, elementum eu justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sed ante at tellus pulvinar elementum sit amet vel ante. Nulla in arcu sit amet lacus placerat pulvinar consectetur non justo. Donec risus erat, sagittis at aliquet eget, faucibus sit amet ante. Morbi ultrices purus et nunc sagittis ultrices. Vivamus auctor facilisis volutpat. Fusce vel diam massa. Vestibulum fringilla pretium rutrum. Ut eros velit, dignissim sit amet sollicitudin nec, eleifend malesuada tellus. Ut in laoreet velit. Nulla lobortis tincidunt velit, ac congue dui ullamcorper ut. Aliquam commodo urna non sapien ornare nec placerat lacus eleifend. Quisque ut velit lacus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
  </p><p>
    Nulla eget turpis a tellus porttitor ultricies. Vestibulum ut ultricies justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum urna dui, sollicitudin eu consectetur nec, posuere sit amet eros. Donec in erat ut elit euismod elementum. Pellentesque vel arcu odio. Aliquam fermentum cursus erat ac egestas. Sed vel malesuada nunc. In volutpat, sem nec dictum suscipit, tortor magna volutpat sem, nec dictum diam metus vel diam. Vestibulum fringilla nulla vitae leo euismod nec commodo libero ullamcorper. Nulla facilisi. Curabitur tempus urna at felis iaculis elementum. Praesent a metus nulla. Duis consectetur, neque ut varius venenatis, diam justo tristique nisi, et ultrices turpis lorem a ante. Quisque sit amet magna leo. Etiam vel mi diam, quis ullamcorper diam. Vestibulum vitae nisl odio.
  </p><p>
    Maecenas tellus ante, rhoncus dictum ullamcorper nec, accumsan vitae diam. Etiam vitae enim metus, id luctus eros. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse fermentum diam a est dictum sit amet commodo sapien venenatis. Duis dignissim bibendum elit, sit amet sodales est fermentum id. Aliquam scelerisque dignissim elit, sed aliquet ligula cursus vitae. Mauris lectus nulla, porttitor interdum placerat quis, lacinia ut nisl. Quisque porta consectetur velit at ornare. Etiam in enim ut sem mattis porta. Donec ac purus magna. Morbi tellus felis, convallis at placerat vitae, facilisis in nunc. In ipsum tortor, hendrerit a interdum non, facilisis mattis felis.
  </p><p>
    Donec viverra mollis nibh id convallis. In lobortis, sapien elementum pulvinar tempus, lacus nibh semper massa, congue pharetra mauris ligula quis mi. Phasellus placerat euismod sagittis. Nullam ornare, massa eleifend iaculis aliquet, lacus urna vestibulum enim, a scelerisque nisi nisl nec elit. Duis dolor nibh, volutpat eget adipiscing sed, aliquam eget sapien. Etiam in pretium purus. Morbi odio leo, lobortis et rutrum tincidunt, pharetra eget mauris. Donec lobortis turpis vel elit elementum rhoncus. Phasellus vitae arcu dolor. Aenean eget lacus nibh, eu rutrum ipsum. Pellentesque mollis leo condimentum dui commodo iaculis. Quisque rutrum lorem nec nibh mattis malesuada. In hac habitasse platea dictumst. Duis nec purus purus. Suspendisse fermentum porta nibh, quis vulputate magna pellentesque vitae. Curabitur eu tortor eu quam tincidunt egestas ac sit amet mauris.
  </p><p>
    Maecenas tempus nibh eget augue fringilla at egestas enim ultrices. In a velit gravida mi sodales vehicula. In vestibulum elementum velit sit amet luctus. Vestibulum et auctor ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec et lectus eget sapien porttitor porttitor pretium sit amet ligula. Sed et erat in quam bibendum aliquet. Integer porttitor pellentesque nulla, quis vestibulum lectus ultricies sed. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras ut augue augue. In eget accumsan leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis diam velit, non ultrices quam. Curabitur vitae urna nec lorem adipiscing tincidunt id id velit. Aliquam blandit ornare metus, sed adipiscing diam feugiat vitae. Mauris hendrerit hendrerit turpis, id feugiat mi interdum nec. 
  </p>
</div>


contact.php File
Code:
<?php
  include "./pages/skelet/header.php";
  include "./pages/skelet/menu.php";
  include "./pages/contact.php";
  include "./pages/skelet/footer.php";  
?>


gallery.php File
Code:
<?php
  include "./pages/skelet/header.php";
  include "./pages/skelet/menu.php";
  include "./pages/gallery.php";
  include "./pages/skelet/footer.php";
?>


index.php File
Code:
<?php
  include "./pages/skelet/header.php";
  include "./pages/skelet/menu.php";
  include "./pages/home.php";
  include "./pages/skelet/footer.php";
?>


SQL
Code:

pictures  CREATE TABLE `pictures` (                                                      
            `picture_id` int(10) unsigned NOT NULL auto_increment,                       
            `picture_name` varchar(255) collate utf8_unicode_ci default NULL,            
            PRIMARY KEY  (`picture_id`)                                                  
          ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci  
[ Zmaj @ 11.05.2009. 04:02 ] @
malo je off ali ovo sto se u ovoj temi sastavlja je okvir za neki osnovni framwork, a to se moze se naci vec zavrseno u CodeIgiteru, koji je krajnje jednostavan za instalaciju i upotrebu, za one koji neznaju u pitanju je MVC framework. Na sajtu se nalazi odlican video tutorijal koji za nekih 20 minuta objasni instalaciju i jedan jednostavan primer. U njemu sam odradio par projekata i vrlo sam zadovoljan, jer sve sto sam i sam godinama razvijao nasao sam u njemu. CodeIgniter je odlican za manje projekte, kojih je vecina. Nije mi zelja dapotcenjujem bilo ciji rad u ovoj temi, jednostavno sam i sam odustao od pravljenja svog framworka kad sam proba CI, jer je mnogo lakse koristiti gotovo sve i testirano od strane hiljada ljudi nego pisati sam.
[ Nikola Poša @ 11.05.2009. 11:00 ] @
Slažem se... I ja sam ranije uvek pokušavao da pravim nešto svoje, da razrađujem neki svoj radni okvir, a onda sam uvideo da to u stvari sve već postoji, a plus je odrađeno na mnogo kvaliteniji, profesionalniji način. Npr. zašto bi sad ja uzeo da pravim neki svoj template engine sistem, kad postoji Smarty. Ili da pravim neki database apstraction sloj kad postoji npr. ADOdb. Ima još mnogo takvih primera, ali poenta je da ne treba izmišljati "toplu vodu". Bar ja tako mislim...

Uglavnom, u poslednje vreme se najviše oslanjam upravo na Smarty, ADOdb Lite, zatim pojedine klase iz PEAR bibilioteke (Auth, Captcha, itd.), kao i poneke iz Zend Framework paketa (npr. Zend_Form, Zend_Mail, Zend_Registry, Zend_Json, itd.). Naravno, uz sve ovo koristim još par klasa koje sam baš ja napisao...

I da me neko ne shvati pogrešno, svaka čast Borisu na ovome što radi, jer to može da bude stvarno super kurs za nekoga ko se tek upoznaje sa OOP-om i nekim iole naprednijim prinicipima programiranja u PHP-u. Samo napred.
[ Mister_rap @ 11.05.2009. 11:28 ] @
Cilj ove teme jeste da se korisnicima olaksa upoznavanje sa nekim framework-om. I naravno da skapiraju neke koncepte.
Takodje mogu da pitaju sve sto im nije jasno i da ucestvuju u razvoju ako to zele. Tako da je tema kao takva po mom licnom misljenju odlicna.

Sa druge strane CI, ZF, Cake, qCodo i sl. imaju niz prednosti ali za pocetnike moze da bude jako tesko da krenu sa ucenjem istih...
Takodje cesto se desava na vecim projektima da moras koristiti inhouse projekat jer jer racionalnije i jednostavnije, a njega je o5 pisalo recimo par ljudi sto ce reci da "personal" fw-i mogu da budu jako mocni i isplativi.
Meni licno ni jedan od fw-a sam po sebi nije dovoljan vec koristim posebne fw-e za testing, externe OR mappere i sl. A to nije mali broj tehnologija i treba da prodje odredjeno vreme da bi se neko upoznao sa istima.

Zakljucak je da svakako podrzavam fw-e ali mislim da ova diskusija stvara samo dodatnu konfuziju kod pocetnika koji ovo citaju.
[ b0ris @ 11.05.2009. 17:58 ] @
Slazem se u potpunosti sa mister_rep.
Poenta je da ljudi shvate o cemu se radi (naravno da svi mi znamo za frameworke i milione kalsa koje mogu da se samo implementiraju).
Mislio sam da je najlakse da krenemo od pocetka (bukvalno od 0), i onda da polako dodamo neke prednosti.
Recimo sledece sto bih uradio, posle kreiranja cms-a, je prebacivanje sadrzaja stranica u DB i prikazivanje preko jedne strane.
Zatim sam planirao da ubacim Smarty da vide ljudi koliko olaksava posao i sta je to ustvari template engine (na samom primeru), a posle toga ko zna :)
[ vatri @ 14.05.2009. 20:07 ] @
Ljudi tema je super, svaka cast i samo naprijed! Pohvale za borisa i ostale clanove i nadam se da ce se i ostali iskusniji (ima ih dosta na ovom forumu) ukljuciti u raspravu.

Mozda bi bilo dobro da moderatori preimenuju temu i da je stave u TOP, to je moj predlog.

Pozdrav i samo naprijed
[ vatri @ 16.05.2009. 21:50 ] @
E ljudi mene zanimaju dve stvari kod klasa:

Code:

 /**
    * Connection parameter which holdes information about host account
    * @access private
    * @name host
    */
    private $db_host = "";
...


Gore je u pitanju db klasa sa prve strane ove teme.
1. jel ima kakvu funkciju ovo @acces privat i @name host ili je to cisto komentar?
2. zasto se pise ovo private $db_host = ""?
[ Nikola Poša @ 16.05.2009. 21:56 ] @
1. Da to je običan komentar, ali pisan PHPDoc sintaksom. Na taj način se mnogo jednostavno pravi dokumentacija uz pomoć nekih parser-a, kao što je phpDocumentator.
2. Ako si pitao za ono "private", onda je odgovor da tom članu klase ne bi moglo da se pristupa spolja, odnosno, taj član će moći da se koristi samo unutar klase. Takođe, privatni članovi neke klase nisu dostupni u klasama koje se izvode iz nje.
[ b0ris @ 16.05.2009. 23:21 ] @
Sutra sam na putu ceo dan ali vec sledece nedelje cu postaviti osnovni CMS.
Pozdrav
[ vatri @ 17.05.2009. 16:16 ] @
1. Nisam znao za tu PHPdoc sintaksu, moracu to pocet koristi...

2. Da razumijem sta je private ali zasto se dodjeljuje prazna vrijednost ?
[ Nemanja Avramović @ 17.05.2009. 16:27 ] @
Pa inicijalizuje se na prazan string, da ne bude null
[ vatri @ 17.05.2009. 17:17 ] @
e jes mi objasni svaka ti cast :)))

Code:

function DB($host, $user, $password, $database){
      /**
      * Setting up parameters
      */
      $this->db_host = $host;
      $this->db_user = $user;
      $this->db_password = $password;
      $this->db_database = $database;
      
      /**
      * Establishing connection
      */
      return $this->connect();   
    }


Vidim da se te var. opet kasnije inicijalizuju u ovoj gore funkciji ??

PS vidite da sam pocetnik ne zamjerite na glupim pitanjima :)
[ Mister_rap @ 17.05.2009. 18:07 ] @
Ta f-ja je konstruktor DB klase i ocekuje da ces joj proslediti neophodne parametre.
Promenjiva je inicijalizovana na "" zbog koda koji sledi u connect metodi

Code:

/**
  * Checking if everything is filled up so we can establish connection.
  * We can also use empty() function in this if statment.
  */
      if(($this->db_host != "") && ($this->db_user != "")  && ($this->db_database != "")){


Ps.
Mali hint za b0risa: nema potrebe za dvostrukim navodinicima.
Ne bi bilo lose da se ovo ostavi na google code recimo kad se napravi taj osnovni funkcionalan kostur...
[ b0ris @ 20.05.2009. 15:49 ] @
Evo ga i ostatak.
Obratite paznju na to da je sve za sad osnovno.
Dok sam radio primetio sam da bi bilo najbolje da sledecei korak bude implementacija nekog template engine-a (smarty).

@Mister_rap: ok :), ulepsavam kod cim dodam smarty. Onda ga stavite gde zelite :)
[ b0ris @ 20.05.2009. 16:05 ] @
Izgled cms kostura
Code:

- cms
-- base
--- tools.php
-- css
--- admin.css
--- content.css
--- global.css
--- index.css
--- menu.css
-- pages
--- skelet
---- footer.php
---- header.php
---- menu.php
--- admins.php
--- gallery.php
--- hello.php
--- index.php
--- logout.php
-- admins.php
-- gallery.php
-- hello.php
-- index.php
-- logout.php


file: cms/base/tools.php
Code:

<?php
/**
* File in which all the tool functions that we might use will be stored.
* @version 0.1 beta
* @author www.elitesecurity.org (written by member b0ris)
*/
  
/**
* @desc Function which will check if user is logged in. We will also set up full admin account here for purpose of loging in without
* messing around with data base (test account: administrator/demo (username/password) ).
* We will check for SQL injections later as we develop.
*/
function checkLogged($username, $pass){
  if($username != "" && $pass != ""){
    // Should be removed once we establish our account in database.
    if($username == "administrator" && $pass == "demo") return true;
    global $db;
    $pass = md5($pass);
    $res = $db->getrows("SELECT * FROM admins WHERE admin_name = '$username' AND admin_password = '$pass' ");
    if(is_array($res)){
      if($res[0]['admin_name'] == $username && $res[0]['admin_password'] == $pass ) return true;
      else return false;
    }else return false;
  }
  else return false;
}
?>


file: cms/css/admins.css
Code:

#a_row{
  clear:both;
  text-align:left;
  margin:0 auto;
  width:420px;
}
  #a_column{
    float:left;
    width:200px;
    border-bottom:1px solid gray;
    padding:5px;
  }


file: cms/css/content.css
Code:

#content{
  clear:both;
  text-align:left;
}


file: cms/css/global.css
Code:

body, td {
  font-family: Verdana;
  font-size:11px;
  text-align:center;
  background-color: #F2F2F2;
}

a {
  text-decoration:none;
  color:#FFB900;
}

a:hover {
  color:silver;
}


file: cms/css/index.css
Code:

#table{
  width:350px;
  margin:0 auto;
  border:1px solid black;
  padding: 20px;
}
  #row{
  clear:both;
  }
   #label{
     width:150px;
     float:left;
   }
   #html{
     width:200px;
     float:left;
   }
.button_flat{
  border:1px solid #666666;
}


file: cms/css/menu.css
Code:

#menu{
  clear:both;
  margin: 0 auto;
  text-align: left;
  width:300px;
}
#menu_option{
  float:left;
  width:100px;
}
#menu A{
  font-weight: bold;
}


file: cms/pages/skelet/footer.php
Code:

<?php echo "\n"; ?>
</body>
</html>


file" cms/pages/skelet/header.php
Code:

<?php
  /**
  * @desc Here we will include everything we need for any page. NOTE: Short tags are not used on purpose.
  */
  // Not to copy all classes from our frontend we will just move back and use same classes we use for frontend.
  // Including all the classes we need to display a page. Instead of including this classes one by one each time
  // we could also use _autoload method which php provides
  include "./../base/class.urlhandler.php";
  include "./../base/class.db.php";
  include "./../base/class.session.php";
  include "./base/tools.php";
  
  // Creating instance of urlHandler which we will use later.
  $url = new urlHandler();
  // Creating instance of db (connection to data base)
  if(!$db = new DB("localhost", "root", "", "elitesecurity")){ echo "Could not connect to database!";exit(1);}
  // Creating instance of session and starting up the session (note: session must start before any display happens.
  // Be sure that you dont have enter (\n) as startup char. This can create errors.) 
  $session = new Session();
  $session->startSession();
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="content-language" content="sr">
<meta name="author" content="elitesecurity">
<meta name="generator" content="Elitesecurity CMS <boris vujicic>">
<meta name="description" content="Home page, test page for basic CMS">
<meta name="keywords" content="">
<meta name="creation-date" content="09/20/2007">
<meta name="robots" content="nofollow" />
<title>CMS</title>
<link rel="stylesheet" type="text/css" href="./css/global.css">
<link rel="stylesheet" type="text/css" href="./css/menu.css">
<link rel="stylesheet" type="text/css" href="./css/content.css">
<link rel="stylesheet" type="text/css" href="./css/index.css">
<!-- We will arange display of apropriet css for selected page later. -->
<link rel="stylesheet" type="text/css" href="./css/admins.css">
</head>
<body>


file: cms/pages/skelet/menu.php
Code:

<?php
/**
* @desc Creating menu. Latter we will create dynamic page creation.
*/
$logged = $session->getValue("logged");
if($logged == 1){
?>
<div id="menu">
  <div id="menu_option"><a href="admins.php">Admins</a></div>
  <div id="menu_option"><a href="gallery.php">Gallery</a></div>
  <div id="menu_option"><a href="logout.php">Log out</a></div>
</div>
<br/><br/>
<?php }?>


file: cms/pages/admins.php
Code:

<?php
/**
* Later we will simplify display of this page and add control for permissions (who and how can access this page).
*/
?>
<div id ="content">
<p>Administrate User accounts for backend.</p><br/>
<?php
  // Catching method and id (if ones are set) which is activated for this page
  $method = $url->getValue("method");
  $id = $url->getValue("id");
  // If method is set and id is numeric, then we should do something (check for type of metod and execute)
  if($method != "" && is_numeric($id)){
    // Delete administrator
    if($method == "delete") $db->query("DELETE FROM admins WHERE admin_id = $id");
    // Edit administrator
    if($method == "edit" || $method == "add"){
      $admin = $db->getrows("SELECT * FROM admins WHERE admin_id = $id");
      $content = "
      <form action=\"admins.php\" method=\"post\">
        <div id=\"row\">
          <div id=\"label\"> Admin Name: </div>
          <div id=\"html\"> <input type=\"text\" name=\"admin_name\" value=\"{$admin[0]['admin_name']}\" /> </div>
        </div>
        <div id=\"row\">
          <div id=\"label\"> Password: </div>
          <div id=\"html\"> <input type=\"password\" name=\"pass\" value=\"\" /> </div>
        </div>
        <div id=\"row\">
          <div id=\"label\"> Repeat Password: </div>
          <div id=\"html\"> <input type=\"password\" name=\"repass\" value=\"\" /> </div>
        </div>
        <div id=\"row\">
          <input type=\"hidden\" value=\"{$admin[0]['admin_id']}\" name=\"id\"/> 
          <input type=\"hidden\" value=\"$method\" name=\"method\"/> 
          <input type=\"submit\" value=\"Make Change\" class=\"button_flat\" /> 
        </div>
      </form>
      ";
      echo $content;
    }
  }
  
  // Updating member
  if($method == "edit"){
    // Getting administrator name, password and repeated password
    $admin_name = $url->getValue("admin_name");
    $pass = $url->getValue("pass");
    $repass = $url->getValue("repass");
    
    // Checking if everything is correct
    if($admin_name != "" && $pass == $repass){
      if($pass == "") $db->query("UPDATE admins SET admin_name = '$admin_name' WHERE admin_id = $id");
      else{
        $pass = md5($pass);
        $db->query("UPDATE admins SET admin_name = '$admin_name', admin_password = '$pass' WHERE admin_id = $id");
      }
    }
  }
  
  // Add member
  if($method == "add"){
    // Getting administrator name, password and repeated password
    $admin_name = $url->getValue("admin_name");
    $pass = $url->getValue("pass");
    $repass = $url->getValue("repass");
    
    // Inserting member into databse
    if($admin_name != "" && $pass == $repass && $pass != ""){
        $pass = md5($pass);
        $db->query("INSERT INTO admins(admin_name, admin_password) VALUES ('$admin_name', '$pass')");
    }
  }

  // Lets select all members and display them for managing
  $admins = $db->getrows("SELECT * FROM admins");
  if(is_array($admins)){
    echo "<div id=\"a_row\"><div id=\"a_column\" >Admin name</div><div id=\"a_column\"> <a href=\"admins.php?method=add&id=0\">add new</a> </div></div>";
    foreach($admins as $key => $value){
      echo "<div id=\"a_row\">";
      echo "
      <div id=\"a_column\" >{$admins[$key]['admin_name']}</div>
      <div id=\"a_column\">
        <a href=\"admins.php?method=edit&id={$admins[$key]['admin_id']}\">edit</a>
        <a href=\"admins.php?method=delete&id={$admins[$key]['admin_id']}\">delete</a>
      </div>";
      echo "</div>";
    }
  }else{
  }
?>
</div>


file: cms/pages/gallery.php
Code:

<?php
/**
* Administration of gallery, done really simple. We will build upon this later.
*/
?>
<div id ="content">
<p>Administrate Gallery.</p>
<?php

  echo '<p><a href="gallery.php?mode=add">Add new photo to gallery.</a></p>';
  echo '<p>Gallery</p>';
  
  // Catching mode and id of photo (if one is set). Remember we are using class UrlHandler so there is no reason to think
  // which way (POST, GET) data is being transferred to us.
  $mode = $url->getValue("mode");
  $id = $url->getValue("id");
  
  // If mode is delete, lets delete some pictures.
  if($mode == "delete"){
    $gallery = $db->getrows("SELECT * FROM pictures WHERE picture_id = $id");
    $db->query("DELETE FROM pictures WHERE picture_id = $id");
    // Here we should add some checkups if this picture really exists at the time.
    // We will build upon this later.
    unlink("./../uploads/pictures/{$gallery[0]['picture_name']}");
  }
  
  // If we want to add new picture? Lets display a form for adding one
  if($mode == "add"){
    echo '
    <form enctype="multipart/form-data" action="gallery.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a file to upload: <input name="picture" type="file" /><br />
<input type="hidden" name="mode" value="upload" />
<input type="submit" value="Upload Picture" />
</form>
    ';
  }
  
  // If picture is being uploaded, lets catch that bytes (picture) and do something with it (like store it :) )
  // Here no checkup for right format will be done.
  if($mode == "upload"){
    // Lets set the path where picture will go.
    $target_path = "./../uploads/pictures/";
    // Lets attach the name of the picture to that path.
    $target_path = $target_path . basename( $_FILES['picture']['name']); 
    // Lets copy our photo (file) on location where we want it to go. Is it moved?
    if(move_uploaded_file($_FILES['picture']['tmp_name'], $target_path)) {
        // Yes it is moved. Lets add this into database.
        $db->query("INSERT INTO pictures(picture_name) VALUES ('{$_FILES['picture']['name']}')");
        echo "The file ".  basename( $_FILES['picture']['name'])." has been uploaded";
    } else{
        // No. We should handle this error in some way.
        echo "There was an error uploading the file, please try again!";
    }
  }

  // Lets take all the pictures from database and display them.
  $gallery = $db->getrows("SELECT * FROM pictures");
  foreach($gallery as $key => $value){
    if(($key+1)%5 == 0)
      echo "<div style=\"clear:both;\">&nbsp;</div>";
    echo "
    <div style=\"float:left; border:1px solid black;\">
      <img src=\"./../uploads/pictures/{$gallery[$key]['picture_name']}\" width=\"70px\" style=\"border:1px solid #cccccc\"><br/>
      <a href=\"gallery.php?mode=delete&id={$gallery[$key]['picture_id']}\" >delete</a> | <a href=\"./../uploads/pictures/{$gallery[$key]['picture_name']}\" target=\"_BLANK\">view</a>
    </div>";
  }
?>
</div>


file: cms/pages/hello.php
Code:

<?php
// Checking if user is logged on
$logged = $session->getValue("logged");
if($logged == 1){  
?>
<div id="content">
  <p>
    Welcome to our basic CMS. We will keep on improving this CMS step by step.
  </p>
</div>
<?php }?>


file: cms/pages/home.php
Code:

<?php
/**
* @desc Here we will atempt to login and show some content if we are logged in :)
*/

  // Getting username and password.
  $username = $url->getValue("username");
  $pass = $url->getValue("pass");
  // Now we will check if user exists in database and loog him in if he exists.
  if($username != "" && $pass != ""){
    if(checkLogged($username, $pass)){
      $session->removeValue("logged");
      $session->addValue("logged", 1);
    }
    else {
      $session->removeValue("logged");
      $session->addValue("logged", 0);
    }
  }
  $logged = $session->getValue("logged");
  if($logged != 1){
?>
<form action="index.php" method="post">
  <div id="content">
    <div id="table">
      <div id="row">
        <div id="label" >Username: </div>
        <div id="html" > <input type="text" name="username" /> </div>
      </div>
      <div id="row">
        <div id="label" >Password: </div>
        <div id="html" > <input type="password" name="pass" /> </div>
      </div>
      <div id="row"> <input type="submit" value="Login" class="button_flat"/> </div>
    </div>
  </div>
</form>
<?php }else{ ?>
You are logged :)<br/>
In 3 seconds you will be redirected to backend. If that does not happend click on the link below.<br/>
<a href="hello.php">Backend</a>
<meta http-equiv="refresh" content="3;url=hello.php">
<?php } ?>


file: cms/pages/logout.php
Code:

<?php
  // Lets remove the login flag, and refresh this content.
  $session->removeValue("logged");
?>
<div id="content">
  <p>Thank you for using this CMS.</p>
</div>
<meta http-equiv="refresh" content="3;url=index.php"> 


file: cms/admins.php
Code:

<?php
  include "./pages/skelet/header.php";
  include "./pages/skelet/menu.php";
  include "./pages/admins.php";
  include "./pages/skelet/footer.php";  
?>


file: cms/gallery.php
Code:

<?php
  include "./pages/skelet/header.php";
  include "./pages/skelet/menu.php";
  include "./pages/gallery.php";
  include "./pages/skelet/footer.php";   
?>


file: cms/hello.php
Code:

<?php
  include "./pages/skelet/header.php";
  include "./pages/skelet/menu.php";
  include "./pages/hello.php";
  include "./pages/skelet/footer.php";
?>


file: cms/index.php
Code:

<?php
  include "./pages/skelet/header.php";
  include "./pages/home.php";
  include "./pages/skelet/footer.php";  
?>                                                                   


file: cms/logout.php
Code:

<?php
  include "./pages/skelet/header.php";
  include "./pages/logout.php";
  include "./pages/skelet/footer.php";  
?>
[ b0ris @ 20.05.2009. 16:07 ] @
Eto to je za sad vrlo mali CMS sa vrlo ruznom galerijom :)
Ako imate neka pitanja udrite, sad je vreme.
Rekao bih da je ovo dovoljno za prvu zastavicu :)
Druga zastavica bi bila implementacija smarty template engine-a i preraspodela koda kako bi odgovarao istom.

Pozdrav
[ amitkic @ 28.06.2009. 11:35 ] @
e ovo je ekstra, jedva cekam nastavak
[ amitkic @ 28.06.2009. 11:46 ] @
evo ovo shto je boris napisao samo zapakovano u rar
[ amitkic @ 14.08.2009. 20:38 ] @
ajd malo budjenje teme
[ b0ris @ 17.08.2009. 12:21 ] @
Vidim da je jedini zainteresovan za ovo pokretac teme (amitkic).
Postavicu za sad grubu postavku smarty za frontend. Posle cu dodati jos ako ljudima bude interesantno da citaju :)
Malo mi je glupo da pisem u prazno.

[Ovu poruku je menjao b0ris dana 17.08.2009. u 13:45 GMT+1]
[ b0ris @ 17.08.2009. 12:39 ] @
Za postavku smarty-ja potrebno je isti prvo skinuti sa neta http://www.smarty.net/download.php.
Zatim smarty prebaciti u root sajta i modifikovati dve linije.
file: smarty/Smarty.calss.php
Code:
    /**
     * The name of the directory where templates are located.
     *
     * @var string
     */
    var $template_dir    =  './cache/smarty/templates';

    /**
     * The directory where compiled templates are located.
     *
     * @var string
     */
    var $compile_dir     =  './cache/smarty/templates_c';

Linije se kod mene nalaze na 82 i 75 liniji.

Posto smo postavili smarty potrebno je kreirati foldere u kojima ce se nalaziti smarty fajlovi (kao sto je navedeno u kodu iznad).

Kreirati sledecu strukturu na rootu sajta.
-cache
--smarty
---templates
---templates_c
U koliko koristite LINUX potrebno je postaviti na templates_c "chmod 777 ./cache/smarty/templates_c"

U ovom trenutku smarty je postavljen. Sada sledi prebacivanje koda u smarty.
Folder pages trenutno postaje nepotreban buduci da ce se sve stranice nalaziti u folderu ./cache/smarty/templates
Skripte contact.php i gallery.php mozemo ukloniti.
Skriptu index.php cemo promeniti da odgovara novom sistemu.

file: index.php
Code:
<?php
    /**
  * @desc Here we will include everything we need for any page. Attention to SEO (search engine optimization)
  * will be established latter when we move page display into data base. NOTE: Short tags are not used on purpose.
  */
  // Including all the classes we need to display a page. Instead of including this classes one by one each time
  // we could also use _autoload method which php provides
  include "./base/class.urlhandler.php";
  include "./base/class.db.php";
  include "./base/class.session.php";
  include "./smarty/Smarty.class.php";
  
  // Creating instance of urlHandler which we will use later.
  $url = new urlHandler();
  // Creating instance of db (connection to data base)
  if(!$db = new DB("localhost", "root", "", "elitesecurity")){ echo "Could not connect to database!";exit(1);}
  // Creating instance of session and starting up the session (note: session must start before any display happens.
  // Be sure that you dont have enter (\n) as startup char. This can create errors.) 
  $session = new Session();
  $session->startSession();
  
  $page = $url->getValue("page"); // Getting the page we want to display
  if(!$page) $page = "index";      // Setting up startup page
  // Here we should add a checkup if page does not exist.
  
  // Creating menu. Later we will retrieve menu options from data base. There fore this is useful to 
  // be done here.
  $menu = array(
  "0" => array("href" => "index.php", "name" => "Home"),
  "1" => array("href" => "index.php?page=gallery", "name" => "Gallery"),
  "2" => array("href" => "index.php?page=contact", "name" => "Contact"),
  );                                                                     
  
  $smarty = new Smarty();  
  
  // Assigning variables that will be used in certain pages. This should be called dynamically so
  // that it is not executed each time index.php loads.
  $haspictures = false;
  // Executing query
  $pictures = $db->getrows("SELECT * FROM pictures");
  // did we got something back?
  if($pictures) $haspictures = true;
  // We did. Ooo looky looky we have some photos :) Lets display them.
  if($haspictures){
    foreach($pictures as $key => $value){
      $pictures[$key]['src'] = "./uploads/pictures/{$pictures[$key]['picture_name']}";
      $pictures[$key]['alt'] = $pictures[$key]['picture_name'];
      $pictures[$key]['title'] = $pictures[$key]['picture_name'];
    }
  }
  $smarty->assign("pictures", $pictures);
  $smarty->assign("haspictures", $haspictures);
  
  $smarty->assign("menu", $menu);               // Menu array
  $smarty->assign("title", "$page");            // page title
  $smarty->display("header.tpl");               // Executing header
  $smarty->display("menu.tpl");                 // Executing menu
  $smarty->display("$page.tpl");                // Executing desired page
  $smarty->display("footer.tpl");               // Executing footer.
?>


zatim cemo kreirati nove templejt fajlove.

file: ./cache/smarty/templates/header.tpl
Code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="content-language" content="sr">
<meta name="author" content="elitesecurity">
<!-- <meta http-equiv="Reply-to" content="@.com"> -->
<meta name="generator" content="Elitesecurity CMS <boris vujicic>">
<meta name="description" content="Home page, test page for basic CMS">
<meta name="keywords" content="">
<meta name="creation-date" content="09/20/2007">
<meta name="revisit-after" content="15 days">
<title>{$title}</title>
<link rel="stylesheet" type="text/css" href="./css/global.css">
<link rel="stylesheet" type="text/css" href="./css/menu.css">
<link rel="stylesheet" type="text/css" href="./css/content.css">
</head>
<body>


file: ./cache/smarty/templates/footer.tpl
Code:

</body>
</html>


file: ./cache/smarty/templates/menu.tpl
Code:
<div id="menu">
  {section name=i loop=$menu}
  <div id="menu_option"><a href="{$menu[i].href}">{$menu[i].name}</a></div>
  {/section}                                                   
</div>
<br/><br/>


file: ./cache/smarty/templates/index.tpl
Code:

<div id="content">
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis dictum pellentesque sem. Praesent purus dui, cursus eu gravida sit amet, elementum eu justo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sed ante at tellus pulvinar elementum sit amet vel ante. Nulla in arcu sit amet lacus placerat pulvinar consectetur non justo. Donec risus erat, sagittis at aliquet eget, faucibus sit amet ante. Morbi ultrices purus et nunc sagittis ultrices. Vivamus auctor facilisis volutpat. Fusce vel diam massa. Vestibulum fringilla pretium rutrum. Ut eros velit, dignissim sit amet sollicitudin nec, eleifend malesuada tellus. Ut in laoreet velit. Nulla lobortis tincidunt velit, ac congue dui ullamcorper ut. Aliquam commodo urna non sapien ornare nec placerat lacus eleifend. Quisque ut velit lacus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
  </p><p>
    Nulla eget turpis a tellus porttitor ultricies. Vestibulum ut ultricies justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum urna dui, sollicitudin eu consectetur nec, posuere sit amet eros. Donec in erat ut elit euismod elementum. Pellentesque vel arcu odio. Aliquam fermentum cursus erat ac egestas. Sed vel malesuada nunc. In volutpat, sem nec dictum suscipit, tortor magna volutpat sem, nec dictum diam metus vel diam. Vestibulum fringilla nulla vitae leo euismod nec commodo libero ullamcorper. Nulla facilisi. Curabitur tempus urna at felis iaculis elementum. Praesent a metus nulla. Duis consectetur, neque ut varius venenatis, diam justo tristique nisi, et ultrices turpis lorem a ante. Quisque sit amet magna leo. Etiam vel mi diam, quis ullamcorper diam. Vestibulum vitae nisl odio.
  </p><p>
    Maecenas tellus ante, rhoncus dictum ullamcorper nec, accumsan vitae diam. Etiam vitae enim metus, id luctus eros. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse fermentum diam a est dictum sit amet commodo sapien venenatis. Duis dignissim bibendum elit, sit amet sodales est fermentum id. Aliquam scelerisque dignissim elit, sed aliquet ligula cursus vitae. Mauris lectus nulla, porttitor interdum placerat quis, lacinia ut nisl. Quisque porta consectetur velit at ornare. Etiam in enim ut sem mattis porta. Donec ac purus magna. Morbi tellus felis, convallis at placerat vitae, facilisis in nunc. In ipsum tortor, hendrerit a interdum non, facilisis mattis felis.

  </p><p>
    Donec viverra mollis nibh id convallis. In lobortis, sapien elementum pulvinar tempus, lacus nibh semper massa, congue pharetra mauris ligula quis mi. Phasellus placerat euismod sagittis. Nullam ornare, massa eleifend iaculis aliquet, lacus urna vestibulum enim, a scelerisque nisi nisl nec elit. Duis dolor nibh, volutpat eget adipiscing sed, aliquam eget sapien. Etiam in pretium purus. Morbi odio leo, lobortis et rutrum tincidunt, pharetra eget mauris. Donec lobortis turpis vel elit elementum rhoncus. Phasellus vitae arcu dolor. Aenean eget lacus nibh, eu rutrum ipsum. Pellentesque mollis leo condimentum dui commodo iaculis. Quisque rutrum lorem nec nibh mattis malesuada. In hac habitasse platea dictumst. Duis nec purus purus. Suspendisse fermentum porta nibh, quis vulputate magna pellentesque vitae. Curabitur eu tortor eu quam tincidunt egestas ac sit amet mauris.
  </p><p>
    Maecenas tempus nibh eget augue fringilla at egestas enim ultrices. In a velit gravida mi sodales vehicula. In vestibulum elementum velit sit amet luctus. Vestibulum et auctor ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec et lectus eget sapien porttitor porttitor pretium sit amet ligula. Sed et erat in quam bibendum aliquet. Integer porttitor pellentesque nulla, quis vestibulum lectus ultricies sed. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras ut augue augue. In eget accumsan leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec quis diam velit, non ultrices quam. Curabitur vitae urna nec lorem adipiscing tincidunt id id velit. Aliquam blandit ornare metus, sed adipiscing diam feugiat vitae. Mauris hendrerit hendrerit turpis, id feugiat mi interdum nec. 
  </p>
</div>


file: ./cache/smarty/templates/gallery.tpl
Code:

<div id="content">
  {if $haspictures}
    {section name=i loop=$pictures}
      <div id="img"> <img src="{$pictures[i].src}" alt="{$pictures[i].alt}" title="{$pictures[i].title}"></div>
    {/section}
  {else}
    <p> Currently there are no pictures. </p> 
  {/if}
</div>


file: ./cache/smarty/templates/contact.tpl
Code:
<div id="content">
  <form action="contact.php" method="post">
    Email: <input type="text" name="email" id="email" /><br/><br/>
    Message: <br/>
    <textarea cols="50" rows="5" name="msg"></textarea><br/><br/>
    <input type="submit" value="Ask us?" />
  </form>
</div>


U ovom momentu struktura sajta treba da izgleda ovako
+base
-cache
--smarty
---templates
----contact.tpl
----footer.tpl
----gallery.tpl
----header.tpl
----index.tpl
----menu.tpl
---templates_c
+cms
+css
+smarty
+uploads
index.php
[ dakipro @ 17.08.2009. 12:47 ] @
Pa interesantno je sigurno za citanje, sad, vise je interesantno onima koji nisu imali prilike da se srecu i da rade sa slicnim stvarima, u svakom slucaju bice sigurno interesantno (a bogami i korisno) i buducim pocetnicima, ali definitivno us nick b0ris ide dobar reper kad se budu raspitivali za doticnu personu nekad negde, odmah se vidi da covek zna znanje. Nadam se da je to malo motivacije od strane nas koji se vadimo kako nemamo vremena da pisemo :)
A i ti si guru sad ovog projekta, cekamo da ti kazes nesto pa da prokomentarismo, da odrzis koncepciju i tok misli :)
[ dakipro @ 17.08.2009. 12:49 ] @
Eve zamerke/predloga, u strukturi sajta, da li je mozda bolje da smarty ne bude u root-u, vec da ide u nekom folderu class, ili tako nesto, gde bi posle isle i druge klase, recimo za rad sa bazom i to?
ili sa propustio tok misli od pocetka, prodje vreme
[ b0ris @ 17.08.2009. 12:57 ] @
Razmisljao sam da ide sto lakse na pocetku, i da kako vreme prodje stvari stavljamo na svoje mesto (kako bi ljudima bilo jasno zasto se tu nalaze).
Za sad i u kodu ima dosta propusta (koji su namerno tu kako bi se isprovocirao neki komentar ;) ) te propuste sam mislio kasnije popuniti kako vreme bude prolazilo (uz ili bez pomoci ostalih).

Citat:
ali definitivno us nick b0ris ide dobar reper kad se budu raspitivali za doticnu personu nekad negde

Nisam poceo ovo pisati zbog nekog repera/statusa :) vec zbog ljudi koji iznova pitaju jednu te istu stvar a nigde nemaju sumirane informacije.
Ovo je vise kao pocetnicki projekat da bi ljudi razumeli o cemu se radi, a posle presli na mocnije stvari (atk, code igniter, zend itd..)
[ b0ris @ 17.08.2009. 12:59 ] @
Citat:
dakipro: Eve zamerke/predloga, u strukturi sajta, da li je mozda bolje da smarty ne bude u root-u, vec da ide u nekom folderu class, ili tako nesto, gde bi posle isle i druge klase, recimo za rad sa bazom i to?
ili sa propustio tok misli od pocetka, prodje vreme

Definitvno je bolje smarty smestiti u nekoj takvoj strukturi, slazem se u potpunosti.
Sto zbog nasledjivanja u koliko neko zeli menjati isti, sto zbog preglednosti koda.
[ b0ris @ 17.08.2009. 13:05 ] @
Mozda bi bilo dobro malo promeniti naziv teme?
[ dakipro @ 17.08.2009. 13:08 ] @
Pa razmisljam se razdvojiti temu, te od negde zapoceti novu koju bi smo linkovali u ovoj ili negde vec... ajde da prenoci pa cemo smisliti nesto, taman da se konsultujem sa jos par ljudi.
[ vatri @ 17.08.2009. 20:39 ] @
@b0ris: naravno da nije jedini zainteresovan amitkic. Ima ljudi koji prate ali ne pisu jer nisu kompetentni za to, kao ja npr. :)
Svaka cast jos jednom na trudu i tvojoj upornosti, mnogima ce biti od pomoci.

@dakipro: mislim da je dovoljno samo naziv teme da se promjeni da ne komplikujes bezveze, ioanko je vec drugi post (borisov) bio da ce se praviti CMS....
[ evajolie @ 19.08.2009. 10:05 ] @
I ja sam zainteresovana, samo vi pišite. Svaka čast i na dosadašnjem trudu. Uključiću se u temu onda kada budem imala šta pametno za reći ili za pitati.
Samo napred! Jako korisna tema!
[ vatri @ 13.10.2009. 17:24 ] @
ajde ljudi pisite izumrijece tema, steta je :S
[ b0ris @ 26.10.2009. 16:09 ] @
Evo cim uhvatim malo vremena nastavicu, da ne obecam ali recimo da cu dodati jos stvari uskoro.
[ b0ris @ 15.03.2011. 16:12 ] @
Pozdrav svima, zaposlio sam se u firmi u Splitu, i onda nisam imao dovoljno vremena da se uhvatim piskaranja.
Medjutim sad imam vremena ponovo da piskaram.
Pretpostavljam da je vecina vas koji ste pratili temu do sad briljiralo PHP :D, no ipak ja cu nastaviti da pisem za buduce generacije hehehe
[ b0ris @ 19.03.2011. 13:56 ] @
Pozdrav svima.

Rezime onog sto je napravljeno do sad i plan za nastavak.

Do sad smo napravili osnovnu postavku cms-a sa tri strane, klasom za kontrolu baze, sesije i linkova. Takodje smo napravili pozadinsku aplikaciju (cms) koja nam je omogucavala da dodamo par slika u galeriju i novog korisnika cms-a.

Strane su kreirane kroz fajl sistem tako da smo imali nekolicinu php skripti koje su predstavljale te strane, medjutim da bi dodali novu stranu morali smo da kreiramo jos par php skripti i da promenimo neke od skripti (menu) kako bi dodali novu stranu.

Ovo smo resili na nacin da smo php skripte koje su generisale html prebacili u smarty engine, tako da sad imamo jednu php skriptu kroz koju se ucitava ceo sajt.
Sve sto radimo vezano za sajt (php modele, nacine ponasanja odredjenih stranica) se nalazi u index.php skripti. Dovoljno je da kreiramo novi templejt u smarty i da imamo novu stranu.

Dobra strana ovog pristupa je sto je sad razdvojen dizajnerski i programerski posao. Dok vi pisete modele ponasanja u php-u, dizajner je u mogucnosti da kreira vizuelni izgled a da pri tom nije primoran da gleda gomilu php koda.

Losa strana je sto se sve desava kroz index.php, u slucaju da je zelja da se doda nova funkcionalnost to moramo odraditi u fajlu index.php.

Za sledecu zastavicu predlazem da pocnemo sa kreiranjem klasa koje ce olaksati posao index.php skripte, uz to i postaviti neke osnove OOP-a u web programiranju.

Zeljena funkcionalnost:
Da postoji jedna pomocna klasa koja se bavi prikazom sadrzaja na stranici.
Klase u kojima bi pisali funkcionalnosti odredjenih stranica (gallery, news...) bi implementirale Pages klasu, koja bi posle radila prikaz na osnovu stranice.
Neki od nacina da se postigne veza izmedju Pages klase i ostalih klasa:
- Da ostale klase direktno naslede Pages klasu. U pitanju je nasledjivanje klasa.
- Da ostale klase implementiraju Pages klasu kao interface (ova mi se vise svidja, idemo na ovu varijantu). U pitanje je implementacija interfaca.

Zadatak:
- Kreirati klasu koja se bavi prikazom stranice
- Kreirati klase koje pretstavljaju modele zeljenog ponasanja (gallery, news....)
[ Phikret @ 29.03.2011. 16:10 ] @
Borise svaka cast na dosadasnjem radu na cms-u. Vidi se da imas jasan put kojim nas vodis :). Svidja mi se pristup uvidjanja gde su greske i ispravka istih. Ovo je fantastican kurs. U iscekivanju nastavka kursa grickamo kokice. :)

P.S. Namerno sam otisao u offtopic i napisao ovo da se ne pomisli da niko ne prati ovu temu.
[ Thugzsr @ 09.04.2011. 07:37 ] @
Sjajan tutorijal! Sinoc sam bas poceo da citam, i nadam se da ce biti nastavka? Svaka cast za vreme izdvojeno za ovaj kurs!
[ b0ris @ 12.07.2011. 10:46 ] @
Pozdrav svima :)

Nastavak sledi :)

Sazetak nove funkcionalnosti (za sad i dalje grube)

- view klasa koja ce nam od sad procesirati svaki zahtev za stranicom i inicijalizirati sve sto je potrebno za rad (template engine, request handler (urlHandler), bazu, sesiju)

- rekonstruisali smo klase za galeriju, kontakt i home stranu.

Dobre strane nove funkcionalnosti:
- nemamo vise potrebu da diramo index.php koji sad ima samo svrhu prikazivanja sadrzaja
- obradjujemo sve potrebne inicijalizacije na jednom mestu i nije ih potrebno dirati
- jedino na sta trebamo obratiti paznju su klase koje odgovaraju stranicama koje zelimo prikazati

Lose strane:
- nije moguce aktivno menjati core klase kao sto su urlHandler, sessionHandler, template engine
- nije moguce imati vise opcija za jednu stvar (da recimo parsiramo nase template sa necim drugim osim smartijem)

Ima jos dobrih i losih stvari koje sam verovatno preskocio, no njima cemo se baviti u nastavku :)

Za sledecu zastavicu bi mogli da izvucemo template engine iz klase view napravimo jednu apstraktnu klasu preko koje bi mogli da postavljamo template engine (nesto kao plugin (dependency injection))

Ovo ce nam omoguciti da biramo template engine koji zelimo da koristimo. Elaboriracu u nastavku :)


Sta smo postigli sa ovim klasama?

Dovoljno je kreirati novu klasu koja nasledjuje view i u jednoj metodi obraditi prikaz te stranice.
Svu funkcionalnost novo napravljene stranice imamo na jednom mestu izdvojenu od ostalih stranica. Mozemo posvetiti svu svoju paznju samo toj stranici, bez da gledamo kod za ostale stranice.
Lakse nam je obraditi greske koje ce se javljati i dodavati nove funkcionalnosti.

Unificirali smo pristup urlHandleru (getRequest), tako da sad mozemo nesmetano menjati tu klasu a nas kod na stranicama ce i dalje funkcionirati.


Funkcionalnosti koje su nam omogucile da ovako nesto uradimo je facotry metoda.
- Factory metoda (factory template)


p.s. Nisam koristio interface kao sto sam naglasio u ranijem postu, jer mi se ovo cinilo kao bolji sledeci korak. Interface bi mogli da implementiramo kasnije.

Slede promene.

file: index.php
Code:

<?php 
include_once 'View.php';
View::dispatch();
?>


file: class.View.php
Code:

<?php
// Including all the classes we need to display a page. Instead of including this classes one by one each time
// we could also use _autoload method which php provides
include_once "./base/class.urlhandler.php";
include_once "./base/class.db.php";
include_once "./base/class.session.php";
include_once "./smarty/Smarty.class.php";
      
class View
{
  private $_scripts = array();
  private $_meta = array();
  private $_body = array();
  private $_css = array();
  private $_session = null;
  private $_request = null;
  private $_templateEngine = null;

  private function __construct()
  {
    // Creating instance of db (connection to data base)
    if(!$db = new DB("localhost", "root", "", "elitesecurity")){ echo "Could not connect to database!";exit(1);}
    // Creating instance of session and starting up the session (note: session must start before any display happens.
    $this->_session = new Session();
    $this->_session->startSession();
    $this->_templateEngine = new Smarty();
  }

  /**
   * Display content
   */
  static function dispatch()
  {
    // Build url handler
    $request = new urlHandler();

    $view = View::factory($request);
    $view->_templateEngine->display("header.tpl");               // Executing header
    $view->_templateEngine->display("menu.tpl");                 // Executing menu
    $view->dispatchIndex();                                                             // Executing desired page
    $view->_templateEngine->display("footer.tpl");               // Executing footer.
  }

  private function buildMenu()
  {
    // Creating menu. Later we will retrieve menu options from data base. There fore this is useful to 
   // be done here.
    $menu = array(
      "0" => array("href" => "index.php", "name" => "Home"),
      "1" => array("href" => "index.php?page=gallery", "name" => "Gallery"),
      "2" => array("href" => "index.php?page=contact", "name" => "Contact"),
    );

    $this->_templateEngine->assign("menu", $menu);               // Menu array
  }

  /**
   * Set request handler
   *
   * @param urlHandler $request
   */
  private function setRequest(urlHandler $request)
  {
    $this->_request = $request;
  }

  /**
   * @return urlHandler
   */
  private function getRequest()
  {
    return $this->_request;
  }

  /**
   * Initiate page that user requested. 
   * This method will create instance of class that is in direct releationship with page name.
   *
   * @param urlHandler $request
   * @return View
   */
  static private function factory(urlHandler $request)
  {
    // Creating instance of urlHandler which we will use later.
    $page = $request->getValue("page"); // Getting the page we want to display
    if(!$page) $page = "home";      // Setting up startup page
    // Here we should add a checkup if page does not exist.
    // If we dont have the page we should return 404. For now we will assume that we always have the page :/
    require_once('class.'.ucfirst($page).'.php');
    $view = new $page();
    $view->setRequest($request);

    return $view;
  }
}
?>


file: class.Gallery.php
Code:

<?php

class Gallery extends View
{
  public function dispatchIndex()
  {
    // Assigning variables that will be used in certain pages. This should be called dynamically so
    // that it is not executed each time index.php loads.
    $haspictures = false;
    // Executing query
    $pictures = $db->getrows("SELECT * FROM pictures");
    // did we got something back?
    if($pictures) $haspictures = true;
    // We did. Ooo looky looky we have some photos :) Lets display them.
    if($haspictures){
      foreach($pictures as $key => $value){
        $pictures[$key]['src'] = "./uploads/pictures/{$pictures[$key]['picture_name']}";
        $pictures[$key]['alt'] = $pictures[$key]['picture_name'];
        $pictures[$key]['title'] = $pictures[$key]['picture_name'];
      }
    }

    $this->_templateEngine->assign("pictures", $pictures);
    $this->_templateEngine->assign("haspictures", $haspictures);
    $this->_templateEngine->display("gallery.tpl");
  }
}
?>


file: class.Contact.php
Code:

<?php

class Contact extends View
{
  public function dispatchIndex()
  {
    // Getting email and msg values which are posted and storing those values in corresponding variables.
    $email = $this->getRequest()->getValue("email");
    $msg   = $this->getRequest()->getValue("msg");
         
    // Checking if values aer empty
    if($msg != "" && $email != ""){
      // Do something. For example send email
      /*
      if(mail("[email protected]", "Contact", "Email:$email<br/>\n".$msg)){
       echo "Message sent.";                                           
      }else{
        // Handle error.
      }
      */
      $msg = "Message sent.";
    }

    $this->_templateEngine->assign("message", $msg);
    $this->_templateEngine->display("contact.tpl");
  }
}
?>


file: class.Home.php
Code:

<?php

class Home extends View
{
  public function dispatchIndex()
  {
    $this->_templateEngine->display("index.tpl");
  }
}
?>


U ovom momentu struktura sajta treba da izgleda ovako
+base
+cache
+cms
+css
+smarty
+uploads
index.php
class.Gallery.php
class.View.php
class.Contact.php
class.Home.php
[ b0ris @ 12.07.2011. 10:52 ] @
Mrdamo se dugo ali sigurno ka interesantnijim stvarima :)

Zao mi je sto nemam vise vreman da pisem, ali jbga sta da se radi. Nadam se da ce ovo sluziti necemu, bar cemo proci kroz sve od pocetka do kraja.