Help With PHP Pagination Script For Flat File Database - php

I have a few questions regarding a PHP Pagination Script For Flat File Database I found.
I have posted the script below.
<?php
echo '<html><body>';
// Data, normally from a flat file or some other source
$data = "Item1|Item2|Item3|Item4|Item5|Item6|Item7|Item8|Item9|Item10";
// Put our data into an array
$dataArray = explode('|', $data);
// Get the current page
$currentPage = trim($_REQUEST[page]);
// Pagination settings
$perPage = 3;
$numPages = ceil(count($dataArray) / $perPage);
if(!$currentPage || $currentPage > $numPages)
$currentPage = 0;
$start = $currentPage * $perPage;
$end = ($currentPage * $perPage) + $perPage;
// Extract ones we need
foreach($dataArray AS $key => $val)
{
if($key >= $start && $key < $end)
$pagedData[] = $dataArray[$key];
}
foreach($pagedData AS $item)
echo ''. $item .'<br>';
if($currentPage > 0 && $currentPage < $numPages)
echo '« Previous page<br>';
if($numPages > $currentPage && ($currentPage + 1) < $numPages)
echo 'Next page »<br>';
echo '</body></html>';
?>
My first problem seems to be in line 9. I could change the line to:
$currentPage = trim(#$_REQUEST[page]);
But this change won't fix the error, it will just hide it. What needs to be done to line 9 to rid my page of the error?
Secondly, I would like to fetch the data on line 5 in a different way. I would like to get the data from a text file, let's call it "items.txt", that has entries like below, one per line.
Fun
Games
Toys
Sports
Fishing
Pools
Boats
Please recommend alternate code to fetch the desired data.
Lastly, I would like to include links to the "First page" and "Last page" as well as "Previous page" and "Next page", as is the current code.
I apologize for my sloppy posting, but would be real appreciative of anybody who could help me understand the changes needed to produce my desired results. Thanks.....

Problem With Line 9
$_REQUEST[page] has two separate problems.
1) page is being read as the name of a constant because it is not quoted. PHP then notices there is no constant called page, so it takes a guess that you meant the string page -- which it would be if page was quoted -- and triggers an error to notify you. Therefore, use $_REQUEST['page'] instead.
2) 'page' is not necessarily a key of $_REQUEST because the data is not guaranteed to be given. Therefore, you cannot refer to $_REQUEST['page'] before you ensure that it exists. This may be done by isset($_REQUEST['page']).
Your final code should look something like this, then.
if (isset($_REQUEST['page'])) {
$currentPage = $_REQUEST['page'];
} else {
$currentPage = 'some default value';
}
Problem With Data Source
The file() function reads the lines of a file into an array -- for example, the fourth value of the array is also the fourth line in the file. Therefore, you can set $dataArray simply as $dataArray = file('text.dat');.

Related

CodeIgniter Pagination links format

I am using codeigniter's default pagination
< 1 2 3 4 >
but I'd like to make it to this format
< 1-10 11-20 21-30 >
any ideas?
Good Question: You will need to extend code system/CI_Pagination.php library into application/library/MY_Pagination.php
Math Calculation by #Dan is fine, setup into CI Pagination Library, see below
1) Create file into application/library/MY_Pagination.php more info about Create Library
Overwrite create_links() method from custom method, see below
Revised code section in create_links() method
if ($this->cur_page === $loop){
// Current page
$output .= $this->cur_tag_open.($this->cur_page == 1 ? $loop : $loop*($this->per_page)+1).'-'.($loop * $this->per_page).$this->cur_tag_close;
}elseif ($i === $base_page){
// First page
$output .= $this->num_tag_open.'<a href="'.$first_url.'"'.$attributes.$this->_attr_rel('start').'>'
.((($loop)*($this->per_page) - $this->per_page)+1) .'-'. ($loop * $this->per_page).'</a>'
.$this->num_tag_close;
}else{
$append = $this->prefix.$i.$this->suffix;
$output .= $this->num_tag_open.'<a href="'.$base_url.$append.'"'.$attributes.$this->_attr_rel('start').'>'
.((($loop)*($this->per_page) - $this->per_page)+1) .'-'. ($loop * $this->per_page)
.'</a>'.$this->num_tag_close;
}
Full MY_Pagination.php file Line no(577-592) click here
NOTE I have used latest core file so please use you amendment in your current file
Do some simple math to adjust, so for example if $x = 1
Instead of page 1 being $x page 1 is:
<?php echo $x.'-'.($x * 10); ?>
Page 2 and higher is:
<?php
$x++;
echo (($x)*10)-10)+1.'-'.($x * 10);
?>
Where $x++ counts up for each display.

