SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 26
  1. #1
    SitePoint Member
    Join Date
    Sep 2009
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Pagination with XML content

    Hello all, I did the XML CMS tutorial on site points website.

    Great tutorial.

    How can I implement pagination to the results pulled in from XML? Id also like to add next and previous buttons to browse through a collection of XML articles. How can I achieve this? Any help would be much appreciated. The code from index.php that draws in the XML is below:
    Code PHP:
    <?php
     
    function extractText($array){
    	if(count($array) <= 1){
    		//we only have one tag to process!
    		for ($i = 0; $i<count($array); $i++){
    			$node = $array[$i];
    			$value = $node->get_content();
    		}
    		return $value;
    	} 
     
    }	
    ?>
     
    <?php
    $dh = opendir('./xml/');
     
    $fileCount = 0;
    while ($file = readdir($dh) and $fileCount < 5){
    	if (eregi("^..?$", $file)) {
    		continue;
    	}
    	$open = "./xml/".$file;
    	$xml = domxml_open_file($open);
     
    	//we need to pull out all the things from this file that we will need to 
    	//build our links
    	$root = $xml->root();
    	$stat_array = $root->get_elements_by_tagname("status");
    	$status = extractText($stat_array);
     
    	$ab_array = $root->get_elements_by_tagname("abstract");
    	$abstract = extractText($ab_array);
     
    	$h_array = $root->get_elements_by_tagname("headline");
    	$headline = extractText($h_array);
     
    	if ($status != "live"){
    		continue;
    	}
    	echo "<tr valign=top><td>";
    	echo "<a href=\"showArticle.php?file=".$file . "\">".$headline . "</a><br>";
    	echo $abstract;
    	echo "</td></tr>";
     
    	$fileCount++;
    }
    ?>

  2. #2
    SitePoint Member
    Join Date
    Sep 2009
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    anyone? Im assuming that I would make a conditional after the while loop, or inside it(?) and id use the

    $filecount as limit.

    maybe something like this:
    if ($filecount > 5)

    is my thinking correct, and how would I go about sending the articles not displayed to maybe a results page?

  3. #3
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Have you figured this out yet?
    If so can you share with the rest of us?

    I belive I'm going in the correct direction but what I have so far shows me 5 items from my xml. I need to know how to create the next page with the five next items. btw: I'm reading the posts from last to first.

    Code:
    //read from bev.xml
    $file = 'xml/bev.xml';
    $xml = simplexml_load_file($file);
    
    $limit = 5;
    $page = $_GET['page'];
    $c = 1;
    
    $i = count($xml->messages)-1;
    for($x=$i;$x>=0;$x--)
    if (empty($page) ) 
    {
      if ($c > 0 && $c <= $limit)
      {	
        //write to page
        echo
          $xml->messages[$x]->$vdate.'<br /><p>'
          .$xml->messages[$x]->msgpost.'<hr></p>';
          $c++;
      }
    }
    my xml
    Code:
    <sayings>
      <message>
        <vdate></vdate>
        <msgpost></msgpost>
      </message>
    </sayings>

  4. #4
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Am I even going in the right direction?

  5. #5
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,184
    Mentioned
    17 Post(s)
    Tagged
    4 Thread(s)
    PHP Code:
    <?php
    class Pagination {
        
        protected
        
        
    /*
        * Configuration defaults
        */
        
    $_arrConfig = array(
            
    'limit'=>10
            
    ,'page'=>1
            
    ,'basePath'=>'#'
            
    ,'label'=>'Items'
            
    ,'visiblePages'=>5
            
    ,'pageFlag'=>'{page}'
        
    )
        
        
    /*
        * Data to be passed to template
        */
        
    ,$_arrTemplateData = array()
        
        
    /*
        * function to pass resolved offset and limit
        */
        
    ,$_onPaginate
        
        
    /*
        * extra arguments to pass to to pagination callback 
        * such as data source or db connection
        */
        
    ,$_arrArgs;
        
        public function 
    __construct($onPaginate,$arrConfig=array(),$arrArgs=array()) {
        
            
    $this->_onPaginate $onPaginate;
            
    $this->_arrArgs $arrArgs;
        
            foreach(
    $arrConfig as $strKey=>$mixValue) {
                if(
    array_key_exists($strKey,$this->_arrConfig)) {
                    
    $this->_arrConfig[$strKey] = $mixValue;
                }
            }
        }
        
        public function 
    paginate() {
        
            
    /*
            * Calculate page offset 
            */
            
    $intOffset = ($this->_arrConfig['page']-1)*$this->_arrConfig['limit'];
            
            
    /*
            * Paginate and get number of found rows 
            */
            
    $intFoundRows call_user_func_array($this->_onPaginate,array_merge(array($intOffset,$this->_arrConfig['limit']),$this->_arrArgs));
            
            
    /*
            * Assign template data 
            */
            
    $this->_arrTemplateData['limit'] = $this->_arrConfig['limit'];
            
    $this->_arrTemplateData['page'] = $this->_arrConfig['page'];
            
    $this->_arrTemplateData['offset'] = $intOffset;
            
    $this->_arrTemplateData['found_rows'] = $intFoundRows;
            
    $this->_arrTemplateData['total_pages'] = $intFoundRows $this->_arrConfig['limit']?1:ceil($intFoundRows/$this->_arrConfig['limit']);
            
    $this->_arrTemplateData['visible_pages'] = $this->_arrConfig['visiblePages'];
            
    $this->_arrTemplateData['base_path'] = $this->_arrConfig['basePath'];
            
    $this->_arrTemplateData['label'] = $this->_arrConfig['label'];
            
    $this->_arrTemplateData['page_flag'] = $this->_arrConfig['pageFlag'];
            
            
    /*
            * Return the pagination template 
            */
            
    return $this->display();
        }
        
        public function 
    display() {
            
    extract($this->_arrTemplateData);
            
            if(
    $total_pages <= $visible_pages) {
                
    $page_start 1;
                
    $page_end $total_pages;
            } else if(
    $page <= ceil($visible_pages/2)) {
                
    $page_start 1;
                
    $page_end $visible_pages;
            } else if(
    $page > ($total_pages ceil($visible_pages/2))) {
                
    $page_start $total_pages - (ceil(($visible_pages/2)*2)-1);
                
    $page_end $total_pages;
            } else {
                
    $page_start $page-(floor($visible_pages/2));
                
    $page_end $page+(floor($visible_pages/2));
            }
            
            
    $return sprintf(
                   
    '<div class="summary"><p class="pages">%u %s</p><p class="total">%u %s</p></div>'
                
    ,$total_pages
                
    ,$total_pages == 1?'Page':'Pages'
                
    ,$found_rows
                
    ,$found_rows == 1?$label:$label
            
    );
            
            
    $return.= sprintf('<ul class="pagination">');
            
    $return.= sprintf(
                
    '<li class="first">%s%s%s</li>'
                
    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,1,$base_path))
                ,
    'First'
                
    ,$page == 1?'':'</a>'
            
    );    
            
    $return.= sprintf(
                
    '<li class="previous">%s%s%s</li>'
                    
    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,($page-1),$base_path))
                ,
    'Previous'
                
    ,$page == 1?'':'</a>'
            
    );
            foreach(
    range($page_start,$page_end,1) as $i) {
                
    $return.= sprintf(
                    
    '<li%s>%s%s%s</li>'
                    
    ,$page == $i?' class="current"':''
                    
    ,$page == $i?'':sprintf('<a href="%s">',str_replace($page_flag,$i,$base_path))
                    ,
    $i
                    
    ,$page == $i?'':'</a>'
                
    );
            }
            
    $return.= sprintf(
                
    '<li class="next">%s%s%s</li>'
                
    ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,($page+1),$base_path))
                ,
    'Next'
                
    ,$page == $total_pages?'':'</a>'
            
    );
            
    $return.= sprintf(
                
    '<li class="last">%s%s%s</li>'
                
    ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,$total_pages,$base_path))
                ,
    'Last'
                
    ,$page == $total_pages?'':'</a>'
            
    );
            
    $return.= sprintf('</ul>');
            
            return 
    $return;
            
        }

    }

    class 
    Action {

        private 
    $_objXML;
        private 
    $_arrMessages = array();

        public function 
    __construct() {
            
            
    $this->_objXML simplexml_load_string(
    '<sayings>
      <message>
        <vdate>1</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>2</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>3</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>4</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>5</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>6</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>7</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>8</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>9</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>10</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>11</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>12</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>13</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
    </sayings>'
    );
            
        }

        public function 
    paginate($offset,$limit) {
        
            
    $arrMessages $this->_objXML->xpath('message');
            
            if(isset(
    $arrMessages[$offset])) {
                for(
    $i=0;$i<$limit;$i++) {
                
                    if(!isset(
    $arrMessages[($i+$offset)])) break;
                
                    
    $this->_arrMessages[] = array(
                        
    'vdate'=>(string) $arrMessages[($i+$offset)]->vdate
                        
    ,'msgpost'=>(string) $arrMessages[($i+$offset)]->msgpost
                    
    );
                }
            }
            
            
    // return number of total found rows
            
    return count($arrMessages);
        
        }
        
        public function 
    getMessages() {
            return 
    $this->_arrMessages;
        }

    }

    $action = new Action();

    $func create_function('$offset,$limit,$action','return $action->paginate($offset,$limit);');
    $pg = new Pagination($func,array(
        
    'basePath'=>$_SERVER['PHP_SELF'].'?p={replace_me_with_page}'
        
    ,'pageFlag'=>'{replace_me_with_page}'
        
    ,'label'=>'Messages'
        
    ,'limit'=>5
        
    ,'page'=>isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] != 0?$_GET['p']:1
        
    ,'visiblePages'=>5
    ),array($action));
    ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>Untitled</title>
        <style type="text/css">
        .pagination {
            text-align: center;
        }
        .pagination li {
            display: inline-block;
        }
        *+html .pagination li {
            display: inline;
        }
        * html .pagination li {
            display: inline;
        }
        </style>
    </head>
    <body>
        <?php echo $pg->paginate(); ?>
        
        <?php 
        
    if($action->getMessages()) {
            echo 
    '<ol>';
            foreach(
    $action->getMessages() as $arrMessage) {
                
    printf(
                    
    '<li>
                        <p>%s</p>
                        <p>%s</p>
                     </li>'
                     
    ,$arrMessage['vdate']
                     ,
    $arrMessage['msgpost']
                );
            } 
            echo 
    '</ol>';
        } else {
            echo 
    "<p>No messages available</p>";
        }
    ?>
    </body>
    </html>
    The logic doesn't change just the data source.
    The only code I hate more than my own is everyone else's.

  6. #6
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    you created a class (I don't really have a good grasp of classes) with my xml structure in it (although vdate is a date field in mine). Can I just link to my .xml document?

    Quote Originally Posted by oddz View Post

    class Action {

    private $_objXML;
    private $_arrMessages = array();

    public function __construct() {

    $this->_objXML = simplexml_load_string(
    '<sayings>
    <message>
    <vdate>1</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>2</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>3</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>4</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>5</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>6</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>7</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>8</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>9</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>10</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>11</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>12</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    <message>
    <vdate>13</vdate>
    <msgpost>xxxxx</msgpost>
    </message>
    </sayings>');

    }

  7. #7
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,184
    Mentioned
    17 Post(s)
    Tagged
    4 Thread(s)
    You would replace simplexml_load_string with simplexml_load_file. I just used a string to keep everything in a single file so that you can copy and paste to see it work.
    The only code I hate more than my own is everyone else's.

  8. #8
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    oddz
    love love love you.

  9. #9
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can this be set to post most recent entries first?

    Also when I pointed to my .xml file...when the page is viewed it says "No messages available"
    Is this because my vdate is a Date field and you used as a count (1, 2, 3, ect.)?

  10. #10
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I got my xml to work...

    I'm trying to figure out how this works so I can...
    1. reverse order
    2. put navigation at bottom and top
    3. remove "# pages" and "# Messages"
    4. place spaces between "First", "Previous", page numbers, "Next", and "Last"

    Is there any documentation on this pagination class?

  11. #11
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,184
    Mentioned
    17 Post(s)
    Tagged
    4 Thread(s)
    You can order the messages using a XSLT transformation to place them in ascending or descending order. I added a config property for removing the top message and page header. I than dumped the pagination interface twice to place it at the bottom and top. You can use CSS to place spaces between the various pagination HTML element.

    PHP Code:
    <?php
    class Pagination {
        
        protected
        
        
    /*
        * Configuration defaults
        */
        
    $_arrConfig = array(
            
    'limit'=>10
            
    ,'page'=>1
            
    ,'basePath'=>'#'
            
    ,'label'=>'Items'
            
    ,'visiblePages'=>5
            
    ,'pageFlag'=>'{page}'
            
    ,'display_pages'=>1
            
    ,'display_entity'=>1
        
    )
        
        
    /*
        * Data to be passed to template
        */
        
    ,$_arrTemplateData = array()
        
        
    /*
        * function to pass resolved offset and limit
        */
        
    ,$_onPaginate
        
        
    /*
        * extra arguments to pass to to pagination callback 
        * such as data source or db connection
        */
        
    ,$_arrArgs;
        
        public function 
    __construct($onPaginate,$arrConfig=array(),$arrArgs=array()) {
        
            
    $this->_onPaginate $onPaginate;
            
    $this->_arrArgs $arrArgs;
        
            foreach(
    $arrConfig as $strKey=>$mixValue) {
                if(
    array_key_exists($strKey,$this->_arrConfig)) {
                    
    $this->_arrConfig[$strKey] = $mixValue;
                }
            }
        }
        
        public function 
    paginate() {
        
            
    /*
            * Calculate page offset 
            */
            
    $intOffset = ($this->_arrConfig['page']-1)*$this->_arrConfig['limit'];
            
            
    /*
            * Paginate and get number of found rows 
            */
            
    $intFoundRows call_user_func_array($this->_onPaginate,array_merge(array($intOffset,$this->_arrConfig['limit']),$this->_arrArgs));
            
            
    /*
            * Assign template data 
            */
            
    $this->_arrTemplateData['limit'] = $this->_arrConfig['limit'];
            
    $this->_arrTemplateData['page'] = $this->_arrConfig['page'];
            
    $this->_arrTemplateData['offset'] = $intOffset;
            
    $this->_arrTemplateData['found_rows'] = $intFoundRows;
            
    $this->_arrTemplateData['total_pages'] = $intFoundRows $this->_arrConfig['limit']?1:ceil($intFoundRows/$this->_arrConfig['limit']);
            
    $this->_arrTemplateData['visible_pages'] = $this->_arrConfig['visiblePages'];
            
    $this->_arrTemplateData['base_path'] = $this->_arrConfig['basePath'];
            
    $this->_arrTemplateData['label'] = $this->_arrConfig['label'];
            
    $this->_arrTemplateData['page_flag'] = $this->_arrConfig['pageFlag'];
            
    $this->_arrTemplateData['display_pages'] = $this->_arrConfig['display_pages'];
            
    $this->_arrTemplateData['display_entity'] = $this->_arrConfig['display_entity'];
            
            
    /*
            * Return the pagination template 
            */
            
    return $this->display();
        }
        
        public function 
    display() {
            
    extract($this->_arrTemplateData);
            
            if(
    $total_pages <= $visible_pages) {
                
    $page_start 1;
                
    $page_end $total_pages;
            } else if(
    $page <= ceil($visible_pages/2)) {
                
    $page_start 1;
                
    $page_end $visible_pages;
            } else if(
    $page > ($total_pages ceil($visible_pages/2))) {
                
    $page_start $total_pages - (ceil(($visible_pages/2)*2)-1);
                
    $page_end $total_pages;
            } else {
                
    $page_start $page-(floor($visible_pages/2));
                
    $page_end $page+(floor($visible_pages/2));
            }
            
            
    $return='';
            
            if(
    $display_pages && $display_entity) {
            
    $return.= sprintf(
                   
    '<div class="summary"><p class="pages">%u %s</p><p class="total">%u %s</p></div>'
                
    ,$total_pages
                
    ,$total_pages == 1?'Page':'Pages'
                
    ,$found_rows
                
    ,$found_rows == 1?$label:$label
            
    );
            }
            
            
    $return.= sprintf('<ul class="pagination">');
            
    $return.= sprintf(
                
    '<li class="first">%s%s%s</li>'
                
    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,1,$base_path))
                ,
    'First'
                
    ,$page == 1?'':'</a>'
            
    );    
            
    $return.= sprintf(
                
    '<li class="previous">%s%s%s</li>'
                    
    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,($page-1),$base_path))
                ,
    'Previous'
                
    ,$page == 1?'':'</a>'
            
    );
            foreach(
    range($page_start,$page_end,1) as $i) {
                
    $return.= sprintf(
                    
    '<li%s>%s%s%s</li>'
                    
    ,$page == $i?' class="current"':''
                    
    ,$page == $i?'':sprintf('<a href="%s">',str_replace($page_flag,$i,$base_path))
                    ,
    $i
                    
    ,$page == $i?'':'</a>'
                
    );
            }
            
    $return.= sprintf(
                
    '<li class="next">%s%s%s</li>'
                
    ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,($page+1),$base_path))
                ,
    'Next'
                
    ,$page == $total_pages?'':'</a>'
            
    );
            
    $return.= sprintf(
                
    '<li class="last">%s%s%s</li>'
                
    ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,$total_pages,$base_path))
                ,
    'Last'
                
    ,$page == $total_pages?'':'</a>'
            
    );
            
    $return.= sprintf('</ul>');
            
            return 
    $return;
            
        }
        
    /*
        * Get current page
        */
        
    public function getPage() {
            return 
    $this->_arrConfig['page'];
        }

    }

    class 
    Action {

        private 
    $_objXML;
        private 
    $_boolAscending true;
        private 
    $_arrMessages = array();

        public function 
    __construct($boolAscending=true) {
        
            
    /*
            * Set ordering
            */
            
    $this->_boolAscending $boolAscending;
            
            
    $strXML =
    '<sayings>
      <message>
        <vdate>2010-06-01 00:48:21</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>2010-06-09 00:48:21</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>2010-02-09 00:48:21</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>2010-02-09 00:48:21</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
      <message>
        <vdate>2009-06-09 00:48:21</vdate>
        <msgpost>xxxxx</msgpost>
      </message>
    </sayings>'
    ;

            
    /*
            * transform timestamps
            */
            
    $objXML simplexml_load_string($strXML);
            foreach(
    $objXML->children() as $message) {
                
    $message->vdate strtotime((string) $message->vdate);
            }


            
    $strStyle =
    '<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/xpath-functions">

        <xsl:template match="/">
            <xsl:call-template name="content">
            </xsl:call-template>
        </xsl:template>
        
        <xsl:template name="content">
            <sayings>
            <xsl:for-each select="/sayings/message">
                <xsl:sort select="vdate" data-type="number" order="'
    .($this->_boolAscending?'ascending':'descending').'"/>
                <message>
                    <vdate><xsl:value-of select="vdate"/></vdate>
                    <msgpost><xsl:value-of select="msgpost"/></msgpost>
                </message>
            </xsl:for-each>
            </sayings>
        </xsl:template>
        
    </xsl:stylesheet>'
    ;
            
            
            
    /*
            * Load message DOM document 
            */
            
    $objMessage = new DOMDocument();
            
    $objMessage->loadXML($objXML->asXML());
            
            
    /*
            * Load transform DOM document 
            */
            
    $objStylesheet = new DOMDocument();
            
    $objStylesheet->loadXML($strStyle);
            
            
    /*
            * Create XSLT processor ansd set stylesheet 
            */
            
    $objXSLT = new XSLTProcessor(); 
            
    $objXSLT->importStylesheet($objStylesheet);
            
            
    /*
            * apply transform
            */
            
    $this->_objXML simplexml_load_string($objXSLT->transformToXML($objMessage));

            
        }

        public function 
    paginate($offset,$limit) {
        
            
    $arrMessages $this->_objXML->xpath('message');
            
            if(isset(
    $arrMessages[$offset])) {
                for(
    $i=0;$i<$limit;$i++) {
                
                    if(!isset(
    $arrMessages[($i+$offset)])) break;
                
                    
    $this->_arrMessages[] = array(
                        
    'vdate'=>(string) $arrMessages[($i+$offset)]->vdate
                        
    ,'msgpost'=>(string) $arrMessages[($i+$offset)]->msgpost
                    
    );
                }
            }
            
            
    // return number of total found rows
            
    return count($arrMessages);
        
        }
        
        public function 
    getMessages() {
            return 
    $this->_arrMessages;
        }

    }

    // set ordering
    $order = isset($_GET['order']) && in_array($_GET['order'],array('asc','desc'))?$_GET['order']:'asc';

    $action = new Action(strcmp($order,'asc') == 0?true:false);

    $func create_function('$offset,$limit,$action','return $action->paginate($offset,$limit);');
    $pg = new Pagination($func,array(
        
    'basePath'=>$_SERVER['PHP_SELF'].'?p={replace_me_with_page}&order='.$order
        
    ,'pageFlag'=>'{replace_me_with_page}'
        
    ,'label'=>'Messages'
        
    ,'limit'=>5
        
    ,'page'=>isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] != 0?$_GET['p']:1
        
    ,'visiblePages'=>5
        
    ,'display_pages'=>0
        
    ,'display_entity'=>0
    ),array($action));
    ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>Untitled</title>
        <style type="text/css">
        .pagination {
            text-align: center;
        }
        .pagination li {
            display: inline-block;
        }
        *+html .pagination li {
            display: inline;
        }
        * html .pagination li {
            display: inline;
        }
        </style>
    </head>
    <body>
        
        <?php
        printf
    (
            
    '<a href="%s?p=%u&order=%s">%s</a>'
            
    ,$_SERVER['PHP_SELF']
            ,
    $pg->getPage()
            ,
    strcmp($order,'desc') == 0?'asc':'desc'
            
    ,strcmp($order,'desc') == 0?'Ascending':'Descending'
        
    );
        
    ?>

        <?php $paging $pg->paginate(); ?>
        <?php echo $paging?>
        
        <?php 
        
    if($action->getMessages()) {
            echo 
    '<ol>';
            foreach(
    $action->getMessages() as $arrMessage) {
                
    printf(
                    
    '<li>
                        <p>%s</p>
                        <p>%s</p>
                     </li>'
                     
    ,date('Y-m-d, H:i:s',$arrMessage['vdate'])
                     ,
    $arrMessage['msgpost']
                );
            } 
            echo 
    '</ol>';
        } else {
            echo 
    "<p>No messages available</p>";
        }
    ?>
        
        <?php echo $paging?>
    </body>
    </html>
    The only code I hate more than my own is everyone else's.

  12. #12
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry about all the stupid questions...as you can tell I really don't have a good grasp of this.

    Because my data is in a xml I change:
    Code:
                    
    $strXML =
    '<sayings>  <message>    <vdate>2010-06-01 00:48:21</vdate>    <msgpost>xxxxx</msgpost>  </message>  
    <message>    
      <vdate>2010-06-09 00:48:21</vdate>    
      <msgpost>xxxxx</msgpost>  
    </message>  
    <message>    
      <vdate>2010-02-09 00:48:21</vdate>    
      <msgpost>xxxxx</msgpost>  
    </message>  
    <message>    
      <vdate>2010-02-09 00:48:21</vdate>    
      <msgpost>xxxxx</msgpost>  
    </message>  
    <message>    
      <vdate>2009-06-09 00:48:21</vdate>    <
      msgpost>xxxxx</msgpost>  
    </message>
    </sayings>';
    To:
    Code:
    $strXML = simplexml_load_file('xml/bev.xml');
    I then get a bunch of errors " warning: simplexml_load_string() [function.somplexml-load-string]: Entity: line 2: parser error: Start tag expected, "<' not found " which directs me to this line
    Code:
           
    * transform timestamps        
    */       
    $objXML = simplexml_load_string($strXML);        
    foreach($objXML->children() as $message)
     {           
      $message->vdate = strtotime((string) $message->vdate);       
     }

  13. #13
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Could it be that my date is formated mm/dd/YYYY (in your sample it's YYYY-mm-dd hh:mm:ss)

    I can change that.

  14. #14
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No, changing my date/time format to match yours did not help.

  15. #15
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by I am Abby View Post
    I then get a bunch of errors " warning: simplexml_load_string() [function.somplexml-load-string]: Entity: line 2: parser error: Start tag expected, "<' not found "
    Look at the documentation for simplexml_load_string and you will see that the data needs to be "A well-formed XML string"

    That means starting the string with a known XML doctype.

    Code xml:
    <?xml version='1.0'?>

    See the example at http://www.php.net/manual/en/functio...oad-string.php for an umm, example.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  16. #16
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I got a bit further.

    I now get the fatal error "Call to a memver function children() on a non-object" and points to...
    Code:
    $strXML = simplexml_load_file('xml/bev.xml');
    
    $objXML = simplexml_load_string($strXML);
    foreach(objXML->children() as $message){
    }
    I don't see that it matters if I point to a string or a file when I assign $strXML?

  17. #17
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,184
    Mentioned
    17 Post(s)
    Tagged
    4 Thread(s)
    I have no idea why your loading the XML twice. You only need to load XML file into a simple XML element once. The only reason a string was used in the code I wrote was so that everything was contained within a single script. Ideally though you would load the XML file into a simple XML object given its specific location within your application. Its just much easier to present sample code that takes that divide out of the equation.

    PHP Code:

    $objXML 
    simplexml_load_file('xml/bev.xml');
    foreach(
    objXML->children() as $message){

    The only code I hate more than my own is everyone else's.

  18. #18
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    well I don't get any error messages any more.
    but then none of my xml content is showing up on the page either. All I see is "No messages available".

    oh, I will figure this out.
    Thanks oddz

  19. #19
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I get no error messages, however the code does not show any of my xml content. I know you wrote this for me and changed it for my needs...I feel really bad about asking you to help me even more. But please help.

    It has got to be something very simple that I just can't see.

    xml
    Code:
    <sayings>
      <message>
        <vdate>2010-05-28 00:21:18</vdate>
        <msgpost>Hello World</msgpost>
      </message>
    </sayings>
    Code:
    <?php
    class Pagination {
        
        protected
        
        /*
        * Configuration defaults
        */
        $_arrConfig = array(
            'limit'=>10
            ,'page'=>1
            ,'basePath'=>'#'
            ,'label'=>'Items'
            ,'visiblePages'=>5
            ,'pageFlag'=>'{page}'
            ,'display_pages'=>1
            ,'display_entity'=>1
        )
        
        /*
        * Data to be passed to template
        */
        ,$_arrTemplateData = array()
        
        /*
        * function to pass resolved offset and limit
        */
        ,$_onPaginate
        
        /*
        * extra arguments to pass to to pagination callback 
        * such as data source or db connection
        */
        ,$_arrArgs;
        
        public function __construct($onPaginate,$arrConfig=array(),$arrArgs=array()) {
        
            $this->_onPaginate = $onPaginate;
            $this->_arrArgs = $arrArgs;
        
            foreach($arrConfig as $strKey=>$mixValue) {
                if(array_key_exists($strKey,$this->_arrConfig)) {
                    $this->_arrConfig[$strKey] = $mixValue;
                }
            }
        }
        
        public function paginate() {
        
            /*
            * Calculate page offset 
            */
            $intOffset = ($this->_arrConfig['page']-1)*$this->_arrConfig['limit'];
            
            /*
            * Paginate and get number of found rows 
            */
            $intFoundRows = call_user_func_array($this->_onPaginate,array_merge(array($intOffset,$this->_arrConfig['limit']),$this->_arrArgs));
            
            /*
            * Assign template data 
            */
            $this->_arrTemplateData['limit'] = $this->_arrConfig['limit'];
            $this->_arrTemplateData['page'] = $this->_arrConfig['page'];
            $this->_arrTemplateData['offset'] = $intOffset;
            $this->_arrTemplateData['found_rows'] = $intFoundRows;
            $this->_arrTemplateData['total_pages'] = $intFoundRows < $this->_arrConfig['limit']?1:ceil($intFoundRows/$this->_arrConfig['limit']);
            $this->_arrTemplateData['visible_pages'] = $this->_arrConfig['visiblePages'];
            $this->_arrTemplateData['base_path'] = $this->_arrConfig['basePath'];
            $this->_arrTemplateData['label'] = $this->_arrConfig['label'];
            $this->_arrTemplateData['page_flag'] = $this->_arrConfig['pageFlag'];
            $this->_arrTemplateData['display_pages'] = $this->_arrConfig['display_pages'];
            $this->_arrTemplateData['display_entity'] = $this->_arrConfig['display_entity'];
            
            /*
            * Return the pagination template 
            */
            return $this->display();
        }
        
        public function display() {
            extract($this->_arrTemplateData);
            
            if($total_pages <= $visible_pages) {
                $page_start = 1;
                $page_end = $total_pages;
            } else if($page <= ceil($visible_pages/2)) {
                $page_start = 1;
                $page_end = $visible_pages;
            } else if($page > ($total_pages - ceil($visible_pages/2))) {
                $page_start = $total_pages - (ceil(($visible_pages/2)*2)-1);
                $page_end = $total_pages;
            } else {
                $page_start = $page-(floor($visible_pages/2));
                $page_end = $page+(floor($visible_pages/2));
            }
            
            $return='';
            
            if($display_pages && $display_entity) {
            $return.= sprintf(
                   '<div class="summary"><p class="pages">%u %s</p><p class="total">%u %s</p></div>'
                ,$total_pages
                ,$total_pages == 1?'Page':'Pages'
                ,$found_rows
                ,$found_rows == 1?$label:$label
            );
            }
            
            $return.= sprintf('<ul class="pagination">');
            $return.= sprintf(
                '<li class="first">%s%s%s</li>'
                ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,1,$base_path))
                ,'First'
                ,$page == 1?'':'</a>'
            );    
            $return.= sprintf(
                '<li class="previous">%s%s%s</li>'
                    ,$page == 1?'':sprintf('<a href="%s">',str_replace($page_flag,($page-1),$base_path))
                ,'Previous'
                ,$page == 1?'':'</a>'
            );
            foreach(range($page_start,$page_end,1) as $i) {
                $return.= sprintf(
                    '<li%s>%s%s%s</li>'
                    ,$page == $i?' class="current"':''
                    ,$page == $i?'':sprintf('<a href="%s">',str_replace($page_flag,$i,$base_path))
                    ,$i
                    ,$page == $i?'':'</a>'
                );
            }
            $return.= sprintf(
                '<li class="next">%s%s%s</li>'
                ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,($page+1),$base_path))
                ,'Next'
                ,$page == $total_pages?'':'</a>'
            );
            $return.= sprintf(
                '<li class="last">%s%s%s</li>'
                ,$page == $total_pages?'':sprintf('<a href="%s">',str_replace($page_flag,$total_pages,$base_path))
                ,'Last'
                ,$page == $total_pages?'':'</a>'
            );
            $return.= sprintf('</ul>');
            
            return $return;
            
        }
        /*
        * Get current page
        */
        public function getPage() {
            return $this->_arrConfig['page'];
        }
    
    }
    
    class Action {
    
        private $_objXML;
        private $_boolAscending = true;
        private $_arrMessages = array();
    
        public function __construct($boolAscending=true) {
        
            /*
            * Set ordering
            */
            $this->_boolAscending = $boolAscending;
            
            $objXML = simplexml_load_file('xml/bev.xml');
    
            /*
            * transform timestamps
            */
            foreach($objXML->children() as $message) {
                $message->vdate = strtotime((string) $message->vdate);
            }
    
    
            $strStyle =
    '<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/xpath-functions">
    
        <xsl:template match="/">
            <xsl:call-template name="content">
            </xsl:call-template>
        </xsl:template>
        
        <xsl:template name="content">
            <sayings>
            <xsl:for-each select="/sayings/message">
                <xsl:sort select="vdate" data-type="number" order="'.($this->_boolAscending?'ascending':'descending').'"/>
                <message>
                    <vdate><xsl:value-of select="vdate"/></vdate>
                    <msgpost><xsl:value-of select="msgpost"/></msgpost>
                </message>
            </xsl:for-each>
            </sayings>
        </xsl:template>
        
    </xsl:stylesheet>';
            
            
            /*
            * Load message DOM document 
            */
            $objMessage = new DOMDocument();
            $objMessage->loadXML($objXML->asXML());
            
            /*
            * Load transform DOM document 
            */
            $objStylesheet = new DOMDocument();
            $objStylesheet->loadXML($strStyle);
            
            /*
            * Create XSLT processor ansd set stylesheet 
            */
            $objXSLT = new XSLTProcessor(); 
            $objXSLT->importStylesheet($objStylesheet);
            
            /*
            * apply transform
            */
            $this->_objXML = simplexml_load_string($objXSLT->transformToXML($objMessage));
    
            
        }
    
        public function paginate($offset,$limit) {
        
            $arrMessages = $this->_objXML->xpath('message');
            
            if(isset($arrMessages[$offset])) {
                for($i=0;$i<$limit;$i++) {
                
                    if(!isset($arrMessages[($i+$offset)])) break;
                
                    $this->_arrMessages[] = array(
                        'vdate'=>(string) $arrMessages[($i+$offset)]->vdate
                        ,'msgpost'=>(string) $arrMessages[($i+$offset)]->msgpost
                    );
                }
            }
            
            // return number of total found rows
            return count($arrMessages);
        
        }
        
        public function getMessages() {
            return $this->_arrMessages;
        }
    
    }
    
    // set ordering
    $order = isset($_GET['order']) && in_array($_GET['order'],array('asc','desc'))?$_GET['order']:'asc';
    
    $action = new Action(strcmp($order,'asc') == 0?true:false);
    
    $func = create_function('$offset,$limit,$action','return $action->paginate($offset,$limit);');
    $pg = new Pagination($func,array(
        'basePath'=>$_SERVER['PHP_SELF'].'?p={replace_me_with_page}&order='.$order
        ,'pageFlag'=>'{replace_me_with_page}'
        ,'label'=>'Messages'
        ,'limit'=>5
        ,'page'=>isset($_GET['p']) && is_numeric($_GET['p']) && $_GET['p'] != 0?$_GET['p']:1
        ,'visiblePages'=>5
        ,'display_pages'=>0
        ,'display_entity'=>0
    ),array($action));
    ?>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>Untitled</title>
        <style type="text/css">
        .pagination {
            text-align: center;
        }
        .pagination li {
            display: inline-block;
        }
        *+html .pagination li {
            display: inline;
        }
        * html .pagination li {
            display: inline;
        }
        </style>
    </head>
    <body>
        
        <?php
        printf(
            '<a href="%s?p=%u&order=%s">%s</a>'
            ,$_SERVER['PHP_SELF']
            ,$pg->getPage()
            ,strcmp($order,'desc') == 0?'asc':'desc'
            ,strcmp($order,'desc') == 0?'Ascending':'Descending'
        );
        ?>
    
        <?php $paging = $pg->paginate(); ?>
        <?php echo $paging; ?>
        
        <?php 
        if($action->getMessages()) {
            echo '<ol>';
            foreach($action->getMessages() as $arrMessage) {
                printf(
                    '<li>
                        <p>%s</p>
                        <p>%s</p>
                     </li>'
                     ,date('Y-m-d, H:i:s',$arrMessage['vdate'])
                     ,$arrMessage['msgpost']
                );
            } 
            echo '</ol>';
        } else {
            echo "<p>No messages available</p>";
        }?>
        
        <?php echo $paging; ?>
    btw: how do cut and paste your code keeping the colors? I have the colors in my code when it's in dreamweaver but when I copy and paste it looses the colors.

  20. #20
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,184
    Mentioned
    17 Post(s)
    Tagged
    4 Thread(s)
    At this point I'm not exactly sure why it isn't working for you. I just copy and pasted the script to a new file. Created a folder in the same directory called xml and copy and pasted the xml into a file called bev.xml. Everything worked fine for me. Perhaps your XML file path is incorrect?

    One way to debug that issue is to see if the XML file is even being loaded.

    PHP Code:
    $objXML simplexml_load_file('xml/bev.xml');

    // right here dump the XML to confirm its existence
    echo '<pre>',print_r($objXML),'</pre>';

    foreach(
    objXML->children() as $message){

    The other thing it may be is your version of PHP or XSLTProcessor is enabled?

    run this simple script outside of the other one:

    PHP Code:
    echo class_exists('XSLTProcessor')?'Y':'N'
    Is the answer Y or N?

    Your XML should look like this:

    Code XML:
    <?xml version="1.0"?>
    <sayings>
      <message>
        <vdate>2010-05-28 00:21:18</vdate>
        <msgpost>Hello World</msgpost>
      </message>
      <message>
        <vdate>2010-05-28 00:21:18</vdate>
        <msgpost>Hello World</msgpost>
      </message>
      <message>
        <vdate>2010-05-28 00:21:18</vdate>
        <msgpost>Hello World</msgpost>
      </message>
    </sayings>

    All those issues would likely result in errors but you may have some type of suppression or something going on.
    The only code I hate more than my own is everyone else's.

  21. #21
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,397
    Mentioned
    65 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:

    btw: how do cut and paste your code keeping the colors? I have the colors in my code when it's in dreamweaver but when I copy and paste it looses the colors.

    Use the [PHP] bbcode tags, rather than [CODE] -- if you're using the WYSIWYG editor click the icon.
    Salathe
    Software Developer and PHP Manual Author.

  22. #22
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Salathe View Post
    Off Topic:

    btw: how do cut and paste your code keeping the colors? I have the colors in my code when it's in dreamweaver but when I copy and paste it looses the colors.

    Use the [PHP] bbcode tags, rather than [CODE] -- if you're using the WYSIWYG editor click the icon.
    And if you want to get crafty, you can use the highlight tag, which allows you to use php, javascript, html4strict, css, and a whole host of other coding types.

    For example:

    [highlight="php"]
    <?php
    $name = filter_input(INPUT_POST, 'name');
    ?>
    [/highlight]

    looks like this:


    Code php:
    <?php
    $name = filter_input(INPUT_POST, 'name');
    ?>

    and has slightly different formatting than:


    [php]
    <?php
    $name = filter_input(INPUT_POST, 'name');
    ?>
    [/php]

    which looks like this:


    PHP Code:
    <?php
    $name 
    filter_input(INPUT_POST'name');
    ?>
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  23. #23
    @php.net Salathe's Avatar
    Join Date
    Dec 2004
    Location
    Edinburgh
    Posts
    1,397
    Mentioned
    65 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:

    Why do I feel like I'm on StackOverflow?
    Salathe
    Software Developer and PHP Manual Author.

  24. #24
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For the print_r($objXML) quiestion
    I am seeing my xml but what is the "1" at the end?
    SimpleXMLElement Object
    (
    [messages] => SimpleXMLElement Object
    (
    [vdate] => 2010-05-28 00:22:21
    [msgpost] => Hello World!
    )

    )
    1
    And the answer to the class_exists code is "Y"

    Yes, my xml looks correct

  25. #25
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,184
    Mentioned
    17 Post(s)
    Tagged
    4 Thread(s)
    Hmm…

    The problem than has gone beyond speculation for me and the only way I could properly debug what is happening is through trial and error on your environment. I would recommend going through adding var dumps to see where the issue is occurring.

    Although, there is one other thing I thought of. What page are you on? If your on page 2 and have a single message then seeing the no messages feedback is correct.
    The only code I hate more than my own is everyone else's.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •