Extending phpWebSite for mobile access
I have been using phpWebsite in a couple of websites I am administering. It provides a complete content management system and has several modules you can use in order to customize the contents of your site. You can exclude features you don’t need and install only the ones you will use. Most of all, phpWebsite is free and developed using PHP, an HTML-embedded scripting language that I am familiar with.
Recently, I have been thinking of providing a text-only version of my websites so that the contents can also be viewed using web-enabled mobile phones or text-only browsers. What I want for the text-only version is to have an index page that will display the title of the most recent entries with links to the full article and an entry page that will display the full content of a given article.
I started searching the Internet for a third party phpWebSite module that would do the trick, but to no avail. Because of this, I decided to make one myself. Since I am not still familiar with the inner workings of phpWebSite and how its modules are organized, I decided to make a script that is independent from it, not a phpWebSite module. However, the script will still be pulling out data from the phpWebSite database and possibly recycle some of the pre-defined functions already available in the package. Hopefully, I can rewrite the script as a full-pledged module in the future. The script’s organization and code is summarized next.
There are three tasks the script should be able to handle: 1) connecting to the database, 2) retrieving the most recent entries from the database for the index page, and 3) retrieving the contents of a given article for the entry page. If the script is called with a parameter v, it will return the entry page of the article having an id specified by v. Otherwise, it will return the index page. So our simple script will have a structure that is something like this:
1. <? 2. db_connect($db); 3. if (isset($_REQUEST['v']) && is_numeric($_REQUEST['v'])) { 4. view_entry($db,$_REQUEST['v']); 5. } else { 6. get_current_entries($db); 7. } 8. db_disconnect($db); 9. ?>
In order to connect to phpWebSite’s database, we need to know the information necessary to access the database. This information is stored in the config.php file. Thus, this file should be loaded first before any attempt to access the database is made. The block of code to do this is as follows:
1. // get PWS installation directory 2. $pws = getPWSPath(); 3. 4. // get full path of the config.php file 5. $config = $pws."/conf/config.php"; 6. 7. // check if config.php exists, exit if not 8. file_exists($config) or die("Error loading page!"); 9. 10. // load config file 11. require($config); 12. 13. // set pear library's path to the included path 12. set_include_path(get_include_path() . ':' . $pws . '/lib/pear/'); 13. 14. // load pear's DB class in DB.php file 15. require_once('DB.php'); 16. 17. // form connection string. NOTE: $dbversion, $dbuser, etc. 18. // are specified in config.php 19. $conn = "$dbversion://$dbuser:$dbpass@$dbhost/$dbname"; 20. 21. // connect to the database 22. $db = DB::connect($conn);
Statements above starting with double slashes are comments, not part of the code. Basically, what the above code does is load config.php file (line 11) to get the information for the database connection such as $dbversion, $dbuser, etc., then load PEAR’s DB class (line 15) for database connection, and finally connect to the database (line 22). The first line retrieves the root path of phpWebSite installation via the function getPWSPath(), which you need to define. This function should return the full path where phpWebSite is installed. Line 12 is also very important so that the other PEAR classes included in DB.php can also be found and loaded. After line 22, a connection to the database is now established.
Next, we’ll retrieve the most recent entries from the database. This is the task of the function shown below with $db containing the connection information obtained using the above code.
1. function get_current_entries($db) { 2. global $table_prefix, $source_http; 3. $entries = ''; 4. 5. $sql = "SELECT id, title, updated_date FROM ". $table_prefix; 6. $sql .= "mod_article ORDER BY updated_date DESC LIMIT 10"; 7. 8. $res=$db->query($sql); 9. while($data = $res->fetchRow(DB_FETCHMODE_ASSOC)) { 10. $id=$data['id']; 11. $title=$data['title']; 12. $entries .= "<br><a href='http://${source_http}mobile.php?v=$id'>$title</a>"; 13. $entries .= "<br>updated on ".$data['updated_date'] ."<br>"; 14. } 15. if (!empty($entries)) { 16. $entries = "<h2>Recent Articles</h2><p>" . $entries . "</p>"; 17. } 18. return $entries; 19. }
Line 2 declares the variables $table_prefix and $source_http as global variables. These variables were loaded when config.php was loaded. The $entry variable is initialized in line 3. This variable will hold the output of this function, which is the list of the most recent entries and their corresponding links. In lines 5 and 6, a query statement is formed to search one of the tables in the article manager module for the most recent entries. Line 8 performs the actual query and the results are retrieved from line 9 to 14. If the result is not empty, a title is attached to the $entry variable. This is done in lines 15 to 17. Finally, the $entry variable is returned in line 18.
If an entry page is requested, we need to retrieve all the information for the requested entry. The function to do this is shown below. $db is the variable containing the connection information and $id is the id of the entry to retrieve.
1. function view_entry($db,$id) { 2. global $table_prefix; 3. $entry = ''; 4. 5. // retrieve article info 6. $sql = "SELECT * FROM ". $table_prefix; 7. $sql .= "mod_article WHERE id = ". $id; 8. $res = $db->query($sql); 9. 10. $data = $res->fetchRow(DB_FETCHMODE_ASSOC); 11. if ($data == NULL) { 12. $entry = "ERROR: Cannot retrieve information for entry id = $id"; 13. return $entry; 14. } 15. $order = unserialize($data['section_order']); 16. 17. $entry .= "<h2>" . $data['title'] . "</h2>"; 18. if (count($order)>0) { 19. $sql = "SELECT * FROM " . $table_prefix; 20. $sql .= "mod_article_sections "; 21. $sql .= "WHERE id IN (" . implode(',',$order) . ")"; 22. $res = $db->query($sql); 23. $body = ''; 24. while ($secData = $res->fetchRow(DB_FETCHMODE_ASSOC)) { 25. $body .= "<h3>".$secData['title']."</h3>"; 26. $body .= breaker($secData['text']); 27. } 28. if (!empty($body)) 29. $entry .= "<div>" . $body . "</div>"; 30. } 31. 32. // increment the number of hits 33. $sql = "UPDATE " . $table_prefix . "mod_article "; 34. $sql .= "SET hits=hits+1 WHERE id=".$id; 35. $res = $db->query($sql); 36. 37. return $entry; 38. }
In line 2, we again include the global variables $table_prefix for use within the function. Next, all entries in the mod_article table associated to the given id are retrieved (lines 6 to 10). Using the information in the section_order entry extracted in line 15, the contents of all sections are then retrieved (line 18 to 27). The hit counter is incremented in lines 33 to 35. Finally, the content is returned in the $entry variable. Note the presence of the breaker function in line 26 that you need to define. Its function is to convert line breaks to <br>.
This basically completes the script. Click here to download the full script. And here for a working example. Enjoy!