You are here:  » Parse 2 type of category independently


Parse 2 type of category independently

Submitted by rubenxela on Wed, 2010-01-27 17:10 in

Hello. 've got now another problem.

My need : I'm doin' slideshows for items from categories. So 2 differents pasring (diffrent variabls) in he same feed.

First I Need to parse 4 items from category "Proprietes"
Second I need to parse 4 items from category "Appartements"

Actualy I can parse one or the other but not in the same page.

I think that my method to get elementsis too heavy caus I used the entire piece of code from counter for paging.

<?php
  
require("MagicParser.php");
   
$counter 0;
  
$total_number_of_items 0;
  
$itemsOnPage 4;
  
// default to the first page
  
function myRecordCounter($item)
{
global 
$total_number_of_items;
$total_number_of_items++;// increment for each record in the feed
}
  if (!
$page$page 1;
  echo 
"<div style=\"height:120px; margin-bottom:10px\">";
echo 
"<ul id=\"portfolio\"> \n";
  function 
myRecordHandler($record)
  {
  
// CHOIX RUBRIQUE
   
$rub "Appartements" ;
if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
// DEF PAGE
    
global $page;
    global 
$counter;
    global 
$itemsOnPage;
    
$counter++;
    
// return false whilst parsing items on previous pages
    
if ($counter <= (($page-1)*$itemsOnPage)) return false;
    
// display the item
 
print "<li><a href=\"article.php?ref=".$record["CBIEN"]."\"><img src=\"http://ifergane.activimmo.fr/photo/".$record["SFILENAMEPHOTO1"]."\" border=\"0\"></a> ".$record["BIENDESC/LTITRE"]."</li> \n\n";
    
// return true if counter reaches current page * items on each page
    
return ($counter == ($page*$itemsOnPage));
  }
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
   echo 
"</ul> \n";
echo 
"</div>";    
  
?>

I think code is bad but with it I got my "Appartements" Slideshow with 4 pictures. Now I need to get another one for category "Proprietes" in the same page.

Best Regards

Submitted by support on Thu, 2010-01-28 11:59

Hello,

What you can do is set $rub as a global variable; initialise it to the category you want just before calling MagicParser_parse; and then simply call it twice - however this may be made more complicated depending on how you want to page the results. First things first, for example, to display 4 of each:

  function myRecordHandler($record)
  {
    global $rub;
    global $max;
    if ($record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    // display the item
    // ...
    // return TRUE if reached $max (by decrementing it)
    return(!$max--);
  }
  $rub = "Appartements";
  $max = 4;
  MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  $rub = "Proprietes";
  $max = 4;
  MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");

Perhaps if you could explain more how you want the paging to work with 4 from each etc. I will try and show you how to merge this with the paging code...

Hope this helps!
Cheers,
David.

Submitted by rubenxela on Fri, 2010-01-29 14:37

Thank you it works great, exactly as I needed. Sorry for my first message with paging code ! I tryed to do it starting with paging example as a counter and found another more solution quickly after posting here, but yours is realy better and more simple

Submitted by rubenxela on Fri, 2010-02-05 15:02

Using that exemple I tried to sort the items with an array(). But I 've failed because items need to be displayed after
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
So in this case I can't call MagicParser_parse twice.

Submitted by support on Fri, 2010-02-05 15:55

Hi,

What about loading a global array indexed by $rub? For example:

  $records = array();
  function myRecordHandler($record)
  {
    global $records;
    if (
       ($record["BIENDESC/LTYPMETA"] <> "Appartements")
       &&
       ($record["BIENDESC/LTYPMETA"] <> "Proprietes")
        )
        return;
    // add to the global $records array
    $records[$record["BIENDESC/LTYPMETA"]][] = $record;
  }
  MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");

Hope this helps!
Cheers,
David.

Submitted by rubenxela on Mon, 2010-02-08 14:14

The thing is that with this method I can sort my items but i can't parse the items like previously done

<?php
function myRecordHandler($record)
  {
    global 
$rub;
    global 
$max;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
// display the item
    // ...
    // return TRUE if reached $max (by decrementing it)
    
return(!$max--);
  }
  
$rub "Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
?>

thanks for your help

Submitted by support on Mon, 2010-02-08 14:21

Hello,

Do you mean to limit the display to 4 of each?

Remember that after the parse in the previous example, all the records are in the $records array; so you can display them from there rather than in myRecordHandler, for example:

<?php
  $records 
= array();
  function 
myRecordHandler($record)
  {
    global 
$records;
    if (
       (
$record["BIENDESC/LTYPMETA"] <> "Appartements")
       &&
       (
$record["BIENDESC/LTYPMETA"] <> "Proprietes")
        )
        return;
    
// add to the global $records array
    
$records[$record["BIENDESC/LTYPMETA"]][] = $record;
  }
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$max["Appartements"] = 4;
  
$max["Proprietes"] = 4;
  foreach(
$records as $record)
  {
    
$max[$record["BIENDESC/LTYPMETA"]] = $max[$record["BIENDESC/LTYPMETA"]] - 1;
    
// skip this iteration if we have already displayed $max[type]
    
if ($max[$record["BIENDESC/LTYPMETA"]] < 0) continue;
    
// display record here just as in myRecordHandler
    
print "<li><a href=\"article.php?ref=".$record["CBIEN"]."\"><img src=\"http://ifergane.activimmo.fr/photo/".$record["SFILENAMEPHOTO1"]."\" border=\"0\"></a> ".$record["BIENDESC/LTITRE"]."</li> \n\n";
  }
?>

Hope this helps!
Cheers,
David.

Submitted by rubenxela on Mon, 2010-02-08 14:24

Oh I think I explained bad the meaning of my problem because I've got this piece of code you exlaied to me before

<?php
function myRecordHandler($record)
  {
    global 
$rub;
    global 
$max;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
// display the item
    // ...
    // return TRUE if reached $max (by decrementing it)
    
return(!$max--);
  }
  
$rub "Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
?>

which is very usefull for m need but now with this new need I must use it but sorting my items using this method
<?php
if (
       (
$record["MPRIXEURO"]<=$_GET['price'])
       ||
       (
$record["MPRIXEURO"]>=$_GET['price2'])
       ||
       (
$record["LCP"]<>$_GET['search'])
       )
       return;
?>

Submitted by support on Mon, 2010-02-08 14:29

Hi,

Exactly the same code should still work with the new example; have a go with:

<?php
  
function myRecordHandler($record)
  {
    global 
$rub;
    global 
$max;
    if (
       (
$record["MPRIXEURO"]<=$_GET['price'])
       ||
       (
$record["MPRIXEURO"]>=$_GET['price2'])
       ||
       (
$record["LCP"]<>$_GET['search'])
       )
       return;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
// display the item
    // ...
    // return TRUE if reached $max (by decrementing it)
    
return(!$max--);
  }
  
$rub "Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
?>

Hope this helps!
Cheers,
David.

Submitted by rubenxela on Mon, 2010-02-08 14:43

Sorry another time I'm still wrong with what I explained ! I'm so confuse now !

So I need to use that kind of function and so my basic function is :

<?php
  
require("MagicParser.php");
   function 
myRecordHandler($record)
  {
    global 
$rub;
    global 
$max;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
// MISE EN PAGE
 
print "<h3>".$record["BIENDESC/LTITRE"]."</h3> \n";
    
// return TRUE if reached $max (by decrementing it)
    
return(!$max--);
  }
    
$rub "Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
?>

Work fine. But I need to sort results by price for exemple and use that kind of function in a array() foreach etc ...

<?php
function cmp($a$b)
  {
    if (
$a["MPRIXEURO"] == $b["MPRIXEURO"]) {
      return 
0;
    }
    return (
$a["MPRIXEURO"] < $b["MPRIXEURO"]) ? -1;
  }
  
usort($records,"cmp");
  
// now display or use the sorted records
  
foreach($records as $record)
  {
    
print_r($record);
  }
?>

So Actually I can do a solution or an other but I don't know how to sort by price usig that kind of stuff which is very usefull for me for my layout especialy :
<?php
$rub 
"Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
?>

<?php
  $rub 
"Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
?>

Submitted by support on Mon, 2010-02-08 14:46

Hi,

I see - have a go with something like this;

<?php
  $records 
= array();
  function 
myRecordHandler($record)
  {
    global 
$records;
    global 
$rub;
    global 
$max;
    if (
       (
$record["MPRIXEURO"]<=$_GET['price'])
       ||
       (
$record["MPRIXEURO"]>=$_GET['price2'])
       ||
       (
$record["LCP"]<>$_GET['search'])
       )
       return;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
$records[] = $record;
    return(!
$max--);
  }
  
$rub "Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  function 
cmp($a$b)
  {
    if (
$a["MPRIXEURO"] == $b["MPRIXEURO"]) {
      return 
0;
    }
    return (
$a["MPRIXEURO"] < $b["MPRIXEURO"]) ? -1;
  }
  
usort($records,"cmp");
  
// now display or use the sorted records
  
foreach($records as $record)
  {
    print 
"<h3>".$record["BIENDESC/LTITRE"]."</h3> \n";
  }
?>

Hope this helps!
Cheers,
David.

Submitted by rubenxela on Tue, 2010-02-09 14:12

Thank you it works great but there is still a problem because with this piece of code I can parse the number of items that I need for each category but sorting (buy price in the exemple) is done for the whole. So finaly I've got a list of items of different categories sorted by price.
What I need is differents blocks related to categories and each one sorted by price.

Submitted by support on Tue, 2010-02-09 14:17

Hi,

What I would do in that case is parse into separate global arrays; sort separately, and then combine before finally displaying them; for example:

<?php
  $rubrecords 
= array();
  function 
myRecordHandler($record)
  {
    global 
$rubrecords;
    global 
$rub;
    global 
$max;
    if (
       (
$record["MPRIXEURO"]<=$_GET['price'])
       ||
       (
$record["MPRIXEURO"]>=$_GET['price2'])
       ||
       (
$record["LCP"]<>$_GET['search'])
       )
       return;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
$rubrecords[$rub][] = $record;
    return(!
$max--);
  }
  
$rub "Appartements";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
$max 4;
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  function 
cmp($a$b)
  {
    if (
$a["MPRIXEURO"] == $b["MPRIXEURO"]) {
      return 
0;
    }
    return (
$a["MPRIXEURO"] < $b["MPRIXEURO"]) ? -1;
  }
  
usort($rubrecords["Appartements"],"cmp");
  
usort($rubrecords["Proprietes"],"cmp");
  
// merge the sorted records into a single array
  
$records array_merge($rubrecords["Appartements"],$rubrecords["Proprietes"]);
  
// now display or use the sorted records
  
foreach($records as $record)
  {
    print 
"<h3>".$record["BIENDESC/LTITRE"]."</h3> \n";
  }
?>

Hope this helps!
Cheers,
David.

Submitted by rubenxela on Tue, 2010-02-09 14:18

There is also another thing. Sorting is not good because I need for exemple for each category block (like explained in the previous message) the 4 most expensive or 4 less expensive or 4 more recent etc ...

Submitted by support on Tue, 2010-02-09 14:23

Hi,

I think we both posted at the same time so make sure you didn't miss my reply above!

Once that it is working, you can simply write different cmp() functions to do whatever sort you want, and switch between them depending on the sort required by your script.

One way to do this would be with the function name in a variable - in PHP you can call $variablefunctioname() for example; so one way would be:

  function cmp_priceAsc($a, $b)
  {
    if ($a["MPRIXEURO"] == $b["MPRIXEURO"]) {
      return 0;
    }
    return ($a["MPRIXEURO"] < $b["MPRIXEURO"]) ? -1 : 1;
  }
  function cmp_priceDesc($a, $b)
  {
    if ($a["MPRIXEURO"] == $b["MPRIXEURO"]) {
      return 0;
    }
    return ($a["MPRIXEURO"] > $b["MPRIXEURO"]) ? -1 : 1;
  }
  switch($_GET["sort"])
  {
    case "priceDesc":
      $cmp = "cmp_priceDesc";
      break;
    case "priceAsc":
    default:
      $cmp = "cmp_priceAsc";
      break;
  }
  usort($rubrecords["Appartements"],$cmp);
  usort($rubrecords["Proprietes"],$cmp);

Hope this points you in the right direction!
Cheers,
David.

Submitted by rubenxela on Tue, 2010-02-09 23:25

Thank you very much David. I think that I'm right now in the good direction.

Submitted by rubenxela on Thu, 2010-02-11 15:53

I've got 2 problems with that piece of code :
The first one is not so important. When I use

  $rub = "Appartement";
  $max = 3;
    MagicParser_parse("myfile.xml","myRecordHandler","xml|BACKSLASH/BIEN/");

It don't show 3 but 4 items, so I use $max = 2 to display 3 items.

But my real problem come from the sorting. Filters functions are OK to
sort my parsed items, but in fact I need the items to be sorted before
the parse because for exemple I'm trying to get "3" Items from $rub =
Appartement BUT This items need to be the 3 more expensives items (Higher [MPRIXEURO]).

I think it's the same case when I need 3 Appartement with higher
[CMANDAT] Number.

I show you my piece of code, filtering with only [CMANDAT] in that case

{code saved}

When I use his code it display the number of items I need, sorted like I need,
BUT result don't parse the higher number [CMANDAT]

Submitted by support on Thu, 2010-02-11 16:14

Hi,

I understand, I will fix both based on the example previously, let me know if you're not sure how to incorporate this into your code...

<?php
  $rubrecords 
= array();
  function 
myRecordHandler($record)
  {
    global 
$rubrecords;
    global 
$rub;
    if (
       (
$record["MPRIXEURO"]<=$_GET['price'])
       ||
       (
$record["MPRIXEURO"]>=$_GET['price2'])
       ||
       (
$record["LCP"]<>$_GET['search'])
       )
       return;
    if (
$record["BIENDESC/LTYPMETA"] <> "".$rub."") return;
    
$rubrecords[$rub][] = $record;
  }
  
$rub "Appartements";
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  
$rub "Proprietes";
  
MagicParser_parse("myfeed.xml","myRecordHandler","xml|BACKSLASH/BIEN/");
  function 
cmp($a$b)
  {
    if (
$a["MPRIXEURO"] == $b["MPRIXEURO"]) {
      return 
0;
    }
    return (
$a["MPRIXEURO"] < $b["MPRIXEURO"]) ? -1;
  }
  
usort($rubrecords["Appartements"],"cmp");
  
usort($rubrecords["Proprietes"],"cmp");
  
// pop top $max results from each `rub`
  
$records = array();
  
$max 4;
  for(
$i=1;$<=$max;$i++)
  {
    
$records[] = array_shift($rubrecords["Appartements"]);
  }
  for(
$i=1;$<=$max;$i++)
  {
    
$records[] = array_shift($rubrecords["Proprietes"]);
  }
  
// now display or use the sorted records
  
foreach($records as $record)
  {
    print 
"<h3>".$record["BIENDESC/LTITRE"]."</h3> \n";
  }
?>

Hope this helps!

Cheers,
David.

Submitted by rubenxela on Thu, 2010-02-11 16:36

I tried in many way but it always send a php error
Parse error: syntax error, unexpected T_IS_SMALLER_OR_EQUAL, expecting T_VARIABLE or '$'

Submitted by rubenxela on Thu, 2010-02-11 16:42

Sorry for my last question I found the error
better
for($i=1;$i<=$max;$i++)
than
for($i=1;$<=$max;$i++)

So it works but it's very very long !

Submitted by rubenxela on Thu, 2010-02-11 18:26

It need more than 1 minute tu return my page (with 4 categories). So I try to understand what kind of items are display when we basicly use $max= instead of your last piece of code with for($i=1;$i

Submitted by support on Thu, 2010-02-11 18:28

Hi,

Do you know about how many there are in the entire feed?

There is a big difference between just parsing the first 4, and parsing the entire feed, so if it is very large (lots) then perhaps another way would be better - where you only read this remote URL once a day...

Cheers,
David.

Submitted by rubenxela on Thu, 2010-02-11 18:33

There is 500 items in the feed
For this page called "selection" I need to parse the X last items for 4 categories.
I installed a cache system so it can be quiker to load, but first load ofthe day ned more than 1 minute !

Submitted by support on Thu, 2010-02-11 19:15

Hi,

Yes, it is not a good idea to parse 500 items when you only want 8 every page view; so how about using a CRON job to call your script that does the cache (first load of the day)?

If that runs on its own every night (say midnight) then the normal page views are very quick...

Cheers,
David.

Submitted by rubenxela on Fri, 2010-02-12 09:29

Yes that's the thing I'll do and I did a manual reload page too.
I though it was more easier to check the items sorting by last record (number of [CMANDAT]), like it's generaly done with dates.
Thanks David.

Submitted by rubenxela on Fri, 2010-02-12 15:00

I've finally to find another solution because I think that the time to load the page is realy too much important for my host provider (I think) because my script doesn't work anymore today and display nothing (for 4 category - ok for 2). I think it come from the provider.
I'll try to build another xml feed with the first array() maybe, or use an iframe in the page !! I'll try.

Submitted by rubenxela on Fri, 2010-02-12 16:38

Finaly I choose the solution of 4 Ajax kind of Iframe and so I call all sorted category pages individualy. Loading time is acceptable if I only choose 1 category in the first array. and very good with cache sytem.
Thanks

Submitted by support on Fri, 2010-02-12 16:59

Hi rubenxela,

Sounds good - let me know if you need any more help...

All the best,
David.