While running my code through W3C's HTML validator for HTML5, I noticed that some of my files had this comment inserted before the tag:
<!-- This file should NOT be stored in the web root directory (or any sub-directory thereof) If this is not possible, place it in the 'include' directory and restrict access via Apache's .htaccess files -->
This only seems to happen with pages that are accessed via POST requests, though I have been unable to pin down any cause, nor have searches turned up anything.
I am using mod rewrites and the HTML is generated from multiple files from webroot/views/ and webroot/includes/, but other pages that are similarly generated do not have this issue.
Anyway, I normally wouldn't worry about it, but when sending an xml request to dynamically update a price field, the xml return results, which were supposed to be just the price value as a number, were prefixed by that entire comment.
Now, I can remove it in my application code, which is what I have done, but I'd really like to know under what circumstances Apache decides to inject this comment into outputted HTML files.
For reference, here is my JS to send/handle the xml request:
<script type="text/javascript">
/**
* Updates the currently displayed price based on currently selected options
* #param category_id Id of currently selected category
*/
function updatePrice(category_id) {
if (category_id === undefined || category_id < 1) {
return false;
}
if (!document.getElementsByTagName) { return; }
var aSelect = document.getElementsByTagName("SELECT");
var data = [];
data.push("category_id=" + category_id);
for (var i = 0; i < aSelect.length; i++) {
var sid = aSelect[i].id;
if (sid !== undefined && sid.indexOf("select_") > -1) {
data.push(sid + '=' + aSelect[i].value);
}
}
data = data.join('&');
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// Hack to remove Apache's auto-generated comment/warning at top of some pages
var text = xmlhttp.responseText;
text = (text.length > 0 ? text.substring(text.lastIndexOf('>') + 1).trim() : '');
var price = document.getElementById("product-price");
if (price != null) {
price.value = (text.length < 1 ? 'N/A' : ('$' + text));
}
}
}
xmlhttp.open("POST", "rental_update_price.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(data);
}
</script>
And here is the php file that processes the request:
<?php
if (!isset($errors)) { $errors = array(); }
if (!isset($notifications)) { $notifications = array(); }
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($_POST['category_id']) || !is_numeric($_POST['category_id'])) {
die('Sorry, there has been a system error.');
}
$category_id = (int) $_POST['category_id'];
require './includes/config.inc.php';
require MYSQL;
$att_tbl = selectWithCondition($dbc, 'att_table', 'rental_categories', 'id', $category_id, 'i', 'LIMIT 1');
if ($att_tbl === FALSE) {
die('Failed to retrieve product attribute table from database.');
}
// Retrieve all 'select' keys and values to query exact product id and price
$selected = array();
foreach($_POST AS $k=>$v) {
if (strpos($k, 'select_') > -1) {
// All select fields should be foreign key references, i.e. positive integers
if (ctype_digit($v) && $v > 0) {
$selected[(str_replace('select_', '', $k) . '_id')] = (int) $v;
} else {
$errors[$k] = 'Invalid value';
}
}
}
if (empty($selected)) {
die('No columns selected.');
}
// TODO select price instead of id
$q = "SELECT p.id FROM products p";
$where = '';
foreach($selected AS $k=>$v) {
if (empty($where)) {
$where = "t.$k=$v";
} else {
$where .= " AND t.$k=$v";
}
}
$q .= " JOIN $att_tbl t ON t.product_id=p.id WHERE $where LIMIT 1";
if (($r = $dbc->query($q))) {
if ($row = $r->fetch_assoc()) {
// Generate dummy price value for testing:
echo number_format((((int) $row['id']) * 31) / 100, 2);
}
$r->close();
} else {
$notifications['error'] = 'A system error has occurred. The system administrator will be notified automatically.';
$notifications['error_log'] = 'Error No: ' . $dbc->errno . '-' . $dbc->error;
}
}
require MYSQL;
if MYSQL is a file, give it an extension .php so it doesn't bypass the PHP interpreter.
I think PHP does print the warning when you include a file which is not parsed.
Answering my own question since it was one of those where you look for days and when you finally break down and ask, it becomes glaringly obvious almost immediately.
In my MYSQL file, I had that comment at the top, even before the php tags, and in certain situations the MYSQL file is included before any other HTML output, which then results in that comment being displayed.
Moving the comment to within the php tags so that it is not considered HTML fixes the issue.
Thanks to all who commented.
Related
I'm new in php and right now I'm having a problem when storing data in the $_SESSION array. I have an index page that retrieves information from an XML file and displays each product from the XML file in the page each one with a button to add to a cart. When the button is pressed, I send an XMLHttpRequest with the id of the product I want to add to the $_SESSION array.
This is the main page:
function check_avi(id){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var available = this.responseText;
if (available == "True") {
alert("Add to the cart successfully.");
} else {
alert("Sorry, the car is not available now. Please try other cars.");
}
}
};
xhttp.open("GET", "add_delete_session.php?action=add&id="+id, true);
xhttp.send();
In the php I open the xml, retrieve the info and store it into an array, I then copy the information to the $_SESSION[#number of product]
What is happening is that after I add a product, it deletes in the session array the previous products, so each time I'm only having one product in the array and I want to store all of them to show them later in a shopping cart. The php should return a variable to the main page indicating the availability of the product but I'll do that later.
$arra is the array in where I'm storing the values obtained from the XML file corresponding to the product of the Id sent from the main page, like the price or name. $rf is the variable which count the amount of products stored and serve the same function as $_SESSION['g']
This is my PHP:
<?php
session_start();
$id = $_GET[id];
$action = $_GET[action];
if (empty($_SESSION['g'])) {
$_SESSION['g'] = 0;
}
switch($action){
case "add" :
$xmlDoc = new DOMDocument();
$xmlDoc = simplexml_load_file("cars.xml");
for ($e = 0; $e < 10; $e++) {
$cont = 0;
unset($arra);
foreach ($xmlDoc->carrito[$e]->children() as $child) {
$arra[$cont] = $child;
$cont = $cont + 1;
}
if ($arra[0] == $id) {
for ($f = 0; $f < 10; $f++) {
$rf = $_SESSION['g'];
$_SESSION[$rf][$f] = $arra[$f];
}
$_SESSION['g'] = $_SESSION['g'] + 1;
}
}
break;
case "delete":
break;
}
If anyone could help me I'll be so grateful.
Thanks
I think your in your code
1:
if (empty($_SESSION['g'])) {
$_SESSION['g'] = 0;
}
Actually here you haven't even defined the session at all and you are checking for its value if empty or not that's gonna stop execution of your code there itself, first you need to define the session variable and the check the value for it.
2:
$rf = $_SESSION['g'];
$_SESSION[$rf][$f] = $arra[$f];
Because it means that
$_SESSION[$_SESSION['g']][$f] = $arra[$f];
Which is a wrong approach.
Better way first you make all the simplifications and then assign it to the $_SESSION[] and echo it.
This may help a few people using Aicontactsafe with joomla as the core component does not have it currently as an option. Essentially i need to change the module php file to allow different redirect urls depending on what dropdown option is selected in the "Studio" Combobox field.
Perfectly honest with you i do not know if i am typing in the correct fields or code values:
The test site you can see here - http://www.datumcreative.com/wellness/ and the form is 'book my taster class' on the right.
Below is where i believe code needs adding in the original file:
if (!array_key_exists('return_to', $parameters)) {
// initialize the database
$db = &JFactory::getDBO();
$query = 'SELECT redirect_on_success FROM #__aicontactsafe_profiles WHERE id = ' . $pf;
$db->setQuery( $query );
$redirect_on_success = $db->loadResult();
// set the return link to the current url or the one setup into the profile
if (strlen(trim($redirect_on_success)) == 0) {
$postData['return_to'] = $currentUrl;
} else {
$postData['return_to'] = $redirect_on_success;
}
}
To create the other redirects i added the following custom lines, below the line "$redirect_on_success = $db->loadResult();":
$redirect_to_wgc = "http://www.google.com";
$redirect_to_harp = "http://www.yahoo.co.uk";
I then needed to add the "if" statements **.
**if ($field_values['aics_studio'] == "Welwyn Garden City") {
$postData['return_to'] = $redirect_to_wgc;
}
elseif ($field_values['$aics_studio'] == "Harpenden") {
$postData['return_to'] = $redirect_to_harp;
}**
elseif (strlen(trim($redirect_on_success)) == 0) {
$postData['return_to'] = $currentUrl;
} else {
$postData['return_to'] = $redirect_on_success;
}
No luck so far, any suggestions?
Hi guys I wanted to know how to validate 3 things both server and client side.
database table product
my database looks something like this but they are over 400 data in it.
pid name size
1 grey 12 inch
2 blue 16 inch
database table category
pid category
1 vans
2 nike
database table itemised
pid price
1 30.00
2 50.00
I have some fields I need to verify. I have already done a validation to check that it is not empty.
One of the field in my table looks like this
<select id="Category" name="Category">
<?php
dbconnect();
$stmt = $conn->prepare("SELECT Name FROM Category WHERE pid=:id");
$stmt->bindParam('id',$id);
$stmt->execute();
$i = 0;
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if ($i == 0) {
echo '<option SELECTED value="'.$row['Name'].'">'.$row['Name'].'</option>
';
}
else {
echo '<option value="'.$row['Name'].'">'.$row['Name'].'</option>';
}
$i++;
}
?>
</select>
it is not in a form rather a table. If you notice the size as number and letter it in.
My question
More or less everyone familiar with developer tools to change posted value. I want to validation both client(JS) and client(php) to make sure that no one as mess up the value.
I did this to check that not of it is empty
for an example if have
normal
<option value="blue vans">blue vans</option>
not-normal
<option value="">blue vans</option> // in this one the value is `BLANKET`
The js below check this
function isEmpty(aTextField,errormessage) //null may be used for errormessage to only change the colour of matching fields
{
if (aTextField.value.length<=0)
{
if (lfield != aTextField || lfield === null) { fields[fields.length] = [aTextField,false]; } else { fields[fields.length-1] = [aTextField,false]; }
lfield = aTextField;
if (errormessage !== "")
{
if (counter < error_count || error_count == 0) { errors += errormessage+'\n'; } counter++;
}
return true;
}
else
{
if (lfield != aTextField || lfield === null) { fields[fields.length] = [aTextField,true]; }
lfield = aTextField;
return true;
}
}
in php
function notEmpty($inputname,$error_message)
{
$this->js.='if (!isEmpty(formname.'.$inputname.',"'.$error_message.'")) return false;';
if ( isset($_POST[$inputname]) && ( strlen($_POST[$inputname]) <= 0 ))
{
if ($error_message != null)
{
$this -> error_message .= $error_message.'<br>';
}
}
}
Now you see how I have validate for blanket value for all of the options in my table
How can i verify both in js and php
for the size it will be kinda simple if i didnt have inch at the end but changing over 1000 data in a database will be a pain.
Any idea how I can do this please???
I hope I have explain this clearly and if not please leave a comment and I will try and rephrase the question.
Thanks
I would use regular expressions for both Javascript and php. You can use the same pattern in both languages, so u don't have to write it twice.
php-check for the size:
<?php
if(!preg_match("/^[0-9]+ (inch|othervalue1|othervalue2)$/",$_POST[$inputname]){
$this -> error_message .= 'Wrong Value<br>';
}
?>
For JS, you can take a look at this: http://www.w3schools.com/jsref/jsref_obj_regexp.asp
This might do the trick in JS, but not tested yet:
function checkSize(value){
var patt=new RegExp("^[0-9]+ (inch|othervalue1|othervalue2)$");
return patt.test(value); //returns false for wrong value
}
Furthermore I would suggest to make 2 columns for both value and unit. It would give you several advantages.
You could use intval to convert the string size into an integer, for example intval('12 inch') will return 12.
Try preg_match("/(\d+) inch/", $input_str) or similar to test whether your desired regular expression matches.
You should also be escaping (html special entities) all variable to your HTML output. Otherwise angle-brackets will break the page.
At least you're using prepared statements on the DB side.. thank God. One out of three seems to be good for a PHP "application".
Just to provide you with an alternative way of validating.
You could also post the form via ajax so you only have to validate server-side:
$('#myForm').ajaxForm({
dataType: 'json',
success: function(response) {
if (response.error) {
alert(response.error);
} else {
$('#myForm').text(response.message);
}
}
});
(This is assuming you're using the jQuery plugin http://malsup.com/jquery/form)
Then in you're PHP you should check whether the current request is ajax:
function isAjax() {
return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
}
...
if (isAjax() {
$response = array();
if (!empty($this->error_message)) {
$response['error'] = str_replace('<br>', "\n", $this->error_message);
} else {
$response['message'] = 'Form submitted';
}
header('Content-type: application/json');
echo json_encode($response);
exit;
}
I am working with SilverStripe, and I am working on making a newspage.
I use the DataObjectAsPage Module( http://www.ssbits.com/tutorials/2012/dataobject-as-pages-the-module/ ), I got it working when I use the admin to publish newsitems.
Now I want to use the DataObjectManager Module instead of the admin module to manage my news items. But this is where the problem exists. Everything works fine in draft mode, I can make a new newsitem and it shows up in draft. But when I want to publish a newsitem, it won't show up in the live or published mode.
I'm using the following tables:
-Dataobjectaspage table,
-Dataobjectaspage_live table,
-NewsArticle table,
-NewsArticle_Live table
The Articles have been inserted while publishing in the Dataobjectaspage table and in the NewsArticle table... But not in the _Live tables...
Seems the doPublish() function hasn't been used while 'Publishing'.
So I'm trying the use the following:
function onAfterWrite() {
parent::onAfterWrite();
DataObjectAsPage::doPublish();
}
But when I use this, it gets an error:
here is this picture
It seems to be in a loop....
I've got the NewsArticle.php file where I use this function:
function onAfterWrite() {
parent::onAfterWrite();
DataObjectAsPage::doPublish();
}
This function calls the DataObjectAsPage.php file and uses this code:
function doPublish() {
if (!$this->canPublish()) return false;
$original = Versioned::get_one_by_stage("DataObjectAsPage", "Live", "\"DataObjectAsPage\".\"ID\" = $this->ID");
if(!$original) $original = new DataObjectAsPage();
// Handle activities undertaken by decorators
$this->invokeWithExtensions('onBeforePublish', $original);
$this->Status = "Published";
//$this->PublishedByID = Member::currentUser()->ID;
$this->write();
$this->publish("Stage", "Live");
// Handle activities undertaken by decorators
$this->invokeWithExtensions('onAfterPublish', $original);
return true;
}
And then it goes to DataObject.php file and uses the write function ():
public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false) {
$firstWrite = false;
$this->brokenOnWrite = true;
$isNewRecord = false;
if(self::get_validation_enabled()) {
$valid = $this->validate();
if(!$valid->valid()) {
// Used by DODs to clean up after themselves, eg, Versioned
$this->extend('onAfterSkippedWrite');
throw new ValidationException($valid, "Validation error writing a $this->class object: " . $valid->message() . ". Object not written.", E_USER_WARNING);
return false;
}
}
$this->onBeforeWrite();
if($this->brokenOnWrite) {
user_error("$this->class has a broken onBeforeWrite() function. Make sure that you call parent::onBeforeWrite().", E_USER_ERROR);
}
// New record = everything has changed
if(($this->ID && is_numeric($this->ID)) && !$forceInsert) {
$dbCommand = 'update';
// Update the changed array with references to changed obj-fields
foreach($this->record as $k => $v) {
if(is_object($v) && method_exists($v, 'isChanged') && $v->isChanged()) {
$this->changed[$k] = true;
}
}
} else{
$dbCommand = 'insert';
$this->changed = array();
foreach($this->record as $k => $v) {
$this->changed[$k] = 2;
}
$firstWrite = true;
}
// No changes made
if($this->changed) {
foreach($this->getClassAncestry() as $ancestor) {
if(self::has_own_table($ancestor))
$ancestry[] = $ancestor;
}
// Look for some changes to make
if(!$forceInsert) unset($this->changed['ID']);
$hasChanges = false;
foreach($this->changed as $fieldName => $changed) {
if($changed) {
$hasChanges = true;
break;
}
}
if($hasChanges || $forceWrite || !$this->record['ID']) {
// New records have their insert into the base data table done first, so that they can pass the
// generated primary key on to the rest of the manipulation
$baseTable = $ancestry[0];
if((!isset($this->record['ID']) || !$this->record['ID']) && isset($ancestry[0])) {
DB::query("INSERT INTO \"{$baseTable}\" (\"Created\") VALUES (" . DB::getConn()->now() . ")");
$this->record['ID'] = DB::getGeneratedID($baseTable);
$this->changed['ID'] = 2;
$isNewRecord = true;
}
// Divvy up field saving into a number of database manipulations
$manipulation = array();
if(isset($ancestry) && is_array($ancestry)) {
foreach($ancestry as $idx => $class) {
$classSingleton = singleton($class);
foreach($this->record as $fieldName => $fieldValue) {
if(isset($this->changed[$fieldName]) && $this->changed[$fieldName] && $fieldType = $classSingleton->hasOwnTableDatabaseField($fieldName)) {
$fieldObj = $this->dbObject($fieldName);
if(!isset($manipulation[$class])) $manipulation[$class] = array();
// if database column doesn't correlate to a DBField instance...
if(!$fieldObj) {
$fieldObj = DBField::create('Varchar', $this->record[$fieldName], $fieldName);
}
// Both CompositeDBFields and regular fields need to be repopulated
$fieldObj->setValue($this->record[$fieldName], $this->record);
if($class != $baseTable || $fieldName!='ID')
$fieldObj->writeToManipulation($manipulation[$class]);
}
}
// Add the class name to the base object
if($idx == 0) {
$manipulation[$class]['fields']["LastEdited"] = "'".SS_Datetime::now()->Rfc2822()."'";
if($dbCommand == 'insert') {
$manipulation[$class]['fields']["Created"] = "'".SS_Datetime::now()->Rfc2822()."'";
//echo "<li>$this->class - " .get_class($this);
$manipulation[$class]['fields']["ClassName"] = "'$this->class'";
}
}
// In cases where there are no fields, this 'stub' will get picked up on
if(self::has_own_table($class)) {
$manipulation[$class]['command'] = $dbCommand;
$manipulation[$class]['id'] = $this->record['ID'];
} else {
unset($manipulation[$class]);
}
}
}
$this->extend('augmentWrite', $manipulation);
// New records have their insert into the base data table done first, so that they can pass the
// generated ID on to the rest of the manipulation
if(isset($isNewRecord) && $isNewRecord && isset($manipulation[$baseTable])) {
$manipulation[$baseTable]['command'] = 'update';
}
DB::manipulate($manipulation);
if(isset($isNewRecord) && $isNewRecord) {
DataObjectLog::addedObject($this);
} else {
DataObjectLog::changedObject($this);
}
$this->onAfterWrite();
$this->changed = null;
} elseif ( $showDebug ) {
echo "<b>Debug:</b> no changes for DataObject<br />";
// Used by DODs to clean up after themselves, eg, Versioned
$this->extend('onAfterSkippedWrite');
}
// Clears the cache for this object so get_one returns the correct object.
$this->flushCache();
if(!isset($this->record['Created'])) {
$this->record['Created'] = SS_Datetime::now()->Rfc2822();
}
$this->record['LastEdited'] = SS_Datetime::now()->Rfc2822();
} else {
// Used by DODs to clean up after themselves, eg, Versioned
$this->extend('onAfterSkippedWrite');
}
// Write ComponentSets as necessary
if($writeComponents) {
$this->writeComponents(true);
}
return $this->record['ID'];
}
Look at the $this->onAfterWrite();
It probably goes to my own function on NewsArticle.php and there starts the loop! I'm not sure though, so i could need some help!!
Does anyone knows how to use the doPublish() function?
The reason that is happening is that in the DataObjectAsPage::publish() method, it is calling ->write() - line 11 of your 3rd code sample.
So what happens is it calls ->write(), at the end of ->write() your onAfterWrite() method is called, which calls publish(), which calls write() again.
If you remove the onAfterWrite() function that you've added, it should work as expected.
The doPublish() method on DataObjectAsPage will take care of publishing from Stage to Live for you.
I have a MySQL table holding lots of records that i want to give the user access to. I don't want to dump the entire table to the page so i need to break it up into 25 records at a time, so i need a page index. You have probably seen these on other pages, they kind of look like this at the base of the page:
< 1 2 3 4 5 6 7 8 9 >
For example, when the user clicks on the '4' link, the page refreshes and the offset is moved on (4th page x 25 records). Here is what i already have:
function CreatePageIndex($ItemsPerPage, $TotalNumberOfItems, $CurrentOffset, $URL, $URLArguments = array())
{
foreach($URLArguments as $Key => $Value)
{
if($FirstIndexDone == false)
{
$URL .= sprintf("?%s=%s", $Key, $Value);
$FirstIndexDone = true;
}
else
{
$URL .= sprintf("&%s=%s", $Key, $Value);
}
}
Print("<div id=\"ResultsNavigation\">");
Print("Page: ");
Print("<span class=\"Links\">");
$NumberOfPages = ceil($TotalNumberOfItems / $ItemsPerPage);
for($x = 0; $x < $NumberOfPages; $x++)
{
if($x == $CurrentOffset / $ItemsPerPage)
{
Print("<span class=\"Selected\">".($x + 1)." </span>");
}
else
{
if(empty($URLArguments))
{
Print("".($x + 1)." ");
}
else
{
Print("".($x + 1)." ");
}
}
}
Print("</span>");
Print(" (".$TotalNumberOfItems." results)");
Print("</div>");
}
Obviously this piece of code does not create a dynamic index, it just dumps the whole index at the bottom of the page for every page available. What i need is a dynamic solution that only shows the previous 5 pages and next 5 pages (if they exist) along with a >> or something to move ahead 5 or so pages.
Anybody seen an elegant and reusable way of implementing this as i feel i'm re-inventing the wheel? Any help is appreciated.
Zend Framework is becoming a useful collection and includes a Zend_Paginator class, which might be worth a look. Bit of a learning curve and might only be worth it if you want to invest the time in using other classes from the framework.
It's not too hard to roll your own though. Get a total count of records with a COUNT(*) query, then obtain a page of results with a LIMIT clause.
For example, if you want 20 items per page, page 1 would have LIMIT 0,20 while page 2 would be LIMIT 20,20, for example
$count=getTotalItemCount();
$pagesize=20;
$totalpages=ceil($count/$pagesize);
$currentpage=isset($_GET['pg'])?intval($_GET['pg']):1;
$currentpage=min(max($currentpage, 1),$totalpages);
$offset=($currentpage-1)*$pagesize;
$limit="LIMIT $offset,$pagesize";
It's called Pagination:
a few examples:
A nice one without SQL
A long tutorial
Another tutorial
And Another
And of course.. google
How about this jQuery-plugin?
So all the work is done on the clientside.
http://plugins.jquery.com/project/pagination
demo: http://d-scribe.de/webtools/jquery-pagination/demo/demo_options.htm
Heres an old class I dug out that I used to use in PHP. Now I handle most of it in Javascript. The object takes an array (that you are using to split the stack into pages) and return the current view. This can become tedious on giant tables so keep that in mind. I generally use it for paging through small data sets of under 1000 items. It can also optionally generate your jump menu for you.
class pagination {
function pageTotal($resultCount, $splitCount) {
if (is_numeric($resultCount) && is_numeric($splitCount)) {
if ($resultCount > $splitCount) {
$pageAverage = (integer)$resultCount / $splitCount;
$pageTotal = ceil($pageAverage);
return $pageTotal;
} else {
return 1;
}
} else {
return false;
}
}
function pageTotalFromStack($resultArray, $splitCount) {
if (is_numeric($splitCount) && is_array($resultStack)) {
if (count($resultStack) > $splitCount) {
$resultCount = count($resultStack);
$pageAverage = (integer)$resultCount / $splitCount;
$pageTotal = ceil($pageAverage);
return $pageTotal;
} else {
return 1;
}
} else {
return false;
}
}
function makePaginationURL($preURL, $pageTotal, $selected=0, $linkAttr=0, $selectedAttr=0) {
if (!empty($preURL) && $pageTotal >= 1) {
$pageSeed = 1;
$passFlag = 0;
$regLink = '<a href="{url}&p={page}"';
if (is_array($linkAttr)) $regLink .= $this->setAttributes($linkAttr); //set attributes
$regLink .= '>{page}</a>';
$selLink = '<a href="{url}&p={page}"';
if (is_array($selectedAttr)) $selLink .= $this->setAttributes($selectedAttr); //set attributes
$selLink .= '>{page}</a>';
while($pageSeed <= $pageTotal) {
if ($pageSeed == $selected) {
$newPageLink = str_replace('{url}', $preURL, $selLink);
$newPageLink = str_replace('{page}', $pageSeed, $newPageLink);
} else {
$newPageLink = str_replace('{url}', $preURL, $regLink);
$newPageLink = str_replace('{page}', $pageSeed, $newPageLink);
}
if ($passFlag == 0) {
$passFlag = 1;
$linkStack = $newPageLink;
} else {
$linkStack .= ', ' . $newPageLink;
}
$pageSeed++;
}
return $linkStack;
} else {
return false;
}
}
function splitPageArrayStack($stackArray, $chunkSize) {
if (is_array($stackArray) && is_numeric($chunkSize)) {
return $multiArray = array_chunk($stackArray, $chunkSize);
} else {
return false;
}
}
}