how to do: top ten articles per catergory

In this board you can talk about general questions about phpMyFAQ

Moderator: Thorsten

natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

how to do: top ten articles per catergory

Post by natmanu »

Before i start i must commend Thorsten on an excelent piece of work. I've been playing many scripts online and I've found yours very logical and easy to use and modify. I've even learnt a bit more css from you :-) Thanks i shall be visiting you wish list soon.

1.
I want to be able to provide top 10 articles for each catergory. I have: catergory 1
catergory 2

and on website www.domain.com/catergory1

I'd like to insert a rss feed of catergory 1 top 10 articles from the faq

and the same for category 2

Should I be using rss or is there another way to do it?

2. the rss feeds combine the numer of views with the article name. is there a way to seperate this info:

How long should I volunteer for? (145 views)

I'd like to be able to format like below per each list item
<li>
How long should I volunteer for?<br />
<em>(145 views)</em>
</li>


but i can not if the feed provides both the views and the title together as one piece of info.

Hope I've explained myself well,

TIA
Cheers
Nat
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

forgot to send the url I'm working on

Post by natmanu »

forgot to send the url I'm working on

www.uvolunteer.org/faqs
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Post by matteo »

Hi,
the url provided is HTTP BASIC AUTH protected.
BTW, you could hack by your own this file, [PATH_TO_LEXINSTALL]/feed/topten/rss.php, precisely this line for point 1:

Code: Select all

$query = 'SELECT '.SQLPREFIX.'faqdata.id AS id, '.SQLPREFIX.'faqdata.lang AS lang, '.SQLPREFIX.'faqdata.thema AS thema, '.SQLPREFIX.'faqcategoryrelations.category_id AS category_id, '.SQLPREFIX.'faqvisits.visits AS visits, '.SQLPREFIX.'faqdata.datum AS datum, '.SQLPREFIX.'faqvisits.last_visit AS last_visit FROM '.SQLPREFIX.'faqvisits, '.SQLPREFIX.'faqdata LEFT JOIN '.SQLPREFIX.'faqcategoryrelations ON '.SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqcategoryrelations.record_id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqcategoryrelations.record_lang WHERE '.SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqvisits.id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqvisits.lang AND '.SQLPREFIX.'faqdata.active = \'yes\' ORDER BY '.SQLPREFIX.'faqvisits.visits DESC';
and this line for point 2:

Code: Select all

            $rss .= "\t\t<title><![CDATA[".makeShorterText($row->thema, 8)." (".$row->visits." ".$PMF_LANG["msgViews"].")]]></title>\n";
FYI, an unordered list (UL/LI) must be built not in the RSS feed side but in the feed client that will read the PMF TopTen feed
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

Post by natmanu »

Thanks for the reply matteo,

point 1.