For Loop - Do Something Once Loop Hits Certain Number PHP

I'm working on a project for a real estate website. I have a function that uses a for loop to grab a row of data from the database for each available property. Normally this works perfectly but for this particular site the properties are displayed in rows of three. This means that once I have outputted 3 properties, I need to close the current div and open another div to display the next row of 3 properties. So essentially I need the loop to recognize once it hits three rows, echo something like
</div><div class="new div">
Then pick back up where it left off. My for loop currently looks like this:
function showFeaturedHomes() {
$fetcher = $this->startDataFetch();
for ($idx = 0; $idx < 30; $idx++)
{
$row = $fetcher->fetch_assoc();
if (!$row)
break;
$retVal .= $this->showBlock($row);
}
return ($retVal);
I've tried using the modulus operator(%) to detect once it hits a multiple of 3 and while it seems like it works, it's outputting the closing and opening divs BEFORE it does anything else, so I still end up in the same situation.
I hope I've been clear enough about what I'm trying to do, but if not please feel free to ask me for more info. Your help is very much appreciated! Thanks!
function showFeaturedHomes() {
echo '<div class="new div">'; // !!!
$fetcher = $this->startDataFetch();
for ($idx = 0; $idx < 30; $idx++)
{
if ($idx != 0 && $idx % 3 == 0) echo '</div><div class="new div">'; // !!!
$row = $fetcher->fetch_assoc();
if (!$row)
break;
$retVal .= $this->showBlock($row);
}
echo '</div>'; // !!!
return ($retVal);
}
I dont know if you are returning values through echo and what does showBlock do, but the idea is clear here :). You were close with modulo! Best regards!

divide xml into chunks based on url in php

I have a robots.txt file
in that i generate dynamic sitemap links.
I get the following links if i run the robots.txt file in the browser.
Here you get 5 sitemap links for each language.
Reason: there are 10 products in database.
i want to show only two products per link. so i divided the total no.of products with no.of products on one page.
Sitemap:http://demo.com/pub/sitemap_products.php?page=1&lang=it_IT
the part in bold is dynamic.
code in: sitemap_products.php
$Qproduct : returns an array of all the products in the db for all the languages.
So the bellow loop generates an xml having links of the products for the language in the sitemap url
for eg.
if the link is
Sitemap:http://demo.com/pub/sitemap_products.php?page=1&lang=it_IT
it will generate all the products present in IT language.
The xml links that are generated now are based on languages that we get from url.
but i want to divide them into chunks of 2 product's xml per sitemap link.
while($Qproduct->next())
{
if(!isset($page_language[$Qproduct->valueInt('language_id')]))
{
$page_language[$Qproduct->valueInt('language_id')] = mxp_get_page_language($MxpLanguage->getCode($Qproduct->valueInt('language_id')), 'products');
}
if($Qproduct->valueInt('language_id') == $QproductLang->valueInt('languages_id'))
{
$string_to_out .= '<url>
<loc>' . href_link($page_language[$Qproduct->valueInt('language_id')], $Qproduct->value('keyword'), 'NONSSL', false) . '</loc>
<changefreq>weekly</changefreq>
<priority>1</priority>
</url>';
}
}
what i wish to do is apply a condition so that it gives me exactly two products links in xml when page=1(see in the sitemap links) instead of all the 10 products link in xml.
similarly if page=2 it should display next 2 products. and so on.
I am a bit confused in the condition that i am supposed to apply.
Please help me out.
First of all, use an XML library to create the XML, not string concatenation. Example:
$loc = href_link($page_language[$Qproduct->valueInt('language_id')], $Qproduct->value('keyword'), 'NONSSL', false);
$url = new SimpleXMLElement('<url/>');
$url->loc = $loc;
$url->changefreq = 'weekly';
$url->priority = 1;
In your case, you can even easily wrap that into a function that just returns such an element and which has two parameters: $Qproduct and $page_language (as string, not array (!)).
But that's just some additional advice, because the main point you ask about is the looping and more specifically the filtering and navigating inside the loop to the elements you're interested in.
First of all you operate on all results by looping over them:
while ($Qproduct->next())
{
...
}
Then you say, that you're only interested in links of a specific language:
while ($Qproduct->next())
{
$condition = $Qproduct->valueInt('language_id') == $QproductLang->valueInt('languages_id');
if (!$condition) {
continue;
}
...
}
This already filters out all elements not interested in. What is left to keep track and decide which elements to take:
$page = 1;
$start = ($page - 1) * 2;
$end = $page * 2 - 1;
$count = 0;
while ($Qproduct->next())
{
$condition = $Qproduct->valueInt('language_id') == $QproductLang->valueInt('languages_id');
if (!$condition) {
continue;
}
$count++;
if ($count < $start) {
continue;
}
...
if ($count >= $end) {
break;
}
}
Alternatively, instead writing this all the time your own, create an Iterator for $Qproduct iteration and the use FilterIterator and LimitIterator for filtering and pagination.

