Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: PHP: Sivuttaja-luokka

JayJayKing [13.10.2009 16:20:10]

#

Pager-sovellus sisältää työkalut elementtien sivutuksessa tarvittavien tietojen tuottamiseen ja hakemiseen. Pager noudattaa seuraavanlaista rakennetta:

./
Pager.php
lib/exceptions/InvalidParameterException.php
lib/exceptions/VariableNotSetException.php
examples/callback_array_example.php

Esimerkki on tehty array-tietovarastona ja se toimii sellaisenaan asianmukaisella palvelimella.

Toivottavasti tästä on jollekin iloa! :-)

Pager.php

<?php

	require_once("lib/exceptions/InvalidParameterException.php");
	require_once("lib/exceptions/VariableNotSetException.php");

	/**
	 * Luokka sisältää työkalut elementtien sivutuksessa tarvittavien tietojen
	 * tuottamiseen ja hakemiseen.
	 *
	 * @see Konstruktori heittää InvalidParameterException, jos parametreja ei
	 * anneta.
	 *
	 * @author JayJayKing
	 */
	class Pager {

		private $itemsTotal;
		private $itemsPerPage;
		private $perPage;
		private $pagesTotal;
		private $currentPage;
		private $startPos;
		private $endPos;
		private $pageRange;
		private $firstPage;
		private $lastPage;

		/**
		 * Konstruktori ottaa kolme parametria ja asettaa ne luokkaan sekä
		 * laskee tarvittavien sivujen kokonaismäärän. Lisäksi konstruktori
		 * laskee ja asettaa sivun ensimmäisen ja viimeisen viestin sijainnin
		 * (indeksin) tietokannan taulussa, array'ssa tms.
		 *
		 * @param $iTotal int Sivutettavien elementtien kokonaismäärä
		 * @param $iPerPage int Sivutetavien elementtien haluttu määrä yhdellä
		 * sivulla
		 * @param $currentPage int Nykyisen sivun numero
		 *
		 * @see Throws InvalidParameterException Jos parametreja ei anneta.
		 */
		public function Pager($iTotal, $iPerPage, $currentPage) {

			if(!$iTotal || !$iPerPage || !$currentPage || !is_numeric($iTotal) || !is_numeric($iPerPage) || !is_numeric($currentPage)) {

				throw new InvalidParameterException("Anna kaikki parametrit int iTotal, int iPerPage ja int currentPage.");

			}

			$this->itemsTotal = $iTotal;
			$this->pagesTotal = ceil($iTotal / $iPerPage);
			$this->setCurrentPage($currentPage, $this->getPagesTotal());
			$this->perPage = $iPerPage;
			$this->setItemsPerPage($iPerPage);
			$this->startPos = $this->perPage * ($this->currentPage - 1);
			$this->endPos = $this->startPos + $this->perPage - 1;

			if($this->endPos >= $this->itemsTotal) {

				$this->endPos = $this->itemsTotal - 1;

			}

		}

		/**
		 * Asettaa nykyisen sivun ja jos parametrina annettu nykyinen sivu ylittää
		 * sivujen kokonaismäärän, asetetaan nykyiseksi sivuksi sivujen
		 * kokonaismäärä.
		 *
		 * @param int $currentPage Nykyinen sivu
		 * @param int $pagesTotal Sivujen kokonaismäärä
		 * @see Throws InvalidParameterException Jos parametreja ei anneta.
		 */
		private function setCurrentPage($currentPage, $pagesTotal) {

			if($currentPage > $pagesTotal) {

				$this->currentPage = $pagesTotal;

			} else if($currentPage < 1) {

				$this->currentPage = 1;

			}else {

				$this->currentPage = $currentPage;
			}

		}

		/**
		 * Palauttaa nykyisen sivun. Arvo asetetaan ja tarkastetaan
		 * konstruktorissa, joten tarkastaminen ei ole tässä tarpeellista.
		 *
		 * @return int Nykyinen sivu
		 */
		public function getCurrentPage() {

			return $this->currentPage;

		}

		/**
		 * Asettaa parametrina saamansa arvon luokkaan ja jos nykyinen sivu on
		 * viimeinen ja itemit eivät mene sillä tasan, asetetaan arvoksi
		 * viimeiselle sivulle jäävien itemien määrä.
		 *
		 * Parametriksi annetun
		 * muuttujan olemassaolo tarkastetaan jo aiemmin, joten tässä
		 * tarkastaminen ei ole tarpeellista.
		 *
		 * @param int $itemsPerPage Haluttu yhdellä sivulla olevien itemien
		 * määrä
		 */
		private function setItemsPerPage($itemsPerPage) {

			if($this->currentPage == $this->pagesTotal && $this->perPage > 0) {

				$this->itemsPerPage = $this->itemsTotal - $this->perPage * ($this->pagesTotal - 1);

			} else {

				$this->itemsPerPage = $itemsPerPage;

			}

		}

		/**
		 * Palauttaa sivutettavien elementtien halutun määrän per sivu.
		 *
		 * Arvo asetetaan ja tarkastetaan konstruktorissa, joten tarkastaminen
		 * ei ole tässä tarpeellista.
		 *
		 * @return int Sivutettavien elementtien haluttu määrä per sivu
		 */
		public function getItemsPerPage() {

			return $this->itemsPerPage;

		}

		/**
		 * Palauttaa sivutettavien elementtien kokonaismäärän.
		 *
		 * Arvo asetetaan ja tarkastetaan konstruktorissa, joten tarkastaminen
		 * ei ole tässä tarpeellista.
		 *
		 * @return int Sivutettavien elementtien kokonaismäärä.
		 */
		public function getItemsTotal() {

			return $this->itemsTotal;

		}

		/**
		 * Palauttaa tarvittavien sivujen kokonaismäärän.
		 *
		 * Arvo asetetaan ja tarkastetaan konstruktorissa, joten arvon
		 * olemassaoloa ei ole tarvetta tarkastaa tässä.
		 *
		 * @return int Tarvittavien sivujen kokonaismäärä.
		 */
		public function getPagesTotal() {

			return $this->pagesTotal;

		}

		/**
		 * Palauttaa sivun ensimmäisen viestin sijainnin(indeksi) esim.
		 * tietokannan taulussa.
		 *
		 * Arvo asetetaan ja tarkastetaan konstruktorissa, joten tarkastaminen
		 * ei ole tässä tarpeellista.
		 *
		 * @return int Sivun ensimmäisen viestin sijainti tietokannan taulussa.
		 */
		public function getStartPos() {

			return $this->startPos;

		}

		/**
		 * Palauttaa sivun viimeisen viestin sijainnin(indeksin) esim.
		 * tietokannan taulussa.
		 *
		 * Arvo asetetaan ja tarkastetaan konstruktorissa, joten tarkastaminen
		 * ei ole tässä tarpeellista.
		 *
		 * @return int Sivun viimeisen viestin sijainti tietokannana taulussa
		 */
		public function getEndPos() {

			return $this->endPos;

		}

		/**
		 * Palauttaa true, jos nykyinen sivu on ensimmäinen sivu ja false jollei.
		 *
		 * @return boolean True, jos nykyinen sivu on ensimmäinen sivu ja false
		 * jollei.
		 */
		public function isFirstPage() {

			if($this->currentPage == 1) {

				return true;

			}

			return false;

		}

		/**
		 * Palauttaa true, jos nykyinen sivu on viimeinen sivu ja false jollei.
		 *
		 * @return boolean True, jos nykyinen sivu on viimeinen sivu ja false
		 * jollei.
		 */
		public function isLastPage() {

			if($this->currentPage == $this->pagesTotal) {

				return true;

			}

			return false;

		}

		/**
		 * Asettaa lukualueen määrittävän luvun luokkaan ja lukualue = nykyinen
		 * sivu +/- lukualue.
		 *
		 * @param int $range Lukualueen(range) määrittävä luku.
		 *
		 * @see Throws InvalidParameterException Jos parametria ei anneta.
		 * @see Esimerkki lukualueesta: Nykyinen sivu=3 ja lukualue=1, niin
		 * lukualue käsittää sivut 2, 3 ja 4.
		 *
		 * Lisäksi funktio asettaa luokkaan lukualueen sen
		 * hetkisen ensimmäisen ja viimeisen sivun numeron ja jakaa yli jäävän
		 * lukualueen toiselle ääripäälle, jos lukualueella ei ole tarpeeksi
		 * sivuja.
		 * Siis jos nykyinen sivu = 1, pageRange = 2, niin viimeisen sivun
		 * numero on silloin 5 koska lastPageInRange saa myös
		 * firstPageInRangelta yli jäävän lukualueen 2 kokonaisuudessaan.
		 */
		public function setPageRange($range) {

			if(!$range || !is_numeric($range)) {

				throw new InvalidParameterException("Anna parametri int range.");

			}

			$this->pageRange = $range;


			switch($this->getCurrentPage()) {

				case ($this->getCurrentPage() - $this->pageRange <= 1 && $this->getPagesTotal() >= $this->pageRange * 2 + 1):
					$this->firstPage = 1;
					$this->lastPage = $this->currentPage + $this->pageRange + (($this->pageRange - $this->currentPage) + 1);
					break;
				case ($this->getCurrentPage() + $this->pageRange >= $this->getPagesTotal() && $this->getPagesTotal() >= $this->pageRange * 2 + 1):
					$this->lastPage = $this->getPagesTotal();
					$this->firstPage = $this->currentPage - $this->pageRange - (($this->currentPage + $this->pageRange) - $this->getPagesTotal());
					break;
				case ($this->getPagesTotal() < $this->pageRange * 2 + 1):
					$this->firstPage = 1;
					$this->lastPage = $this->getPagesTotal();
					break;
				default:
					$this->firstPage = $this->currentPage - $this->pageRange;
					$this->lastPage = $this->currentPage + $this->pageRange;
					break;

			}

		}

		/**
		 * Iteroi lukualueen läpi ja kutsuu käyttäjän määrittämää
		 * Callback-funktiota sekä antaa sille parametriksi sen hetkisen
		 * iteraation sivun numeron.
		 *
		 * @param function Käyttäjän määrittämä funktio, jota kutsutaan
		 * jokaisella iteraatiokerralla ja jolle annetaan parametrina kunkin
		 * iteraation sivun numero.
		 *
		 * @see Throws InvalidParameterException Jos parametria ei anneta tai se ei
		 * ole funktio.
		 */
		public function getPagesInRange($userFunction) {

			if(!function_exists($userFunction)) {

				throw new InvalidParameterException("Määritä parametriksi olemassa oleva funktio.");

			}

			for($i = $this->getFirstInPageRange(); $i <= $this->getLastInPageRange(); $i++) {

				$userFunction($i, $this->getCurrentPage());

			}

		}

		/**
		 * Palauttaa pageRangen(lukualue).
		 *
		 * @return int pageRange
		 *
		 * @see Throws VariableNotSetException Jos funktiota kutsutaan ennen
		 * palautusarvon asettamista.
		 */
		public function getPageRange() {

			if(!$this->pageRange) {

				throw new VariableNotSetException("Sivutusaluetta(pageRange) ei ole vielä asetettu. Käytä setPageRange-funktiota ensin.");

			}

			return $this->pageRange;
		}

		/**
		 * Palauttaa lukualueen ensimmäisen numeron.
		 *
		 * @return int Lukualueen ensimmäinen numero.
		 *
		 * @see Throws VariableNotSetException Jos funktiota kutsutaan ennen
		 * palautusarvon asettamista.
		 */
		public function getFirstInPageRange() {

			if(!$this->firstPage) {

				throw new VariableNotSetException("Ensimmäistä sivua ei ole vielä asetettu. Käytä setPageRange-funktiota ensin.");

			}

			return $this->firstPage;

		}

		/**
		 * Palauttaa lukualueen viimeisen numeron.
		 *
		 * @return int Lukualueen viimeinen numero.
		 *
		 * @see Throws VariableNotSetException Jos funktiota kutsutaan ennen
		 * palautusarvon asettamista.
		 */
		public function getLastInPageRange() {

			if(!$this->lastPage) {

				throw new VariableNotSetException("Viimeistä sivua ei ole vielä asetettu. Käytä setPageRange-funktiota ensin.");

			}

			return $this->lastPage;

		}

	}