I'm afraid I'm totally lost when it comes to database query syntax. I have just started learning it and don't have enough knowledge to separate the category top tens! And it would be also difficult fro me to turn it into a rss fed:-) sorry
maybe this will not be possible for me to do. Is this going to be a big hack or not? (just so I can decide whether Its worth the time as I'm on quite a short self imposed deadline)

2. I understand your point about not having <tags> inside rss feeds. Although the feed is only being used internally but my own website and is not privately available. But I you are right, I should do this at the phrasing end


Sorry about the protected url , It's ok to view now: www.uvolunteer.org/faqs

Cheers
Nat
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Post by matteo »

natmanu wrote:point 1.

I'm afraid I'm totally lost when it comes to database query syntax. I have just started learning it and don't have enough knowledge to separate the category top tens! And it would be also difficult fro me to turn it into a rss fed:-) sorry
maybe this will not be possible for me to do. Is this going to be a big hack or not? (just so I can decide whether Its worth the time as I'm on quite a short self imposed deadline)
Basically the effort depends on the hierarchical structure of your categories: I'm seeing that you're using only 4 root/main categories and maybe it would be more convenient to create a custom RSS feed and a generateTopTenData() function, passing them the category id for filtering out the records.
In these days I've really few time for doing this... I do not promise nothing but I'll come back here when I'll have spare time for look at a quick code solution.
natmanu wrote:2. I understand your point about not having <tags> inside rss feeds. Although the feed is only being used internally but my own website and is not privately available. But I you are right, I should do this at the phrasing end
Something like the code below?

Code: Select all

            $rss .= "\t\t<title><![CDATA[<li>".makeShorterText($row->thema, 8)."<br /><em>(".$row->visits." ".$PMF_LANG["msgViews"].")</em></li>]]></title>\n";
natmanu wrote:Sorry about the protected url , It's ok to view now: www.uvolunteer.org/faqs
Really a nice template :wink:
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

Post by natmanu »

matteo wrote:
Basically the effort depends on the hierarchical structure of your categories: I'm seeing that you're using only 4 root/main categories and maybe it would be more convenient to create a custom RSS feed and a generateTopTenData() function, passing them the category id for filtering out the records.
In these days I've really few time for doing this... I do not promise nothing but I'll come back here when I'll have spare time for look at a quick code solution.
thanks Matteo, There are currently only 4 root categories but this could grow to 15, but only at root level, No sub root level top10 will be needed. If you manage to have time to help me it would be very much appreciated. By be I'll looking into how to create rss feed when I've learnt a bit more PHP*SQL

Point 2. Yes, I managed to solve that one already

Thanks again Matteo
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Hacking of generateTopTen*() functions

Post by matteo »

Hi,
here is the hacked code for printing out the TOP TEN FAQ list, with a section for each category.
Please locate, backup and open the [PATH_TO_PMFINSTALL/inc/function.php file: these below are the two hacked functions, generateTopTenData() and generateTopTen().

Code: Select all

function generateTopTenData($language = '', $count = PMF_NUMBER_RECORDS_TOPTEN, $categoryId)
{
	global $db, $sids, $PMF_LANG, $PMF_CONF;
	$query = 'SELECT DISTINCT '.SQLPREFIX.'faqdata.id AS id, '.SQLPREFIX.'faqdata.lang AS lang, '.SQLPREFIX.'faqdata.thema AS thema, '.SQLPREFIX.'faqcategoryrelations.category_id AS category_id, '.SQLPREFIX.'faqvisits.visits AS visits FROM '.SQLPREFIX.'faqvisits, '.SQLPREFIX.'faqdata LEFT JOIN '.SQLPREFIX.'faqcategoryrelations ON '.SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqcategoryrelations.record_id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqcategoryrelations.record_lang WHERE ';

    if (isset($categoryId) && is_numeric($categoryId) && ($categoryId != 0)) {
        $query .= SQLPREFIX.'faqcategoryrelations.category_id = \''.$categoryId.'\' AND ';
    }

    if (isset($language) && PMF_Init::isASupportedLanguage($language)) {
        $query .= SQLPREFIX.'faqdata.lang = \''.$language.'\' AND ';
    }

    $query .= SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqvisits.id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqvisits.lang AND '.SQLPREFIX.'faqdata.active = \'yes\' ORDER BY '.SQLPREFIX.'faqvisits.visits DESC';

    $result = $db->query($query);
	$returnArray = array();

	$i = 1;
    $oldId = 0;
	while (($row = $db->fetch_object($result)) && $i <= $count) {
	    if ($oldId != $row->id) {
	        $data['visits'] =  $row->visits;
	        $data['thema'] = $row->thema;
	        if (isset($PMF_CONF["mod_rewrite"]) && $PMF_CONF["mod_rewrite"] == "TRUE") {
	            $data['url'] = $row->category_id."_".$row->id."_".$row->lang.".html";
	        } else {
	            $data['url'] = $_SERVER["PHP_SELF"]."?".$sids."action=artikel&cat=".$row->category_id."&id=".$row->id."&artlang=".$row->lang;
	        }
	        $returnArray[] = $data;
	        $i++;
	    }
	    $oldId = $row->id;
	}

	return $returnArray;
}

Code: Select all

function generateTopTen($language = '')
{
    global $PMF_LANG, $PMF_CONF, $tree;

    $output = "";
    foreach ($tree->categories as $category) {
        $result = generateTopTenData($language, PMF_NUMBER_RECORDS_TOPTEN, $category['id']);
        if (count($result) > 0) {
            $output .= "<ol><h3>".$category['name']."</h3>\n";
            foreach ($result as $row) {
                $output .= "\t<li><strong>".$row['visits']." ".$PMF_LANG["msgViews"].":</strong><br />";
                $output .= '<a href="'.$row['url'] . '">'.makeShorterText(PMF_htmlentities($row['thema'], ENT_NOQUOTES, $PMF_LANG['metaCharset']), 8)."</a></li>\n";
            }
            $output .= "</ol>\n";
        }
    }
    if ('' == $output) {
        $output = $PMF_LANG["err_noTopTen"];
    }

    return $output;
}
Do you need also a per-category TOP TEN RSS feed?
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

Post by natmanu »

Thank You for this Matteo.

That is working fine. One little problem is that if only show top 10 category questions when you are on an actual FAQ page but not when you are in the category homepage (the page which list all questions in that category, accessible by pressing the category link in the menu).

Yes it would be great to also have RSS feeds per category. Thank you very much.

Cheers
Nat
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Post by matteo »

Hi Nat,
natmanu wrote:That is working fine. One little problem is that if only show top 10 category questions when you are on an actual FAQ page but not when you are in the category homepage (the page which list all questions in that category, accessible by pressing the category link in the menu).
Locate, backup and open the [PATH_TO_PMFINSTALL]/inc/category.php file and search for the getCategoriesFromArticle() function and replace it with this one below:

Code: Select all

    function getCategoriesFromArticle($article_id) {
        $rel = SQLPREFIX."faqcategoryrelations";
        $cat = SQLPREFIX."faqcategories";
        $query = "SELECT ".$cat.".id AS id, ".$cat.".lang AS lang, ".$cat.".parent_id AS parent_id, ".$cat.".name AS name, ".$cat.".description AS description FROM ".$rel.", ".$cat." WHERE ".$cat.".id=".$rel.".category_id AND ".$rel.".record_id = ".$article_id." AND ".$rel.".category_lang = '".$this->language."'";
        $result = $this->db->query($query);
        $num = $this->db->num_rows($result);
        $categories = array();
        if ($num > 0) {
            while ($row = $this->db->fetch_assoc($result)) {
                $categories[] = $row;
            }
        }
        return $categories;
    }
Please beware that the hack for giving you TOP TEN entries for each category will add extra-load to your server compared to the PMF "standard" code so keep the number of categories low: perhaps 15 will be high for your server. If the "overload" will become an issue you could select some of them, among the 15, and rewrite the generateTopTen hacked function for cycling not through the whole of your cattegories.

natmanu wrote:Yes it would be great to also have RSS feeds per category. Thank you very much.
I hope to find spare time also for this hack :wink:
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Here is the hacked RSS feed

Post by matteo »

natmanu wrote:Yes it would be great to also have RSS feeds per category. Thank you very much.
Please locate, backup and open the [PATH_TO_PMFINSTALL]/feed/topten/rss.php, locate the $query variable declaration and replace it according to what written below:

Code: Select all

...
require_once (PMF_ROOT_DIR."/lang/".$PMF_CONF["language"]);

$query = 'SELECT DISTINCT '.SQLPREFIX.'faqdata.id AS id, '.SQLPREFIX.'faqdata.lang AS lang, '.SQLPREFIX.'faqdata.thema AS thema, '.SQLPREFIX.'faqcategoryrelations.category_id AS category_id, '.SQLPREFIX.'faqvisits.visits AS visits, '.SQLPREFIX.'faqdata.datum AS datum, '.SQLPREFIX.'faqvisits.last_visit AS last_visit FROM '.SQLPREFIX.'faqvisits, '.SQLPREFIX.'faqdata LEFT JOIN '.SQLPREFIX.'faqcategoryrelations ON '.SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqcategoryrelations.record_id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqcategoryrelations.record_lang WHERE ';
if (isset($_GET['cat']) && is_numeric($_GET['cat']) && ($_GET['cat'] != 0)) {
    $query .= SQLPREFIX.'faqcategoryrelations.category_id = \''.$_GET['cat'].'\' AND ';
}
if (isset($_GET['lang']) && PMF_Init::isASupportedLanguage($_GET['lang'])) {
    $query .= SQLPREFIX.'faqdata.lang = \''.$_GET['lang'].'\' AND ';
}
$query .= SQLPREFIX.'faqdata.id = '.SQLPREFIX.'faqvisits.id AND '.SQLPREFIX.'faqdata.lang = '.SQLPREFIX.'faqvisits.lang AND '.SQLPREFIX.'faqdata.active = \'yes\' ORDER BY '.SQLPREFIX.'faqvisits.visits DESC';

$result = $db->query($query);
...
This hack will give you the use of two optional HTTP GET parameters:
  1. cat, for filtering the feed result set with a category id: e.g.: /feed/topten/rss.php?cat=5;
  2. lang, for filtering the feed result set with a valid language code: /feed/topten/rss.php?lang=it.
Ciao,
Matteo
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

Post by natmanu »

Hi Matteo,

Sorry I’ve been out of circulation for a while; Thanks for the work you’ve done for me.

1.
The category top ten is working but not quite as intended :-) When on the faq index I want it to show a mix of all the categories in the top ten without separating them by headers, (top 10 from all categories, as it was before hack) It does so now but each category is separated by a header. This could create a very long list as more categories are added. I’d like all of these to be a mixed cat top ten at the faq index page level.

But when a user click on a category from the menu (reaching the cat index page) I would then like to show only that categories top10 and the same for all pages under it:
http://www.uvolunteer.org/faqs/index.ph ... show&cat=3
At the moment it only shows category top ten only when you further navigate to an actual faq page:
http://localhost/faqs/index.php?action= ... artlang=en

which is below the category index but not on the index it self.

2.
The rss feeds are not working, I’ve hacked the file as you asked me to and added the appropriate ending to the url when requesting the rss feed
$url = 'http://www.uvolunteer.org/faqs/feed/top ... .php?cat=5';

but nothing happened and it just shows me the feed as normal.

I also tried it with the language:

$url = 'http://www.uvolunteer.org/faqs/feed/top ... =5&lang=en';

But it still does not work.

This is how I’m dealing with the rss feed:
require_once('magpierss/rss_fetch.inc');
$url = 'http://www.uvolunteer.org/faqs/feed/top ... .php&cat=2';
$rss = fetch_rss($url);
echo "<ul>\n";
foreach ($rss->items as $item ) {
$string = $item[title];
$substr = strstr($string, '(');
$arr = split( '\('.$substr, $string );
$substr1 = trim($arr[0]);
$title = $substr1;
$views = $substr;
$url = $item[link];
echo "<li><a href=$url>$title</a><span class=\"views\">$views</span></li>\n";
}
echo "</ul>\n";
?>

I just copied and pasted those function as you instructed
We are nearly there, but not quite yet. Please, I hope I don’t sound ungrateful actually I’m very appreciative of your efforts.

Cheers
Nat
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Post by matteo »

Hi,
natmanu wrote:1.
[cut]
But when a user click on a category from the menu (reaching the cat index page) I would then like to show only that categories top10 and the same for all pages under it:
http://www.uvolunteer.org/faqs/index.ph ... show&cat=3
At the moment it only shows category top ten only when you further navigate to an actual faq page:
http://localhost/faqs/index.php?action= ... artlang=en

which is below the category index but not on the index it self.
now it sounds as a clear spec :wink:!
Please, use the generateTopTen() function below:

Code: Select all

function generateTopTen($language = '')
{
    global $PMF_LANG, $PMF_CONF, $tree, $cat;

    $output = "";
    foreach ($tree->categories as $category) {
        if (((0 != $cat) && ($cat == $category['id'])) || (0 == $cat)) {
            $result = generateTopTenData($language, PMF_NUMBER_RECORDS_TOPTEN, $category['id']);
            if (count($result) > 0) {
                $output .= "<ol><h3>".$category['name']."</h3>\n";
                foreach ($result as $row) {
                    $output .= "\t<li><strong>".$row['visits']." ".$PMF_LANG["msgViews"].":</strong><br />";
                    $output .= '<a href="'.$row['url'] . '">'.makeShorterText(PMF_htmlentities($row['thema'], ENT_NOQUOTES, $PMF_LANG['metaCharset']), 8)."</a></li>\n";
                }
                $output .= "</ol>\n";
            }
        }
    }
    if ('' == $output) {
        $output = $PMF_LANG["err_noTopTen"];
    }

    return $output;
}
and we'll reach your goal! :D
natmanu wrote:2.
The rss feeds are not working, I’ve hacked the file as you asked me to and added the appropriate ending to the url when requesting the rss feed
$url = 'http://www.uvolunteer.org/faqs/feed/top ... .php?cat=5';

but nothing happened and it just shows me the feed as normal.
Mmmhhh... IMHO it works like expected. Have you tried to open a browser and take a look e.g. at these urls below?As you'll see the XML content provided by the feed changes according to the the provided category id (in your case tha lang in unuseful or, maybe, reserved for future use).
Maybe it is an issue related to the RSS feed fetcher you're using, something like a local cache.
natmanu wrote:We are nearly there, but not quite yet. Please, I hope I don’t sound ungrateful actually I’m very appreciative of your efforts.
Time permitted I like any "challenge" with PMF: FYI, I'm using this scenario like a test case for QAing both PMF code and its powerful flexibility :wink:.

PS: If you make a diff from the original functions to those provided here by me, you'll see how little "and simple" changes drive PMF just to the user needs! :D
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

Post by natmanu »

Hi,

1. so far so good the only bug left in it is that when on the index page:
http://localhost/faqs/index.php?
&
ask/contact pages
http://localhost/faqs/index.php?action=ask

the top 10 is : cat1 then followed by cat 2 etc. I would like it on these pages (general pages 'not general cat, which is 1') to combine all the catergories top 10s. so it should be a list of top 10 from all catergories combined, don't seperated then by catergory here.
--
TOP 10
1. from cat1
2. from cat3
3. from cat 1
4. from cat 2
5. from cat2
--

2. you are right the rss feeds do work, i'm not sure why they are not behaving. I'll look more into it, I found the cache and set it to 0 for the mo.


Cheers, I'll let you know if i can fix the problem with the rss.
Nat
matteo
Posts: 572
Joined: Sun Nov 20, 2005 6:53 pm
Location: Italy

Post by matteo »

Hi,
I go ahead just for curiosity about the RSS fetcher class and your code snippet. There are at least 2 blocking errors in your code:
  1. Uncorrect management of HTTP GET parameters: you must use ? for separating the "main" URL from its query part and then use & ONLY if multiple HTTP GET parameters must be provided. See RFC 2396 for the complete hystory of an URI;
  2. Uncorrect use of the indexes of $items array.
Please, give a try to the code below:

Code: Select all

<?php
    require_once('magpierss/rss_fetch.inc');
    $url = 'http://www.uvolunteer.org/faqs/feed/topten/rss.php?cat=1';
    $rss = fetch_rss($url);
    echo "<ul>\n";
    foreach ($rss->items as $item ) {
        $string = $item['title'];
        $substr = strstr($string, '(');
        $arr = split( '\('.$substr, $string );
        $substr1 = trim($arr[0]);
        $title = $substr1;
        $views = $substr;
        $url = $item['link'];
        echo "<li><a href=$url>$title</a><span class=\"views\">$views</span></li>\n";
    }
    echo "</ul>\n";
Ciao,
Matteo
phpMyFAQ QA / Developer
Amazon.co.uk Wishlist
natmanu
Posts: 22
Joined: Wed May 24, 2006 7:07 pm

THE RSS FEED

Post by natmanu »

Hi Agian,

last one for tonight:-)

I tried runing the parser php file from the browser directly: It runs fine until I add the ending '&cat=2' then it bombs. I get this warning
--
Warning: MagpieRSS: Failed to fetch http://www.uvolunteer.org/faqs/feed/top ... .php&cat=3 (HTTP Response: HTTP/1.1 404 Not Found ) in /home/natt/public_html/includes/magpierss/rss_fetch.inc on line 238

Warning: Invalid argument supplied for foreach() in /home/natt/public_html/includes/cr_topten.php on line 8

--

it seems like it is trying to find a file called
http://www.uvolunteer.org/faqs/feed/top ... .php&cat=3

and can cannot find it. It is not running the script , i think!

and ideas? anyway i'll look more ito it 2mor. goodnight

Cheers
nNat
Post Reply