Experience with PHPWCMS, Request for features and better lan

Use GitHub to post feature requests for phpwcms.
Locked
Nik2004
Posts: 132
Joined: Mon 9. Aug 2004, 14:31
Location: Athens,Greece

Experience with PHPWCMS, Request for features and better lan

Post by Nik2004 » Thu 16. Mar 2006, 23:04

Hi, Oliver and everyone.

I've been using PHPWCMS for over 2 years now, and I am very fond of it. Great job. I decided to send this "report" in order to help you in creating better newer versions of this very good CMS. I hope it helps. I know many (if not all) of the feature requests have already been asked, but I thought I should post all of that here, for completeness purposes.

I have not managed to follow the CVS versions, because I have had to make some hacks which I cannot repeat often... So, I am still using phpwcms_1.1-RC4_2004-06-22. You can view my site (of a Greek non profit organization) here: http://www.unborn.gr

However, I would like to post my experience and to request the inclusion of some features. Sorry if some of these features are already included in later versions, I cannot be sure of that.

1. Use of articles in any page:

I would like to have the ability to display some articles from a particular category anywhere, using a desired template. So, I would need a tag like: {CUSTOMARTICLELIST : CATEGORY : NO_OF_ARTICLES : SORT_METHOD : TEMPLATE}. This would allow someone to display individual articles in the homepage and elsewhere. Currently, I am using the trick described here: http://www.phpwcms.de/forum/viewtopic.php?t=1049but this is not a very convenient/robust solution and it does not scale well. In my opinion, this is one of the most important features missing from PHPWCMS. Also, the above trick does not work very well with VTS, and the stats are distorted because all calls on article items used with {PHP: } appear as separate hits (by the site's domain) and not ignored as they should, since they are internal calls.

2. Search content part:

A. I would like to be able to define some categories as not searchable, because I don't want the search system to locate articles used for a particular purpose (temporary, test articles, those used with the trick described above to display particular articles - since these are used with a blank template and, if found, they cannot be displayed correctly, in the context of the site, etc.). I have done this by adding a field (for example cat_search) in the articlecat db table, which takes the values of 0/1. Currently I have to set this value directly in the database.

B. Greek language was not supported properly. So I had to do the following changes (sorry if programming is poor, I' m not a programmer):

In /include/inc_front/front.func.inc.php I have added the following function:

Code: Select all

function grchars_replace($text) {

    // convert all greek chars to lower case, non-accented ones for search ****

    $text = str_replace(chr(220), chr(225), $text);
    $text = str_replace(chr(193), chr(225), $text);
    $text = str_replace(chr(182), chr(225), $text);
    $text = str_replace(chr(194), chr(226), $text);
    $text = str_replace(chr(195), chr(227), $text);
    $text = str_replace(chr(196), chr(228), $text);
    $text = str_replace(chr(197), chr(229), $text);
    $text = str_replace(chr(184), chr(229), $text);
    $text = str_replace(chr(221), chr(229), $text);
    $text = str_replace(chr(198), chr(230), $text);
    $text = str_replace(chr(199), chr(231), $text);
    $text = str_replace(chr(185), chr(231), $text);
    $text = str_replace(chr(222), chr(231), $text);
    $text = str_replace(chr(200), chr(232), $text);
    $text = str_replace(chr(201), chr(233), $text);
    $text = str_replace(chr(186), chr(233), $text);
    $text = str_replace(chr(218), chr(233), $text);
    $text = str_replace(chr(223), chr(233), $text);
    $text = str_replace(chr(250), chr(233), $text);
    $text = str_replace(chr(192), chr(233), $text);
    $text = str_replace(chr(202), chr(234), $text);
    $text = str_replace(chr(203), chr(235), $text);
    $text = str_replace(chr(204), chr(236), $text);
    $text = str_replace(chr(205), chr(237), $text);
    $text = str_replace(chr(206), chr(238), $text);
    $text = str_replace(chr(207), chr(239), $text);
    $text = str_replace(chr(188), chr(239), $text);
    $text = str_replace(chr(252), chr(239), $text);
    $text = str_replace(chr(208), chr(240), $text);
    $text = str_replace(chr(209), chr(241), $text);
    $text = str_replace(chr(211), chr(243), $text);
    $text = str_replace(chr(242), chr(243), $text);
    $text = str_replace(chr(212), chr(244), $text);
    $text = str_replace(chr(213), chr(245), $text);
    $text = str_replace(chr(219), chr(245), $text);
    $text = str_replace(chr(190), chr(245), $text);
    $text = str_replace(chr(253), chr(245), $text);
    $text = str_replace(chr(251), chr(245), $text);
    $text = str_replace(chr(224), chr(245), $text);
    $text = str_replace(chr(214), chr(246), $text);
    $text = str_replace(chr(215), chr(247), $text);
    $text = str_replace(chr(216), chr(248), $text);
    $text = str_replace(chr(217), chr(249), $text);
    $text = str_replace(chr(191), chr(249), $text);
    $text = str_replace(chr(254), chr(249), $text);

    return $text;
}
In include/inc_front/content/cnt13.article.inc.php (Here are included the changes for making some categories non searcheable and call of the above function to make greek character search possible):

Lines 40-46 (those containing the query) are replaced by the following:

Code: Select all

    $content["search_word"] = grchars_replace($content["search_word"]);
   
// new query to exclude article categories designated as non-searcheable
   
    $sql   = "SELECT  A.* , UNIX_TIMESTAMP(article_tstamp) AS article_date ";
    $sql  .= "FROM ".DB_PREPEND."phpwcms_article A, ".DB_PREPEND."phpwcms_articlecat B ";
    $sql  .= "WHERE A.article_public =1 AND A.article_aktiv =1 AND A.article_deleted =0 ";
    $sql  .= "AND A.article_begin < NOW(  ) AND A.article_end > NOW(  ) ";
    $sql  .= "AND B.cat_search =1 ";
    $sql  .= "AND A.article_cid = B.acat_id ";
    $sql  .= "ORDER  BY A.article_cid, A.article_sort, A.article_tstamp DESC ;";
The following lines:

Code: Select all

        preg_match_all(    "/".$content["search_word"]."/i",
    clean_replacement_tags($s_text.' '.$srow["article_keyword"].' '.$s_title.' '.$s_user),
    $s_result); //search string
become:

Code: Select all

        preg_match_all(    "/".$content["search_word"]."/i",
    grchars_replace(clean_replacement_tags($s_text.' '.$srow["article_keyword"].' '.$s_title.' '.$s_user)),
    $s_result); //search string
C. Finally some comments:

* Pre-indexing: Search (as I am sure you know) should better be based on a pre-indexed list, otherwise the search mechanism will be extremely CPU intensive if many searches are conducted concurrently. I hope next versions will be upgraded to this mode of operation. Alternatively, MySQL's very powerful full-text search could be used in the back-end.
* Paging: Results should be displayed in pages of a selectable number of items.
* "Smart" Result summary: In the summary of each result, the located keyword should be included, so the user can decide whether the result is pertinent or not.

3. Support of Greek language:

* Codepage (ISO-8859-7) is not correctly automatically selected in all parts of the application. I had to manually change the default encoding in various places (for example in PHPMailer).
* Localization: A lot of pieces of text had to be manually edited so that Greek text could be used (e.g. in the form mail application). So, there are no localization files that include all system messages, as one would expect. For example, in cnt18.article.inc.php there is a hard-coded message in English. This means that if someone wants localized messages, (s)he must search all files, locate messages and localize them in the source code. This makes upgrade a nightmare.
* I am posting here the Greek localization files I used for the formmailer (bottom of message). Note that I have been a professional in localization, so this piece of work is good enough to be included in future versions of phpwcms.

4. Ability to display articles sorted by different criteria. Last-edit-date (the default behaviour) is not the best criterion, in my humble opinion. I have been obliged to alter the code to use the start_date as the main sorting criterion. Here is how: in /include/inc_front/front.func.inc.php, I change:

Code: Select all

function get_articles_data ($dbcon) {
    //returns the complete active and public article data as array (basic infos only)
    //so it is reusable by many functions -> lower db access
   
    $sql  = "SELECT *, UNIX_TIMESTAMP(article_tstamp) AS article_date FROM ".DB_PREPEND."phpwcms_article ";
    $sql .= "WHERE article_public=1 AND article_aktiv=1 AND article_deleted=0 ";
    $sql .= "AND article_begin<NOW() AND article_end>NOW() ";
    $sql .= "ORDER BY article_cid, article_sort, article_tstamp DESC;";
with

Code: Select all

function get_articles_data ($dbcon) {
    //returns the complete active and public article data as array (basic infos only)
    //so it is reusable by many functions -> lower db access
   
    $sql  = "SELECT *, UNIX_TIMESTAMP(article_tstamp) AS article_date FROM ".DB_PREPEND."phpwcms_article ";
    $sql .= "WHERE article_public=1 AND article_aktiv=1 AND article_deleted=0 ";
    $sql .= "AND article_begin<NOW() AND article_end>NOW() ";
    $sql .= "ORDER BY article_cid, article_sort, article_begin DESC;";
And:

Code: Select all

function get_actcat_articles_data ($act_cat_id, $dbcon) {
    //returns the complete active and public article data as array (basic infos only)
    //so it is reusable by many functions -> lower db access
   
    $sql  = "SELECT *, UNIX_TIMESTAMP(article_tstamp) AS article_date FROM ".DB_PREPEND."phpwcms_article ";
    $sql .= "WHERE article_cid=".intval($act_cat_id)." AND article_public=1 AND article_aktiv=1 AND article_deleted=0 ";
    $sql .= "AND article_begin<NOW() AND article_end>NOW() ";
    //$sql .= "ORDER BY article_cid, article_sort, article_tstamp DESC;";
    $sql .= "ORDER BY article_sort, article_tstamp DESC;";
with

Code: Select all

function get_actcat_articles_data ($act_cat_id, $dbcon) {
    //returns the complete active and public article data as array (basic infos only)
    //so it is reusable by many functions -> lower db access
   
    $sql  = "SELECT *, UNIX_TIMESTAMP(article_tstamp) AS article_date FROM ".DB_PREPEND."phpwcms_article ";
    $sql .= "WHERE article_cid=".intval($act_cat_id)." AND article_public=1 AND article_aktiv=1 AND article_deleted=0 ";
    $sql .= "AND article_begin<NOW() AND article_end>NOW() ";
    //$sql .= "ORDER BY article_cid, article_sort, article_tstamp DESC;";
    $sql .= "ORDER BY article_sort, article_begin DESC;";
Also the arrows used to reposition articles (in the admin Article tree) are not practical: I would find it better to have the "priority" field (article_sort) with a value (default 0) which would be directly manually edited (in the admin Article tree, in an input field) with a higher value, to bypass the automatic sorting setting. As is now, by using the arrows, the administrator often loses control, or has to click the arrows all the time and wait forever esp. when the No. of articles is large.

I would also propose to have the user decide whether the sorting of articles (anywhere where a list of articles is displayed) should be based on the article_tstamp or on the article_begin field in parallel with article_sort (as is now). I've seen a lot of phpwcms users prefer article_begin as the main criterion.

5. Guestbook: The administrator should be able to moderate the messages. Now, to make it work as I want, I have modified the source code to keep new messages in the database with an initial value of 9 for the field guestbook_trashed. Then, I have to manually examine and directly change the value to 0 in the database, to make it visible. Here is the code, in /include/inc_front/content/cnt18.article.inc.php:

Code: Select all

        $guestbook['sql']  = "INSERT INTO ".DB_PREPEND."phpwcms_guestbook SET ";
        $guestbook['sql'] .= "guestbook_cid='".intval($crow["acontent_id"])."', ";
        $guestbook['sql'] .= "guestbook_msg='".substr(aporeplace($guestbook['post']['msg']),0,1000)."', ";
        $guestbook['sql'] .= "guestbook_name='".substr(aporeplace($guestbook['post']['name']),0,50)."', ";
        $guestbook['sql'] .= "guestbook_email='".substr(aporeplace($guestbook['post']['email']),0,100)."', ";
        $guestbook['sql'] .= "guestbook_created='".time()."', ";
        $guestbook['sql'] .= "guestbook_trashed=9,";
        $guestbook['sql'] .= "guestbook_url='".substr(aporeplace($guestbook['post']['url']),0,50)."';";
        mysql_query($guestbook['sql'], $db);
6. Inclusion of a Web Site Statistics system. I have managed to integrate VTS with my PHPWCMS installation, and it is valuable, but far from ideal. Something more powerful and out of the box would be needed.

7. Style assignments: A lot of items (e.g. input fields in forms [guestbook, newsletter, search]) have not styles assigned to them, so customization has been hard at times. I have been obliged to manually edit a lot of items to add CSS style assignments.

8. Ability to break long articles in pages. The article author should be able to define {PAGE BREAK} either manually on an ad hoc basis, or automatically, when, for example, the article is longer than the value of a configured parameter. Then, when the article is displayed, the article would automatically have page numbers/links (on top and bottom) which would allow navigation to previous/next page of article.

9. The formmailer content part, I would prefer if the success/error pages were running in the context of the site, rather than in separate ("out of site") pages. This creates a feeling of "non-integration".

10. In the Newsletter content-part, I would prefer if the system could acknowledge the click on the email verification link by a message in a specially-prepared page of the site, rather than saying "you have been verified... you will be redirected"... to the homepage. Also, I would like the system to send an email to the user at this point (with a content I would decide).

11. Login on the user side: ability to have users create personal accounts and offer services to subscribers only.

This list is not exhaustive, but I believe I have included most important things I had in mind. Again thanks for a great system.

Files:

Code: Select all

GR_formmailer.success.html:
--------------------------------------
<html>
<head>
<title>Σύστημα Επεξεργασίας Ηλεκτρονικών Φορμών | Επιτυχία</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
<style type="text/css">
<!--
body, td, tr, p { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px;}
.head {font-size: 14px; color: #92A1AF;}
.error {color: #990000;}
.tblhead {font-size: 9px; color: #A4A4A4;}
.tblhead a, .tblhead a:link, .tblhead a:active, .tblhead a:visited, .tblhead a:hover {color: #A4A4A4; text-decoration: none;}
-->
</style>
</head>

<body bgcolor="#FFFFFF" text="#000000" link="#FF6600" vlink="#FF9900" alink="#FF6600" leftmargin="10" topmargin="10" marginwidth="10" marginheight="10">
<span class="head"><strong>Ευχαριστούμε!</strong></span><br />
<br />
<strong>Όλα τα απαιτούμενα πεδία συμπληρώθηκαν σωστά.</strong><br />

Είμαστε στη διάθεσή σας για οτιδήποτε χρειαστείτε.

Για κάθε τεχνικό πρόβλημα, απευθυνθείτε στον webmaster.<br />
<br /><br />
<strong>Η φόρμα συμπληρώθηκε ως εξής:</strong><br />
<br />
<table border="0" cellpadding="3" cellspacing="1" bgcolor="#D1D1D1">
<tr bgcolor="#E6E6E6">
<td class="tblhead">Πεδίο:</td>
<td class="tblhead">Δεδομένα:</td>
</tr>
<!-- RESULT //-->
</table>
<br /><br />
[<a href="javascript:history.back();"><strong>Επιστροφή</strong></a>]<br />
<br /><br />
<hr size="1" noshade style="color: #A4A4A4;">
<span class="tblhead">Σύστημα Επεξεργασίας Ηλεκτρονικών Φορμών |  Copyright &copy; 2004</span>
</body>
</html>
----------------------------------------------------
GR_formmailer.error.html:
----------------------------------------------------
<html>
<head>
<title>Σύστημα Επεξεργασίας Ηλεκτρονικών Φορμών | Σφάλμα</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
<style type="text/css">
<!--
body, td, tr, p { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px;}
.head {font-size: 14px; color: #92A1AF;}
.error {color: #990000;}
.tblhead {font-size: 9px; color: #A4A4A4;}
.tblhead a, .tblhead a:link, .tblhead a:active, .tblhead a:visited, .tblhead a:hover {color: #A4A4A4; text-decoration: none;}
-->
</style>
</head>

<body bgcolor="#FFFFFF" text="#000000" link="#FF6600" vlink="#FF9900" alink="#FF6600" leftmargin="10" topmargin="10" marginwidth="10" marginheight="10">
<span class="head"><strong>Σφάλμα κατά την αποστολή της φόρμας!</strong></span><br />
<br />
<strong>Πιθανώς να μην έχετε συμπληρώσει όλα τα απαιτούμενα πεδία.</strong><br />
Παρακαλούμε ελέγξτε τα στοιχεία, λαμβάνοντας υπ' όψιν τα παρακάτω. <a href="javascript:history.back();"><strong>Κάντε κλικ εδώ</strong></a> ή χρησιμοποιήστε το κουμπί επιστροφής του προγράμματος περιήγησης στο Internet που χρησιμοποιείτε. Εάν προκύψουν τεχνικά
προβλήματα, παρακαλούμε επικοινωνήστε με τον webmaster.<br />
<br />
<table border="0" cellpadding="3" cellspacing="1" bgcolor="#D1D1D1">
<tr bgcolor="#E6E6E6">
<td class="tblhead">Σφάλμα</td>
<td class="tblhead">Περιγραφή</td>
</tr>
<!-- RESULT //-->
</table>
<br /><br />
[<a href="javascript:history.back();"><strong>Επιστροφή στη φόρμα</strong></a>]<br />
<br /><br />
<hr size="1" noshade style="color: #A4A4A4;">
<span class="tblhead">Σύστημα Επεξεργασίας Ηλεκτρονικών Φορμών |  Copyright &copy; 2004</span>
</body>
</html>
------------------------------------------------------------------------
In lang.formmailer.inc.php: 
-------------------------------------------------------------------------
// Greek
$translate["GR"]["error100"]		= "Η διεύθυνση του παραλήπτη περιέχει λάθος";
$translate["GR"]["error200"]		= "Δεν υπάρχει θέμα!";
$translate["GR"]["error300"]		= "Εσφαλμένη ηλ. διεύθυνση για την αποστολή μηνύματος επιβεβαίωσης.";
$translate["GR"]["error400"]		= "Συμπληρώστε το πεδίο ###value###.";
$translate["GR"]["dateFormat"]		= "Y-m-d";
$translate["GR"]["timeFormat"]		= "H:i:s";
$translate["GR"]["bodyLine1"]		= "Η φόρμα εστάλη την: ###date###, ###time###";
$translate["GR"]["bodyLine2"]		= "Μπορείτε να βρείτε την φόρμα εδώ: ";
$translate["GR"]["bodyRecipient"]	= "Παραλήπτης: ";
-------------------------------------------------------------------------------------
[/code]

Locked