Pagination current page incorrect when 'use_page_numbers'

I'm using CI Pagination library on my website and now with $config['use_page_numbers'] set to TRUE the current page is always the first. Everything works fine, except this.
Other settings:
$config['uri_segment'] = 2;
$config['prefix'] = "p";
$route['mypage/p(:num)'] = "citate/index/$1";
This is the function that calculate the current page (the output is correct). When I'm on first page returns 1, when on third page returns 3 and so on:
function getPagCurr($offset, $limit){
if( ! $offset) return $page = 1;
else return ($offset/$limit)+1;
}
... though, it's not working.
I've try to set up manually, just for testing, the value of $config['cur_page'] = 2 (so this means that the second link should be considered as active) but no change at all.
CI version is latest.
LE: SOLUTION
It seems that the prefix is the problem here. With my actual configuration the link will be like this www.site.com/mypage/p2, which is not working.
The working link would be www.site.com/mypage/p/2/ with the uri_segment = 3 and route mypage/p/(:num).
However, I really want to have the first link structure so here's my solution (not a good one because you have to modify some system library code):
Pagination.php (start line 166):
// Set current page to 1 if using page numbers instead of offset
if ($this->use_page_numbers AND $this->cur_page == 0)
{
$this->cur_page = $base_page;
}
..changed to:
// Set current page to 1 if using page numbers instead of offset
if ($this->use_page_numbers AND $this->cur_page == 0)
{
$current_page = $CI->uri->segment($this->uri_segment); //get pNUM
$current_page = substr($current_page, 1); //remove prefix
$this->cur_page = $current_page; //set current page
}
... and now it works!
If anybody have a better solution please tell!
Thanks.
Yes you are right it will not work because your segment got a p(p2)
To do this you must have to modify the core but i will say dont modify the core just extend the pagination class and modify the code with following:
Add a new class variable
var $use_rsegment = FALSE;
Then modify the create_links() around line 157
//add
$_uri_segment = 'segment';
if($this->use_rsegment){
$_uri_segment = 'rsegment';
}
//modify
if ($CI->uri->$_uri_segment($this->uri_segment) != $base_page)
{
$this->cur_page = $CI->uri->$_uri_segment($this->uri_segment);
// Prep the current page - no funny business!
$this->cur_page = (int) $this->cur_page;
}
The uri rsegment is the new routed segment, now set the pagination config like this
$config['use_rsegment'] = TRUE;
$this->pagination->initialize($config);
So you can use both option when ever you need. When you have route set rsegment true

Adding banner between SimplePie feed articles

My SimplePie install is a straight-up linux install. (no wordpress or anything)
I'm trying to add a banner in-between my feed articles. For instance if I have 10 feed articles displaying per page, I'd like to add one after the 5th one.
Any help is much appreciated... My feed page is very basic and visible here:
http://www.oil-gas-prices.com
In case you're unfamiliar with SimplePie code, here's basically a very similar code to what makes up the page above:
http://simplepie.org/wiki/setup/sample_page?rev=1341798869
To display how many articles I want on each page, I use:
// Set our paging values
$start = (isset($_GET['start']) && !empty($_GET['start'])) ? $_GET['start'] : 0; // Where do we start?
$length = (isset($_GET['length']) && !empty($_GET['length'])) ? $_GET['length'] : 10; // How many per page?
$max = $feed->get_item_quantity(); // Where do we end?
In your loop that outputs the articles, you can use a counter and the modulus operator:
$counter = 0;
foreach ($feed->get_items($start, $length) as $key=>$item) {
if ($counter % 5 == 0) { // use modulus operator
// display banner
}
// ...
$counter++;
}
See php modulus in a loop article. The code above will display the banner when $counter = 0, 5, 10, etc.

Categories