?>

lib/exceptions/InvalidParameterException.php

<?php

	class InvalidParameterException extends Exception {
	}

?>

lib/exceptions/VariableNotSetException.php

<?php

	class VariableNotSetException extends Exception {
	}

?>

examples/callback_array_example.php

<?php
	/**
	 * Esimerkki sivuttaa Arrayn sisällön ja tulostaa sen käyttäjän määrittämää
	 * Callback-funktiota apuna käyttäen. Esimerkki toimii sellaisenaan.
	 *
	 * @author JayJayKing
	 */

	require_once("../Pager.php");

	$pager; //Obj Pager
	$itemsTotal = 18; // Sivutettavien elementtien kokonaismäärä
	$itemsPerPage = 3; // Kuinka monta itemiä halutaan per sivu
	$currentPage; // Nykyinen sivu
	$numberArray = array(); // Esimerkin tietolähde
	$pagerRange = 2; // Lukualue, jolla sivulinkkien esitys tapahtuu suhteessa nykyiseen sivuun

	// Asetetaan nykyinen sivu
	if(isset($_GET['sivu'])) {

		$currentPage = $_GET['sivu'];

	} else {

		$currentPage = 1;

	}

	// Täytetään tietolähde luvuilla kunnes itemien kokonaismäärä täyttyy
	for($i = 0; $i < $itemsTotal; $i++) {

		$numberArray[$i] = $i + 1;

	}

	// Luodaan Pager-objekti ja asetetaan sivutuksen lukualue
	try {

		$pager = new Pager($itemsTotal, $itemsPerPage, $currentPage);
		$pager->setPageRange($pagerRange);

	} catch(Exception $e) {

		echo $e;

	}

	// Tulostetaan sivutus
	if($pager->getPagesTotal() > 1) {

		// Tulostetaan ensimmäisen sivun suoralinkki
		tulostaEkaPikalinkki($currentPage);

		// Tulostetaan varsinainen sivutus käyttäjän Callback-funktiota apuna
		// käyttäen.
		try {

			$pager->getPagesInRange('tulostaSivutus');

		} catch(Exception $e) {

			echo $e;

		}

		// Tulostetaan viimeisen sivun suoralinkki
		tulostaVikaPikalinkki($currentPage, $pager->getPagesTotal());

		echo "<br /><br />";
	}


	// Tulostetaan sivulle kuuluvat tiedot
	for($i = $pager->getStartPos(); $i <= $pager->getEndPos(); $i++) {

		echo "Luku: " . $numberArray[$i] . "<br />";

	}

	// Käyttäjän funktio, joka annetaan getPagesInRange-funktiolle parametrina.
	// Tässä tapauksessa tulostetaan sivulinkki ja jos kyseessä on nykyinen sivu
	// tulostetaan se lihavoituna, muttei linkkinä.
	function tulostaSivutus($luku, $nykyinensivu) {

		if($luku == $nykyinensivu) {

			echo "<b> " . $luku . " </b>";
			return;

		}

		echo "<a href='" . $_SERVER['PHP_SELF'] . "?sivu=" . $luku . "'> " . $luku . " </a>";

	}

	// Tulostaa linkin ensimmäiselle sivulle, jos nykyinen sivu ei ole se.
	function tulostaEkaPikalinkki($nykyinenSivu) {

		if($nykyinenSivu != 1) {

			echo "|<a href='" . $_SERVER['PHP_SELF'] . "'><< </a>";
			return;

		}

		echo "|<< ";

	}

	// Tulostaa linkin viimeiselle sivulle, jos nykyinen sivu ei ole se.
	function tulostaVikaPikalinkki($nykyinenSivu, $sivujenKokonaismaara) {

		if($nykyinenSivu != $sivujenKokonaismaara) {

			echo "<a href='" . $_SERVER['PHP_SELF'] . "?sivu=" . $sivujenKokonaismaara . "'> >></a>|";

		} else {

			echo " >>|";

		}

	}

?>

tsuriga [27.10.2009 16:31:20]

#

-public function Pager -> public function __construct
-echo $e -> echo $e->getMessage()
-PHP_SELF -> SCRIPT_NAME
-En nyt tiedä, notta mikä dokumentointityökalu on käytössä, mutta voisin arvata, että @see avainsanaa on ymmärrykseni mukaan käytetty väärin, mm. "@see Throws.."

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta