Hello!
This is my first tutorial actually. I'm not really even sure if I'm qualified to write tutorials, as I'm still learning PHP. But I think it will be a nice way for me to improove my PHP learning process, by explaining what I've done.
So in this tutorial, we will create a gallery class, and also a template class that will work together with the gallery class.
This is the structure of the files:
| -> index.php
|
| ->
includes
|
| - -> config.php
|
| - ->
classes
|
| - - -> gallery.php
|
| - - -> template.php
|
| - ->
templates
|
| - - -> index.tpl
|
| - - -> gallery.tpl
|
| - - -> view.tpl
|
| - - -> desc.xml
|
| ->
img
|
| - -> folder.gif
|
| ->
images
|
| - ->
example folder 1
|
| - - -> 0.jpg
|
| - - -> 1.jpg
|
| - - -> 2.jpg
|
| - - -> 3.jpg
|
| - ->
example folder 2
|
| - - -> 0.jpg
|
| - - -> 1.jpg
|
| - - -> 2.jpg
|
| - - -> 3.jpg
So let's start!
gallery.php
Located in /includes/classes/gallery.php
php Code:
class gallery
{ // The total of everything. private
$totalPages;
private
$totalPics;
private
$maxColumns;
private
$maxHeight;
private
$maxWidth;
// The current value of everything. private
$currentPicture;
private
$currentFolder;
private
$currentPage;
private
$currentPath;
private
$currentFolderPath;
private
$currentColumn =
1;
private
$currentSpan;
private
$currentFormat;
private
$currentXML;
private
$currentIndex;
// Arrays of available files. private
$folders =
array();
// How many images shown per page in the gallery; set in config.php. private
$imgPerPage;
// The first of everything private
$firstImage;
private
$firstPage =
1;
I think this should be pretty self-explenatory.
This is just basic variables that are needed.
php Code:
public
function __construct
($path) { if($handle = @
opendir($path)) { $this->
currentPath =
$path;
closedir($handle);
} else { die('Could not open the image path '.
$path.
' <br />Please check your settings in the config.php');
} }
This is the initializing function, that is required when you create the gallery object. What it does, is that it checks if it's able to open the image directory. If it can open it, it sets the currentpath variable to that value. If it can't open it, it dies, and echoes out that it can't open the directory.
php Code:
public function setImagesPerPage($imgPerPage) {
$this->imgPerPage = $imgPerPage;
}
public function setIndex($index) {
$this->currentIndex = $index;
}
public function setMaxCol($max) {
$this->maxColumns = $max;
}
public function setSpan($span) {
$this->currentSpan = $span;
}
public function setFormat($format) {
$this->currentFormat = $format;
}
public function setXML($xml) {
$this->currentXML = $xml;
}
public function setMaxWidth($width) {
$this->maxWidth = $width;
}
public function setMaxHeight($height) {
$this->maxHeight = $height;
}
These are just basic functions that sets the value of some variables.
I wrote this script before I read about __call, so obviously, you can make this ALOT nicer and less code, by making a __call function for this.
I might edit that later after I've written the tutorial, maybe ;)
php Code:
// Fetches the current value of $_GET['folder'] and sets the currentFolder to it.
public function getFolder() {
$folder = $_GET['folder'];
if($folder != "." && $folder != "..") {
$this->currentFolder = $folder;
}
}
This function gets the value of the ?folder=VALUE in the URL.
Ofcourse, the folder shouldn't be . or .., so we take those out.
Now after reading more PHP tutorials, I've kind of realized that this isn't very safe either as they can still go up one directory and then go into another folder. So maybe you can come up with a nice preg_match function in this code piece, to take out all the dots if there exists.
php Code:
// Fetches the current value of $_GET['page'] and sets the currentPage to it. public
function getPage
() { $page =
$_GET[
'page'];
if (isset($page) &&
is_numeric($page)) { $this->
currentPage =
$page;
} else { $this->
currentPage =
1;
} }
Same as the function above, only that this checks for the current page.
We now also have to check the value of the pic, by doing this:
php Code:
// Fetches the current value of $_GET['pic'] and sets the currentPicture to it. public
function getPicture
() { $pic =
$_GET[
'pic'];
if(is_numeric($pic)) { $this->
currentPicture =
$pic;
} }
php Code:
// Scans through the current image path, set in config.php, for folders. // If the folder set in $_GET['folder'] exists in the directory, the currentFolderPath is set to a value. Returns true or false. public
function setPicFolder
() { $folders = scandir
($this->
currentPath);
foreach($folders as $folder) { if($folder !=
"..") { $this->
folders[] =
$folder;
} } $folderkey =
array_search($this->
currentFolder,
$this->
folders);
if($folderkey) { $this->
currentFolderPath =
$this->
currentPath.
'/'.
$this->
folders[
$folderkey].
'/';
return true;
} else { return false;
} }
The first thing this function does, is scanning through the path that was needed when creating the gallery object.
php Code:
$folders = scandir($this->currentPath);
The $folders will then be an array, so we foreach that array.
If the folder in the current loop, is called "..", we don't include it.
If it's anything else than "..", we put the name of that folder in the array $this->folders.
After we've scanned through the directory, we do an array search.
We search for $this->currentFolder (set in the $_GET['folder']), in the array $this->folders.
If it finds it, we can set the currentFolderPath to
php Code:
$this->currentFolderPath = $this->currentPath.'/'.$this->folders[$folderkey].'/';
This means, that if we're at ?folder=testing, the script would check in the folder /theimgpath/testing/ for images.
The next function gets the total amount of pictures in the currentFolderPath:
php Code:
// Gets the total amount of pictures in the current folder. public
function getTotalPics
() { if ($handle =
opendir($this->
currentFolderPath)) { while (false !==
($file =
readdir($handle))) { if ($file !=
"." &&
$file !=
"..") { $this->
totalPics++;
} } closedir($handle);
} }
This function opens the directory of the folder specified in ?folder=
Then it checks if false is not the same type as $file, if $file = readdir
readdir reads through the directory, and loops through all of the files in it.
If the file isn't called "." or "..", the variable $this->totalPics gets 1 value added to it.
After the loop looped through all files, $this->totalPics would then contain the amount of all the pictures in the current folder.
Now, I hope you're as smart as I am with maths(I'm just joking, I'm not very good >.< ), because there will be alot of maths from now on.
php Code:
// Gets the total amount of pages based on totalPics and imgPerPage. public
function getTotalPages
() { $totalPages =
$this->
totalPics /
$this->
imgPerPage;
$this->
totalPages =
ceil($totalPages);
}
I think this is pretty straight forward.
The total amount of pictures, is devided with how many images are allowed per page. We then get the amount of pages. But in order not to have like 11,6 pages.. we ceil it, meaning, round it up. So it would then be 12 pages instead of 11,6.
We then set the $this->totalPages to the value of the total pages.
php Code:
// Gets the first image on whatever page the user is currently viewing.
public function getFirstImage() {
$this->firstImage = (($this->currentPage * $this->imgPerPage) - $this->imgPerPage);
}
This function, gets the first image, of the current page.
So, let's say we have 10 images per page.
On page 1, it would show the first 10 images.
On page 2, it would show up to the (2 * 10)th image.
With me so far?
Page 1: 0-9
Page 2: ?-19
Now, we can pretty easy realize that the first image should be 10, on page 2. But in order for the script to get it, we need to subtract $imgPerPage from (2 * 10), leaving us with:
(2 * 10) - 10 = 20 - 10 = 10
Wow, even I didn't get my own explenation. But I hope you get it anyhow!
Because we're moving on!!
The next function isn't really the best coded function, but it gets the work done that it's supposed to!
php Code:
// Prints out a list of available folders. public
function printFolders
() { $folders =
'
<img src="img/folder.gif" /> <a href="'.
$this->
currentIndex.
'">Index</a><br />
';
foreach($this->
folders as $folder) { if($folder !=
"." &&
$folder !=
"..") { $totalPics =
0;
if ($handle =
opendir($this->
currentPath .
$folder .
'/')) { while (false !==
($file =
readdir($handle))) { if ($file !=
"." &&
$file !=
"..") { $totalPics++;
} } closedir($handle);
} $folders .=
'
<img src="img/folder.gif" /> <a href="' .
$_SERVER[
'PHPSELF'] .
'?folder=' .
$folder .
'">' .
$folder.
'</a> ('.
$totalPics.
')<br />
';
} } return $folders;
}
It loops through the array $this->folders, and checks how many pics in each folder.
Then it just makes a nice link, with a folder image. The rest of the function is pretty self-explenatory, messy, but easy to understand.
php Code:
public
function getFolders
() { $count =
count($this->
folders);
if($count ==
1) { $msg =
'There are no folders in the gallery yet!';
} return $msg;
}
Pretty basic. It counts the array $this->folders, and if the count returns only 1, then it's no folders in the gallery.
Returns that message.
The next function, is getting the page links. This is REALLY hard to explain. I don't even know how to begin.
The function itself is also very long. I'll take it in parts.
Here is the whole function:
php Code:
// Prints out the links to the pages in the current folder.
public function printPageLinks() {
if($this->totalPics > 1) {
if(($this->currentPage - ($this->currentSpan-1)) > $this->firstPage) {
$links = '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$this->firstPage.'">
<< '.$this->firstPage.'</a> .. ';
}
// Prints a list of available pages
for ($i = ($this->currentPage-($this->currentSpan-1)); $i <= ($this->currentPage+($this->currentSpan-1)); $i++) {
// If it's not too low, and not too high
if (($i >= $this->firstPage) && ($i <= $this->totalPages)) {
// Show it
$links .= '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$i.'">';
$links .= ($i == $this->currentPage) ? ("<b>" .$i . "</b>") : $i ;
$links .= '</a> ';
}
}
if(($this->currentPage + ($this->currentSpan-1)) < $this->totalPages) {
$links .= ' .. <a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$this->totalPages.'">
'.$this->totalPages.' >></a>';
}
$links .= '<br /><br />';
// Back page link
if($this->currentPage > 1) {
$links .= '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page=' .($this->currentPage-1). '">
Previous Page</a> ';
}
// Next page link
if($this->currentPage+1 <= $this->totalPages) {
$links .= ' <a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page=' .($this->currentPage+1). '">
Next page</a>';
}
$links .= '<br />';
}
else {
$links .= 'There are no images in this folder yet!';
}
return $links;
}
php Code:
public function printPageLinks() {
if($this->totalPics > 1) {
if(($this->currentPage - ($this->currentSpan-1)) > $this->firstPage) {
$links = '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$this->firstPage.'">
<< '.$this->firstPage.'</a> .. ';
}
It first checks if the totalPics is more than one, because otherwise there's no pictures in that folder.
Then it checks if the current page, minus (current span - 1), is larger than the firstpage.
The firstpage, is always 1.
If the currentpage, is 5, and the span is set to 3.
It will then check if 5 - (3 - 1 = 2) > 1 and that is simplified like the following:
5 - 2 = 3
if 3 > 1, which it is, it will print a link to the first page.
So even if you're at page 10, and the span is set to 3:
7 8 9 10 11 12 13
It will show a link to the first page:
<< 1 .. 7 8 9 10 11 12 13
Jesus, how will this tutorial continue... :confused::confused: Hard to explain maths :S
Anyways.
php Code:
// Prints a list of available pages
for ($i = ($this->currentPage-($this->currentSpan-1)); $i <= ($this->currentPage+($this->currentSpan-1)); $i++) {
// If it's not too low, and not too high
if (($i >= $this->firstPage) && ($i <= $this->totalPages)) {
// Show it
$links .= '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$i.'">';
$links .= ($i == $this->currentPage) ? ("<b>" .$i . "</b>") : $i ;
$links .= '</a> ';
}
}
This piece prints out a list of all available pages in the current folder.
php Code:
$i = ($this->currentPage-($this->currentSpan-1))
In the beginning of the for loop. we set the initializer to the current page, minus (span - 1).
And the loop will run, as long as
php Code:
$i <= ($this->currentPage+($this->currentSpan-1))
$i is less, or equal to the currentpage + (span - 1).
And at the end of each loop, we add 1 to $i.
php Code:
if (($i >= $this->firstPage) && ($i <= $this->totalPages)) {
If $i is higher, or equal to the firstpage, and if $i is less or equal to the totalpage(lastpage), it will do this:
php Code:
$links .= '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$i.'">';
A basic link, but this is the key part about it:
php Code:
$links .= ($i == $this->currentPage) ? ("<b>" .$i . "</b>") : $i ;
It runs an if statement, and checks if $i is equal to the current page. If it is, the text of the link, will be in bold. Otherwise, it will just be the number.
The last line in the loop I don't think I have to explain. It just closes the link.
php Code:
if(($this->currentPage + ($this->currentSpan-1)) < $this->totalPages) {
$links .= ' .. <a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page='.$this->totalPages.'">
'.$this->totalPages.' >></a>';
}
This is the same as the "first page" check, but this is the "last page" check.
if the span is set to 3, and we're on page 1 of 20.
It will echo:
1 2 3 4 .. 20 >>
And if we're at the page 10, as the previous example:
It will echo: << 1 .. 7 8 9
10 11 12 13 .. 20 >>
Pretty neat huh? :D
Next thing, we just echo out some basic breaklines, and then this:
php Code:
// Back page link
if($this->currentPage > 1) {
$links .= '<a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page=' .($this->currentPage-1). '">
Previous Page</a> ';
}
If the currentpage is higher than 1, it will echo out a "Previous Page" link.
So the number link menu, is more if you wanna jump several pages at the time. And the "previous page" link will be for those who wanna scan through all the pages.
php Code:
// Next page link
if($this->currentPage+1 <= $this->totalPages) {
$links .= ' <a href="'.$_SERVER['PHPSELF'].'?folder='.$this->currentFolder.'&page=' .($this->currentPage+1). '">
Next Page</a>';
}
Same as the previous code piece. Only that this checks if the next page is less or equal to the last page. It will then echo out "Next page".
Whoa! That was one long function. And messy. But hopefully, you'll just grasp the idea of this class, and will probably come up with your own solutions for some of the things here!
The next function, prints out the actual images in the current folder.
This function really deserves a whole topic of its own, because it's so much code!! :eek:
php Code:
// Prints out the images on the current page in the current folder. public
function printImages
() { $images =
'<table border="1" cellpadding="5"><tr>';
for($i =
$this->
firstImage;
$i <
($this->
firstImage +
$this->
imgPerPage);
$i++
) { if (file_exists($this->
currentFolderPath .
$i .
$this->
currentFormat)) { if($this->
currentColumn >=
$this->
maxColumns) { $xmlstring = simplexml_load_string
(file_get_contents($this->
currentXML));;
foreach($xmlstring as $folder =>
$pic) { if($pic[
'folder'] ==
$this->
currentFolder) { if($pic[
'id'] ==
$i) { $title =
$pic[
'title'];
} } } $image =
$this->
currentFolderPath .
$i .
$this->
currentFormat;
$images .=
'<td><a href="'.
$_SERVER[
'PHPSELF'].
'?folder='.
$this->
currentFolder.
'&page='.
$this->
currentPage.
'
&pic='.
$i.
'" border="0" title="'.
$title.
'"><img src="'.
$image.
'" height="'.
$this->
maxHeight.
'" border="0" /></a></td></tr><tr>';
$this->
currentColumn =
1;
} else { $xmlstring = simplexml_load_string
(file_get_contents($this->
currentXML));;
foreach($xmlstring as $folder =>
$pic) { if($pic[
'folder'] ==
$this->
currentFolder) { if($pic[
'id'] ==
$i) { $title =
$pic[
'title'];
} } } $image =
$this->
currentFolderPath .
$i .
$this->
currentFormat;
$images .=
'<td><a href="'.
$_SERVER[
'PHPSELF'].
'?folder='.
$this->
currentFolder.
'&page='.
$this->
currentPage.
'
&pic='.
$i.
'" border="0" title="'.
$title.
'"><img src="'.
$image.
'" height="'.
$this->
maxHeight.
'" border="0" /></a></td>';
$this->
currentColumn++;
} } } $images .=
'</tr></table>';
return $images;
}
Okey!, so let's try to explain this major HUGE function. Messy.. but still gets the work done ;) lol..
php Code:
for($i = $this->firstImage; $i < ($this->firstImage + $this->imgPerPage); $i++) {
A basic for loop. Sets $i to the first image on the current page.
And as long as $i is less then the first image + imgPerPage, it should do the loop.
And at the end of each loop, it should add 1 to $i.
php Code:
if (file_exists($this->
currentFolderPath .
$i .
$this->
currentFormat)) {
If the file exists in the folderPath, example:
images/testing/2.jpg
php Code:
if($this->currentColumn >= $this->maxColumns) {
If the current column is larger, or equal to the max columns allowed.
php Code:
$xmlstring = simplexml_load_string
(file_get_contents($this->
currentXML));;
foreach($xmlstring as $folder =>
$pic) {