<?
/*
 * Kontroler
 * 
 */
 
 /**
 * @file kontroler.php 
 * @author Damian Świstowski <dswistowski@gery.firma.pl>
 * @brief plik zawierający klasę kontrolera i configa
 * 
 * W pliku tym znajduje się jądro całego systemu do importowania danych, klasa config zawiera zestaw domyślnych ustawień systemu, natomiast kontroler (klasa adcentral) umożliwia łatwy dostęp do danych bez wnikania w szczegóły techniczne.
 * @see config
 * @see adcentral
 * 
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
 */
 
 
 
 /**
  * @brief Główna klasa, umożliwia pobieranie wszelkich danych z serwisu adcentral.pl
  * 
  * Do poprawnego zadziałania serwisu wystarczy wykonać:
  * <pre>
  * $adcentral = new $adcentral();
  * print $adcentral->pokarz();
  * </pre>
  * Domyślne opcje są wystarczające dla wszystkich podstawowych zastosowań.
  * Metody dostępu do obiektów umożliwiają używanie klasy adcentral bez silnika templatów.
  */
class adcentral {
	
	/** nazwa backendu używanego cachowania danych */
	private $backend = null;
	/** dozwolone modele do pobiernia oraz metody, które obsługują to pobieranie */
	private $url_mapper = array(
		'ogloszenie'=>'szczegolyOgloszenia',
		'ogloszenia_uzytkownika'=>'ogloszeniaUzytkownika',
		'ogloszenia_kategorii'=>'ogloszeniaKategorii',
		'zdjecie'=>'zdjecie',
		'film'=>'film',
		'miniatura'=>'miniatura',
		'uzytkownik'=>'uzytkownik',
	);
	/** obiekt klasy pobierającej dane z serwera adcentral*/
	private $fetcher = null;
	
    public function __construct(config $config = null )
    {
    	if($config==null)
    		$config = new config();
    	$this->config = $config;	
    }
    
    /**
     * @brief getter pobieracza danych z serwera
     * 
     * Zwraca obiekt pobieracza danych z serwera, logując tam odpowiedniego użytkownika
     */
    public function getFetcher()
    {
    	if(!$this->fetcher)
    		$this->fetcher = new fetcher($this->config);
    	return $this->fetcher;
    }
    
    /** 
     *  @brief pobranie modelu ogłoszenia
     *  
     *  Pobiera ogłoszenie z serwisu adcentral.
     * 
     *  @see ogloszenie
     * 
     *	@param $id id ogłoszenia które będzie pobrane
     *  @return obiekt simpleXML zawierający opis ogłoszenia 
     **/
    public function szczegolyOgloszenia($id)
    {
    	$ogloszenie = new ogloszenie($this);
    	$ogloszenie->pobierz($id);
    	return $ogloszenie;
    }
    
    /** 
     *  @brief pobranie modelu ogłoszeń użytkownika
     *  
     *  Pobiera ogłoszenie użytkownika z serwisu adcentral. 
     *  Zwracany obiekt simpleXML zawiera pole item, z której można odczytać ogłoszenia:
     *  <pre>
     *     $ogloszenia = $adcentral->ogloszeniaUzytkownika(12345);
     *     foreach($ogloszenia->item as $ogloszenie)
     *        print $ogloszenie->naglowek 
     *  </pre>
     *  Kod ten wypisze nagłówki wszystkich ogłoszeń.
     *  @see ogloszenia_uzytkownika
     * 
     *	@param $id id użytkownika którego ogłoszenia będą pobrane
     *  @return obiekt simpleXML zawierający zbiór ogłoszeń 
     **/
    public function ogloszeniaUzytkownika($id)
    {
    	$ou = new ogloszenia_uzytkownika($this, $id);
    	$ou->pobierz($id);
    	
    	return $ou;
    }
	
	/**
	 * @brief pobieranie modelu ogłoszeń kategorii
	 *  
	 *  Działa podobnie jak ogloszeniaUzytkownika, ale zamiast ogłoszeń użytkownika
	 *  pobiera ogłoszenia wybranej kategorii.
	 * 
	 *  @see ogloszeniaUzytkownika
	 *  @see ogloszenia_kategorii
	 * 
     *	@param $id id kategorii której ogłoszenia będą pobrane
     *  @return obiekt simpleXML zawierający zbiór ogłoszeń 
	 **/
    public function ogloszeniaKategorii($id)
    {
    	$ok = new ogloszenia_kategorii($this, $id);
    	$ok->pobierz($id);
    	return $ok;
    }
    
    /**
     * @brief pobieranie modelu kategorii
     * 
     * Model kategorii umożliwia pobieranie danych o kategorii, zarówno o pod kategoriach jak i o nad kategorii
     * 
     * @see kategoria
     * 
     * @param $id id kategorii, której opis będzie pobrany
     * @return obiekt simpleXML z opisem kategorii.
     */
    public function kategoria($id)
    {
    	$ok = new kategoria($this, $id);
    	$ok->pobierz($id);
    	return $ok;
    }
    
    /**
     * @brief pobieranie modelu użytkownika
     * 
     * Model użytkownika zawiera dane o użytkownikach. Pobierane są tylko te dane, na które
     * użytkownik zezwolił na swojej stronie domowej.
     * 
     * @see uzytkownik
     * 
     * @param $id id pobieranego użytkownika
     * @return obiekt simpleXML z danymi użytkownika
     * 
     */
    public function uzytkownik($id)
    {
    	$u = new uzytkownik($this, $id);
    	$u->pobierz($id);
    	return $u;
    }    
    
    /**
     * @brief pobieranie opisu kategorii
     * 
     * Model opisu kategorii dostarcza szczegółowych danych o wybranek kategorii, 
     * służy do określania dodatkowych pół opisujących ogłoszenia z tej kategorii.
     * 
     * @see opis_kategorii
     * 
     * @param $id id kategorii do której opis jest pobierany
     * @return obiekt simpleXML 
     */
    public function opisKategorii($id)
    {
    	$ok = new opis_kategorii($this, $id);
    	$ok->pobierz($id);
    	return $ok;
    }
    
    /**
     * @brief poberanie zdjęcia
     * 
     * Model służy do cachowania zdjęć pobranych z serwisu adcentral.pl
     * 
     * @see zdjecie
     * 
     * @param $id id zdjęcia
     */
    public function zdjecie($id)
    {
    	$zd = new zdjecie($this, $id);
    	$zd->pobierz($id);
    }


    /**
     * @brief poberanie filmu
     * 
     * Model służy do cachowania zdjęć pobranych z serwisu adcentral.pl
     * 
     * @see film
     * 
     * @param $id id film
     */
    public function film($id)
    {
    	$mov = new film($this, $id);
    	$mov->pobierz($id);
    }

    
    /**
     * @brief poberanie miniatury
     * 
     * Model służy do cachowania miniatur pobranych z serwisu adcentral.pl
     * 
     * @see miniatura
     * 
     * @param $id id miniatury
     * @return obiekt modelu miniatury z którego można odczytać url lokalny pobranego pliku 
     */
    public function miniatura($id)
    {
    	$m = new miniatura($this, $id);
    	$m->pobierz($id);
    	
    }
    
    /**
     * @brief getter adresu serwera adcentral
     * 
     * Pobrany adres url jest używany to tworzenia linków do widoków na serwerze adcentral
     * 
     * @return url serwera adcentral
     */
    public function getSerwerUrl()
    {
    	return $this->config->fetcher['serwer'].'/';
    }
    
    /**
     * @brief opcje konfiguracyjne do modelu
     * 
     * Metoda zwraca tablice z opcjami modelu o podanej nazwie
     * 
     * @param $model nazwa modelu
     * @return tablica z konfigiem modelu
     */
    public function opcjeModelu($model)
    {
    	return $this->config->model[$model];
    }
    
    /**
     * @brief pobiera backend do zachowywania trwałości danych
     * 
     * Obiekt backendu zapisuje raz pobrane obiekty z serwisu adcentral, dzięki czemu cały system działa na
     * lokalnych danych aktualizowanych co ustawiony w configu czas.
     * 
     * @see backend
     * @see fileBackend
     * 
     * @return obiekt backednu
     */
    public function pobierzBackend()
    {
    	if($this->backend==null)
    	{
    		$klasa = $this->config->backend['klasa'].'Backend';
    		require_once($klasa.'.php');
    		$this->backend = new $klasa($this->config->backend);
    	}
    	return $this->backend;
    }
    
    /**
     * @brief uaktywnienie kontrolera
     * 
     * Główna metoda kontrolera, dzieki niej za pomocą parametrów odczytanych w $_GET oraz mappera ulr na model,
     * pobierana są dane wybranego modelu a następnie przekazywane do szablonu przyporządkowanego do tego widoku.
     * 
     * @return wyrenderowana strona
     */
    public function pokarz()
    {
    	foreach($this->config->kontroler as $nazwa=>$get_nazwa)
    	{
    		if(is_string($get_nazwa) && array_key_exists($get_nazwa, $_GET))
    		{
    			$metoda = $this->url_mapper[$nazwa];
    			if(!$metoda)    
    				throw new Exception("W kontrolerze nie okreslono url_mappera do widoków modelu $nazwa");			
    			$dane =  $this->$metoda( $_GET[$get_nazwa]);
    			if($dane)
    			{
	    			$template = new template($this->config);
	    			return $template->renderuj($nazwa, $dane);
    			}
    		}
    	}
    }
}

/**
 * @brief Klasa do przechowywania configa
 * 
 * Dzięki tej klasie można zdefiniować ustawienia początkowe
 * Parametrem konstruktora jest tablica nadpisująca ustawienia.
 * 
 * Config jest tablicą asocjacyjną podzieloną na kilka głównych kategorii:
 * <ul>
 * <li>backend -- opcje przesyłane do backenda czyli tablica:</li>
 * 		<ul>
 * 		<li>klasa -- nazwa klasy używanej jako backend</li>
 * 		<li>sciezka -- dla backendu plik, ścierzka w której będą przechowywane dane</li>
 * 		</ul>
 * <li>model -- opcje przesyłana do klas modelu. Jest tablicą asocjacyjną postaci 'nazwa_modelu'=>opcje modelu, gdzie opcje mogą być następujące:</li>
 * 		<ul>
 * 		<li>url -- url widoku xml na serwerze adcentral</li>
 * 		<li>waznosc -- dlugość życia lokalnego rekordu w sekundach (domyślnie 1 godzina == 3600 sekund)</li>
 * 		</ul>
 * <li>kontroler -- opcje przesyłane do kontrolera, informuje o linkach pod jakimi znajdują się widoki modeli. 
 * Jest tablicą asocjacyjną postaci 'nazwa_modelu'=>'link', 
 * żeby poinformować kontroler że parametr ,,ogloszenie_id'' ma wyświetlać ogłoszenie należy kluczowi ,,ogloszenie''
 * przydzielić wartość ,,ogloszenie_id'' wtedy zapytanie ,,?ogloszenie_id=123'' spowoduje wyrenderowanie ogloszenia\
 * o id 123.</li>
 * <li>template -- opcje przesyłane do silnika templatów, opcje te są tablicą w której klucz ,,sciezka'' wskazuje 
 * na ścieżkę z templatami. Dla każdego modelu template domyślnie posiada nazwę taką jak ten model, aby zmienić to zachowanie należy 
 * ustawić parametr ,,pliki'' na tablice asocjacyjną postaci ,,nazwa_modelu''=>,,nazwa_templatu''.
 * 
 * Ustawienie: 
 * $config->template['pliki']['ogloszenie'] = 'moj_tmpl_ogloszenia' spowoduje używanie templatu o nazwie 
 * moj_tmpl_ogloszenia do renderowania widoku ogłoszenia.
 * </li>
 * <li>bazowy_url -- url pliku w którym znajduje się kontroler, umożliwia tworzenie linków do lokalnych widoków</li> 
 * <li>fetcher ustawienia dla modułu pobierania danych z serwera adcentral, składają się z trzech opcji:</li>
 * 	<ul>
 * 		<li>serwer -- nazwa serwera, z którego pobierana będą ogłoszenia</li>
 * 		<li>login -- login użytkownika na serwerze adcentral</li>
 * 		<li>haslo -- hasło użytkownika na serwerze adcentral</li>
 *  </ul>
 *  
 * </ul>
 */
class config
{
	public function __construct($config=null)
	{
		$this->data = array();
		$this->data['wersja'] = '1.02osc';
		$this->data['backend'] = array();
		$this->data['backend']['klasa'] = 'plik';
		$this->data['backend']['sciezka'] = 'dane/';
		
		
		$this->data['model']['kategoria']['url'] = 'kategoria/';
		$this->data['model']['kategoria']['waznosc'] = 3600;

		$this->data['model']['opis_kategorii']['url'] = 'opis_kategorii/';
		$this->data['model']['opis_kategorii']['waznosc'] = 3600;
		
		$this->data['model']['uzytkownik']['url'] = 'uzytkownik/';
		$this->data['model']['uzytkownik']['waznosc'] = 3600;
		
		$this->data['kontroler'] = array();
		
		$this->data['fetcher'] = array();
		$this->data['fetcher']['login'] = '';
		$this->data['fetcher']['haslo'] = '';
		$this->data['fetcher']['serwer'] = 'adcentral.pl';
		
		
		$this->data['bazowy_url'] = '';
		
		
		if($config)
		foreach($config as $klucz=>$wartosc)
			if(is_array($wartosc) and is_array($this->data[$klucz]))
				$this->data[$klucz]= array_merge($this->data[$klucz], $wartosc);
			else
				$this->data[$klucz] = $wartosc;
	}
	
	public function __get($name)
	{
		if(array_key_exists($name, $this->data))
			return $this->data[$name];
		else
			return null;
	}
}


?>
