Courses/CS 491ab/Winter 2008/Madhavi Nidamarthy

From CSWiki

Jump to: navigation, search

Nidamarthy

Contents

[edit] Week 1 - January 4, 2008

Introduction class. Started researching existing frameworks on MVC based Web applications.

[edit] Week 2 - January 11, 2008

Platform: Spring Framework (or Spring for short) is an open source application framework for the Java platform.

  • The Springs MVC framework is designed to help developers create web applications that utilize a MVC architecture.One of the design goals of the Spring Framework is to easily integrate with existing J2EE standards and vendor tools.
  • The goal of the MVC design pattern is to separate the application object (model) from the way it is represented to the user (view) from the way in which the user controls it (controller).

I did 2-tier Web applications in CS320 course. Web applications based on JavaServer Pages commingle database code(using jstl taglibrary<sql> in jsp), page design code, and control flow code. In Larger applications,these concerns are separated.

Project Idea: Online defect (bug) tracking system which useful for applications developed in an organization. This system can be used for logging bugs against an application/module, assigning bugs to individuals and tracking the bugs to resolution. Preparing Project Proposal document to get a rough idea of the Project.

I want to explore MVC framework for my project. I use NetBeans 5.5 IDE for java applications. This week I am working on Spring MVC framework.

Download & Plugin in NetBeans IDE:

  • Download "net-sf-springnetbeans-support.zip" file & Save it to my local directory and rename it to:

"net-sf-springnetbeans-support.nbm".

  • Open NetBeans IDE.
  • At the tool menu, select Tools --> Update Center
  • At new Update Center Wizard, select:

Install Manually Downloaded Modules (.nbm files)

  • At new window, use "Add" button to locate "net-sf-springnetbeans-support.nbm" file.

Click Next. Step through the following few screens.

  • Select "Yes" at "Unsigned Module dialog"

After installing Spring to my PC. I am able to run few steps of Spring Framework MVC application step-by-step example given in www.springframework.org(Documentation->Tutorials). What I observed is Spring will take care of MVC flow.

Example:Spring starts following flow with this code:

  • web.xml -> The web.xml file(XML schema document) provides configuration and deployment information for the Web components that comprise a Web application. This file reside in the WEB-INF directory under the context of the hierarchy of directories that exist for a Web application. In web.xml file-> welcome-file-list element contains an ordered list of welcome-file elements. <welcome-file> : File name(index.jsp) to use as a default welcome file.
   <welcome-file-list>
           <welcome-file>
           index.jsp
       </welcome-file>
   </welcome-file-list>
  • index.jsp -> Here its redirecting
  <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
  <c:redirect url="/hello.htm" />
  • servlet_name-servlet.xml: This is the file where definitions used by the DispatcherServlet should be entered. Adding a bean entry which defines the controller that our application will be using. We also need to add a url mapping so the DispatcherServlet knows which controller should be invoked for different url:s.We have to follow standard naming convention used in the Spring Framework. viewResolver is to avoid having to type out the full path to a JSP inside of my Controller code.
<beans>    
   <bean id="springappController" class="web.SpringappController"/> 
   <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
       <property name="mappings">       
           <props>           
               <prop key="/hello.htm">springappController</prop>  
           </props>      
       </property>  
       </bean>  
       
 // The goal is to avoid having to type out the full path to a JSP inside of my Controller code.
  
       <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
       <property name="prefix"><value>/WEB-INF/jsp/</value></property>
       <property name="suffix"><value>.jsp</value></property>
   </bean>
</beans>        
  • Controller -> From above code of urlMapping goes to web.SpringappController.java implements BasicContoller interface. The Controller interface defines a single method signature handleRequest().The Controller “handles” the request and returns a ModelAndView. The object that is returned by the handleRequest method is of the type ModelAndView.This ModelAndView has several contructors. The one I am using right now just takes a string that represents the view that we want to forward to.
  public class SpringappController implements Controller
{
   
       public SpringappController()
   {
   }
   
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception
   {
       String now = (new java.util.Date()).toString();   
       return new ModelAndView("hello", "now", now);
  }
}   
  • View -> hello.jsp : I am just retreving String now through Expression Language. ${now}
 <html>
   <head>
       <title>Hello :: Spring Application</title>
   </head>
   <body>
  • Run Project in IDE:
Hello - Spring Application
Greetings, it is now Fri Jan 11 14:03:15 PST 2008 


Next Week : I want to add bussiness logic(model layer) and test it.

[edit] Week 3 - January 18, 2008

This week I continued my work on Spring MVC framework by adding business logic to an already existing application. A Product class and a class that will manage all the products is ProductManager in a package bus.

public class Product
{
   private String description; 
   private Double price;    
   public void setDescription(String s)
   {       
       description = s;    
   }
   
   public String getDescription()
   {       
       return description;    
   }    
       public void setPrice(Double d)
   {       
       price = d;  
   }
       public Double getPrice() 
   { 
       return price;  
   }        
}
  • ProductManager.java : Holds a list of Products. The increasePrice method is a cross the board increase based on the percentage passed in to the method.
public class ProductManager implements Serializable 
{
   private List products; 
   public void setProducts(List p)
   {        
       products = p; 
   }   
   
   public List getProducts()
   {        
       return products; 
   }  
   
   public void increasePrice(int pct)
   {
       ListIterator li = products.listIterator();
       
       while (li.hasNext()) 
       {
           Product p = (Product) li.next();
           double newPrice = p.getPrice().doubleValue() * (100 + pct)/100;
           p.setPrice(new Double(newPrice));
       }       
   }    
}
  • SpringappController.java : Controller pass some product information to the view. The getModelAndView now returns a Map with both the date and time and the product manager reference.
public class SpringappController implements Controller
{
       private ProductManager prodMan;    
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception
   {
       String now = (new java.util.Date()).toString();   
       Map myModel = new HashMap();
       myModel.put("now", now);
       myModel.put("products", getProductManager().getProducts());
       return new ModelAndView("hello", "model", myModel);    
  }
   public void setProductManager(ProductManager pm) {
       prodMan = pm;
   }
  public ProductManager getProductManager() {
       return prodMan;
   }
}
  • springapp-servlet.xml: A couple of instances using Spring's bean and application context support. Add data(business objects) in bean entries as there is no database.
     <bean id="product1" class="bus.Product">
       <property name="description"><value>Lamp</value></property>
       <property name="price"><value>5.75</value></property>
   </bean>
   <bean id="product2" class="bus.Product">
       <property name="description"><value>Table</value></property>
       <property name="price"><value>75.25</value></property>
   </bean>
   <bean id="product3" class="bus.Product">
       <property name="description"><value>Chair</value></property>
       <property name="price"><value>22.79</value></property>
   </bean>


  • hello.jsp: Displays product information with date & time.
 <c:out value="${model.now}"/>Products
           <c:forEach items="${model.products}" var="prod">
       <c:out value="${prod.description}"/> $<c:out value="${prod.price}"/>

</c:forEach>
  • priceincrease.jsp: The <spring:bind>(in order for the databinding functionality to be able to bind the properties again when submitting for instance a form) tag is used to bind an <input> form element to a command object PriceIncrease.java, that is used together with the form. This command object is later passed in to the validator(PriceIncreaseValidator) and if it passes validation it is passed on to the controller. The ${status.errorMessage}( an array of error messages, resulting from validation) and ${status.value}( the actual value of the bean or property) are special variables declared by the framework that can be used to display error messages and the current value of the field.
      <form method="post">
                    <spring:bind path="priceIncrease.percentage"> 
                        <input type="text" name="percentage" value="${status.value}"/>    
                        <c:out value="${status.errorMessage}"/> 
              </spring:bind>   
 
  • PriceIncrease.java:
 public class PriceIncrease {
  private int percentage;
   public void setPercentage(int i) {
       percentage = i;
          }
   public int getPercentage() {
       return percentage;
   } }
  • PriceIncreaseValidator.java: The validator class gets control after the user presses submit. The values entered in the form will be set on the command object by the framework. The method validate is called and the command object and an object to hold any errors are passed in.


public class PriceIncreaseValidator implements Validator {
   private int DEFAULT_MIN_PERCENTAGE = 0;
   private int DEFAULT_MAX_PERCENTAGE = 50;
   private int minPercentage = DEFAULT_MIN_PERCENTAGE;
   private int maxPercentage = DEFAULT_MAX_PERCENTAGE;
       public void validate(Object obj, Errors errors) {
       PriceIncrease pi = (PriceIncrease) obj;
       if (pi == null) {
           errors.rejectValue("percentage", "error.not-specified", null, "Value required.");
       }
       else {
           logger.info("Validating with " + pi + ": " + pi.getPercentage());
           if (pi.getPercentage() > maxPercentage) {
               errors.rejectValue("percentage", "error.too-high",
                   new Object[] {new Integer(maxPercentage)}, "Value too high.");
           }
           if (pi.getPercentage() <= minPercentage) {
               errors.rejectValue("percentage", "error.too-low",
                   new Object[] {new Integer(minPercentage)}, "Value too low.");
           }
       }
   }
   }
  • springapp-servlet.xml file to define the new form and controller(PriceIncreaseFormController) in urlMapping.

We define properties for command object and validator. We also specify two views, one that is used for the form and one that we will go to after successful form processing.

<bean id="priceIncreaseValidator" class="bus.PriceIncreaseValidator"/>
   <bean id="priceIncreaseForm" class="web.PriceIncreaseFormController">
       <property name="sessionForm"><value>true</value></property>
       <property name="commandName"><value>priceIncrease</value></property>
       <property name="commandClass"><value>bus.PriceIncrease</value></property>
       <property name="validator"> //ref bean property
       <property name="formView"><value>priceincrease</value></property>
       <property name="successView"><value>hello.htm</value></property>
       <property name="productManager">
           //ref bean property
       </property>
   </bean>


  • PriceIncreaseFormController.java : The onSubmit method gets control and does some logging before it calls the increasePrice method on the ProductManager object. It then returns a ModelAndView passing in a new instance of a RedirectView created using the url for the successView.
public class PriceIncreaseFormController extends SimpleFormController {
   private ProductManager prodMan;
   public ModelAndView onSubmit(Object command)
           throws ServletException {
       int increase = ((PriceIncrease) command).getPercentage();
       prodMan.increasePrice(increase);
       String now = (new java.util.Date()).toString();
        return new ModelAndView(new RedirectView(getSuccessView()));
   }
public void setMinPercentage(int i) {
       minPercentage = i;
   }
   public int getMinPercentage() {
       return minPercentage;
   }
   public void setMaxPercentage(int i) {
       maxPercentage = i;
   }
   public int getMaxPercentage() {
       return maxPercentage;
   }
}

Build application & able to run by adding model(bussines logic), views(hello.jsp,priceincrease.jsp) passes to controller after validations. Controller forwarded to success view. Prices of Products are increased & displays them.

[edit] Week 4 - January 25, 2008

Last week, Proffessor Russ Abbott suggested me to do 'user-accessible database capability to MediaWiki' Project. In cswiki:[Russ Abbott/Project_ideas ]

Project Idea  : Add a user-accessible database capability to MediaWiki. It allows allow a user to include something like an SQL query in a MediaWiki page. That query would be expanded and the resulting table inserted into the page where the query was found.

My previous Project idea was to do 'Defect Tracking System' in MVC framework as I mentioned in earlier weeks. After taking advise from Prof. Abbott, I am very much interested to do 'user-accessible database capability to MediaWiki' project. As, MediaWiki is a PHP web application. I am completely new to PHP Scripting language. I started downloading PHP, Apache.

Installation PHP under Windows:

Download latest version from php-5.2.5. Unzip it to local folder.

To run PHP we need Apache web server, a web server basically serves web pages from the server to the client browser.

Installation Apache web server:

Download Apache from Apache 2.2. I downloaded from this binary: Win32 Binary including OpenSSL 0.9.8g (MSI Installer). Install it to Program files/Apache Http Server 2.2

1. Set Environment variables as variable & value to C:\Program Files\Apache Software Foundation\Apache2.2

2. Copy php5ts.dll, php5apache2.dll, php.ini-recommended files to C:\Program Files\Apache Software Foundation\Apache2.2

3. Rename php.ini-recommended to php.ini and open it in notepad.

Search for 'doc_root' until you find the line:

doc_root =

Change this line to:

doc_root = C:\Program Files\Apache Software Foundation\Apache2.2\htdocs

4.Open the file httpd.conf in notepad. Httpd.conf can be found in: C:\Program Files\Apache Software Foundation\Apache2.2\conf\; add the following lines to the end of the file:

LoadModule php5_module php5apache2_2.dll

AddType application/x-httpd-php .php

5. Test PHP: To test that PHP has been correctly installed click ‘Start > All Programs > Apache > Configuration > Test Configuration’. A console window should show briefly then disappear, if this happens then everything is ok, it if stays, take note of any errors and makes sure you haven’t missed any of the instructions above.

6. Restart Apache: For all the changes to take effect, and Apache to recognize PHP, Apache must be restarted. To do this click ‘Start > All Programs > Apache > Control > Restart’.

<?php
 echo 'PHP is working.';
 echo phpinfo();
?>

Save test.php file in doc root (C:\Program Files\Apache Software Foundation\Apache2.2\htdocs).

Databse Server : Downolad from Mysql Supported MySQL 4.1

PHP + MySQL :

  • PHP combined with MySQL are cross-platform (means that you can develop in Windows and serve on a Unix platform)


PHP Scripting Language Inroduction:

  • PHP(Hypertext PreProcessor) is a server-side scripting language.
  • PHP scripts are executed on the server.
  • PHP supports many databases (MySQL, Informix, Oracle, Sybase, Solid, PostgreSQL, Generic ODBC, etc.)
  • PHP is an open source software (OSS)

Javascript vs PHP

  • A server-side scripting language is similar to JavaScript in many ways, as they both allow you to embed little programs (scripts) into the HTML of a Web page.
  • The key difference between JavaScript and PHP is that, while the Web browser interprets JavaScript once the Web page containing the script has been downloaded, server-side scripting languages like PHP are interpreted by the Web server before the page is even sent to the browser. Once interpreted, the PHP code is replaced in the Web page by the results of the script, so all the browser sees is a standard HTML file. The script is processed entirely by the server. Thus the designation: server-side scripting language.

Example :

<HTML><HEAD>
<TITLE>Today's Date</TITLE>
</HEAD>
<BODY>Today's Date (according to this Web server) is <?php echo( date("l, F dS Y.") ); ?>
</BODY></HTML> 

Most of this is plain HTML. The line between <?php and ?>, however, is written in PHP. <?php means "begin PHP code", and ?> means "end PHP code". The Web server is asked to interpret everything between these two delimiters and convert it to regular HTML code before sending the Web page to a browser that requests it . The browser is presented with something like this:

<HTML> <HEAD>
<TITLE>Today's Date</TITLE>
</HEAD>
<BODY>Today's Date (according to this Web server) is Thursday, January 24th 2008. 
</BODY></HTML>

Notice that all signs of the PHP code have disappeared. In their place, the output of the script has appeared and looks just like standard HTML.

This example demonstrates several advantages of server-side scripting:


  • No browser compatibility issues. PHP scripts are interpreted by the Web server and nothing else, so no worries about whether the language you're using will be supported by your visitors' browsers.
  • Access to server-side resources. In the above example, we place the date according to the Web server into the Web page. If we had inserted the date using JavaScript, we would only be able to display the date according to the computer on which the Web browser was running.
  • Reduced load on the client. JavaScript can significantly slow down the display of a Web page on slower computers, as the browser must run the script before it can display the Web page. With server-side scripting, this becomes the burden of the Web server machine to bear.

Practicing PHP by running other programs.

[edit] Week 5 - February 1, 2008

I focused this week how MediaWiki works and able to create a Special Page plugin.

Steps to install MediaWiki:

  • Download current version from this link mediawiki-1.11.1.tar.gz. Download a package. Current version: mediawiki-1.11.1.tar.gz.
  • Extract all files in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs folder.
  • Now Site Config : http://localhost/mediawiki-1.11.1/config/: Under the Site config section I am able to choose a name for my wiki, to set up a contact mail, to choose a language and license, to set an admin username and password and to select a caching method.
  • Database config:

In the Database config section: For Database type I selected MySQL. For Database host: localhost. In the fields for database name, user and password enter the MySQL database, username and password that already created during the database setup.

  • If everything has been set up correctly, then we will get Installation successful message. Checking for Environment variables.
  • Then move the file LocalSettings.php from the config/ folder to your main wiki folder.

LocalSettings.php : The file provides local configuration settings (based on the DefaultSettings.php file) of a MediaWiki installation. Changing a setting usually means changing the value of a PHP variable

Now I am able to set up in my PC like calstatela cswiki.

  • To enable image uploads, make sure the 'images' directory is writable by the web server, then set this to true:
    • $wgEnableUploads = true; in LocalSettings.php file.
  • MediaWiki extension:

MediaWiki specializes in the easy creation and distribution of static content, rather than programmatic pages.

  • MediaWiki create dynamically generated pages, and thus was born the Special: designation.
  • Any page whose name begins with Special: is treated—well, it's treated differently, populating the document body with the output of a PHP function.
  • In order to create our own special page, we need to write a PHP function and then register that function with MediaWiki.
  • Steps:
  • To create a new MediaWiki extension, putting it in the extensions directory just under the MediaWiki DocumentRoot. Create the file extensions/SpecialHello.php, which looks like this:
<?php
$wgExtensionFunctions[] = "wfExtensionSpecialHello";
function wfExtensionSpecialHello()
{
   global $wgMessageCache;
   $wgMessageCache->addMessages(array('hello' => 'Hello CS491A Page'));
   require_once('includes/SpecialPage.php');
   SpecialPage::addPage(new SpecialPage('Hello'));
}
?>
  • Description:
  • Function's name (“wfExtensionSpecialHello”) to the global array $wgExtensionFunctions, putting this function in the directory of extensions. Creating entire page instead of the output from certain tags. $wgExtensionFunctions is an array of names of functions without parameters for the setup of extensions. It is defined in DefaultSettings.php without assigning any values.
  • Define function. Modify $wgMessageCache, such that extension will look like a special page rather than a tag-modifying extension.
  • The final two lines import the code specific for special pages, and then create an instance of such a special page, adding it to the directory.
  • Special page does depends on another file of the same name (that is, SpecialHello.php), located in the includes directory that is parallel to extensions, just under the MediaWiki DocumentRoot.
  • includes directory: This directory contains a large number of standard special pages that come with MediaWiki, including SpecialNewpages.php, SpecialUserrights.php and SpecialImagelist.php. These functions can access the back-end MySQL database, perform calculations and access external sites—and then pipe the results back into a standard MediaWiki output page.


  • includes/SpecialHello.php file:


<?php
function wfSpecialHello() {
global $wgOut;
$wgOut->addHTML('Hello, CS491A World ! ');
$wgOut->addHTML('My name is Madhavi'); }
?>
  • Description: The above function, which is invoked whenever we go to the Special:Hello CS491A Page, adds the HTML “Hello, CS491A World !
    My name is Madhavi" to the output.
  • Finally, register extension and special page in the LocalSettings.php file, adding the following line:
 require_once("extensions/SpecialHello.php");

Now MediaWiki site listed as Special:Hello CS491A Page, when visiting Special::Specialpages.

[edit] Week 6 - February 8, 2008

I want to create a new tag(plugin) for Mediawiki. Tag must able to run Mysql queries to a database in any normal page.

  • MediaWiki Extension:
    • With WikiMedia's extension mechanism it is possible to define new tags of the form.
    • The function registered by the extension gets the text between the tags as input and can transform it into arbitrary HTML code.
    • The output is not interpreted as WikiText but directly included in the HTML output.
    • To create a new MediaWiki extension, putting it in the extensions directory just under the MediaWiki DocumentRoot. Create the file extensions/CustomTag.php, which looks like this:
 <?php
 $wgExtensionFunctions[] = 'registerSampleTag';
 $wgExtensionCredits['parserhook'][] = array(
   'name' => 'SampleTag',
   'author' => 'sql_query',
   'url' => 'http://localhost/mediawiki-1.11.1/index.php/Main_Page'); 
 function registerSampleTag() {
   global $wgParser;
   $wgParser->setHook('sql_query', 'printSampleTag');
 } 
 function printSampleTag($input,$params) {
   foreach ($params as $key=>$value) {
       $args .= "$key = $value";
     if ((strlen($input) == 0))
 {
   return("INVALID INPUT : NEED QUERY");
 }
 else
 {
    return('Query_Text: '.$input.'Arguments :'.$args.');
 }
 } 
?>

To activate the extension, include it from your LocalSettings.php with:

 include("extensions/CustomTag.php");
  • Description:
    • Register the extension with the WikiText parser($wgParser).
    • The first parameter is the name of the new tag(sql_query). In this case it defines the tag <sql_query> ... </sql_query>
    • The second parameter is the callback function for processing the text between the tags. $wgParser->setHook('sql_query', 'printSampleTag');
    • hook: Code and data that should be run when an event happens. This can be either a function and a chunk of data, or an object and a method.
    • function printSampleTag($input,$params): $params is an array containing any arguments passed to the extension like <sql_query dbhost="localhost">..</sql_query>

Output of this tag: <sql_query dbhost="localhost" user="root" pwd="cswiki123" dbname="bts">select username from user </sql_query>

Text : select username from user
Arguments :

  • dbhost = localhost
  • user = root
  • pwd = madhu123
  • dbname = bts

Retrieved from "http://localhost/mediawiki-1.11.1/index.php/Main_Page".

I am trying to connect to Mysql from Mediawiki. Couldn't connect to server. I gave same username & password of Mysql during Mediawiki Mysql installation. I posted in Mediawiki General discussion forums.

[edit] Week 7 - February 15, 2008

This week I focused on how to connect Mysql database from Mediawiki. MediaWiki_Forums

Enhancing wiki pages by adding PHP functionality:

  • To do this, add a function into the includes/Setup.php file:


$wgParser->setHook('DBphp','ParsePHPTag');
 function ParsePHPTag($Content)
{
//force any page containing this code not to be displayed
global $wgOut;
$wgOut->enableClientCache(false);
// Mediawiki uses output buffering itself.capture output into the buffer. 
//Turn on output buffering
ob_start();
//Evaluate a string as PHP code.It can be useful for storing code in a database text field for execution.   
eval($Content);
//The contents of the internal buffer copied into a string variable($Result) using ob_get_contents()
$Result = ob_get_contents();
//Clean (erase) the output buffer and turn off output buffering
ob_end_clean();
return($Result);
}

Description: In wikitext parser ($wgParser): The first parameter is the name of the new tag('DBphp'). The second parameter is the callback function, which is hooked to the parser so that, when the parser runs it will find and replace all instances of a specific tag.
ob_start(): Mediawiki capture output into the buffer.
eval($Content): Remember that the string passed must be valid PHP code, including things like terminating statements with a semicolon so the parser doesn't die on the line after the eval()
Get contents in to a variable result:ob_get_contents(); ob_end_clean(): as the buffer contents are discarded when ob_end_clean() is called. Return the result to the function.

To use PHP in any of your wiki pages, no need to use normal <?PHP ... ?> tags instead use <DBPHP> ... </DBPHP>.

Today class was cancelled. Hope I can show this week's demonstration for next week.

[edit] Week 8 - February 22, 2008

Access data in a MySQL database :

  • Adding code like this to a wiki page:
<DBphp>
  $db = mysql_connect("localhost:3306", "root", "madhu")
  or die ('Couldn\'t connect to server.'); 
  mysql_select_db("wikidb",$db);
  $result = mysql_query("SELECT * FROM user",$db);
 while($row=mysql_fetch_array($result)){
 echo $row['user_name'];
  }
</DBphp>

As I already added PHP functionality into the includes/Setup.php file ($wgParser->setHook('DBphp','ParsePHPTag'))(In my previous week section)

This <DBphp> tag invokes the call back function ParsePHPTag(mediawiki uses output buffering itself. capture output into the buffer)

Output just retreiving from user table & displays records of 'user_name'.

Next week I will try to implement like a <mysql> tag and query between them instead of writing user to enter code in wiki page.

[edit] Week 9 - February 29, 2008

This week I am able to display data using tags.

To see PHP errors, add this to the very top of LocalSettings.php:

error_reporting(E_ALL);
ini_set("display_errors", 1);

Especially useful when debugging errors in the PHP code.Enable more details (like a stack trace) to be shown for some types of errors:

$wgShowExceptionDetails = true;

Note: This will cause PHP errors to be shown on-page. This might make it easier for attackers to find a way into your server, so disable it again when you have found the problem.


Sql errors:

 $wgShowSQLErrors = true;
 $wgDebugDumpSql  = true;


To create a new MediaWiki extension, putting it in the extensions directory just under the MediaWiki DocumentRoot. Create the file extensions/mysql_query.php, which looks like this:


<?php
$wgExtensionFunctions[] = 'registerMySql';
$wgExtensionCredits['parserhook'][] = array(
   'name' => 'MySqlTag',
   'author' => 'mysql_query',
   'url' => 'http://localhost/mediawiki-1.11.1/index.php/Main_Page',
 ); 
function registerMySql() {
   global $wgParser;
$wgParser->setHook('mysql_query', 'DisplayTag');
} 
function DisplayTag($input,$params) {
//force any page containing this code not to be displayed
global $wgOut;
$wgOut->enableClientCache(false);
//capture output into the buffer(Send any output to buffer)
ob_start();
$dbhost="";
$dbusername="";
$dbpasswd="";
$dbname="";
   foreach ($params as $key=>$value) {
     if ($key == "1" && strlen($key) == 1)
     {
        $dbhost = $value;
     }
      if ($key == "2" && strlen($key) == 1)
     {
        $dbusername = $value;
     }
     if ($key =="3"  && strlen($key) == 1)
     {
        $dbpasswd = $value;
     }
 if ($key =="4"  && strlen($key) == 1)
     {	$dbname = $value;
     }
   }
$connection = mysql_connect("$dbhost","$dbusername","$dbpasswd") 
or die('Couldn\'t connect server.');
mysql_select_db("$dbname",$connection);
  $result = mysql_query("$input",$connection)
or die ("Could not select all data from table.");
//The contents of the internal buffer copied into a string variable($output) using ob_get_contents()
 $output = ob_get_contents();
  for($i=0;$i<mysql_num_fields($result);$i++) 
       { 
           $output .= "  ". mysql_field_name($result, $i); 
        } 
 while($row = mysql_fetch_array($result))
 {
$output .= . $row['classname'] ."  ". $row['description'] .";
 }
//Clean the output buffer and turn off output buffering
ob_end_clean();
return($output);
}
?>

Description:

  • Register 'registerMySql' to global function array $wgExtensionFunctions[]
  • In function registerMySql() : wikitext parser ($wgParser): The first parameter is the name of the new tag('mysql_query'). The second parameter is the callback function(DisplayTag), which is hooked to the parser so that, when the parser runs it will find and replace all instances of a specific tag.
  • In DisplayTag(callback function): Output buffer On. Internal buffer copied into a string variable($output) using ob_get_contents()

Using Tag <mysql_query> :

 <mysql_query 1="localhost" 2="root" 3="madhu" 4="cs420crs">SELECT classname,description,deptname FROM  
classes,department where classes.deptid=department.deptid </mysql_query>

Output: Retreiving rows & display data from database.

[edit] Week 10 - March 7, 2008

  • To make more generic code from last week's version((i.e) running mysql queries within tags):

Added this code:

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
 foreach ($row as $col_value){
 $output .= "<td>$col_value</td>";
}
}


  • mysql_fetch_array — Fetch a result row as an associative array.
    • The type of array that is to be fetched. Using MYSQL_ASSOC, you only get associative indices (as mysql_fetch_assoc() works).


After doing modifications to mysql_query.php which is in Extensions folder.

 <?php
 $wgExtensionFunctions[] = 'registerMySql';
 $wgExtensionCredits['parserhook'][] = array(
   'name' => 'MySqlTag',
   'author' => 'mysql_query',
   'url' => 'http://localhost/mediawiki-1.11.1/index.php/Main_Page',
 ); 
 function registerMySql() {
 global $wgParser;
 $wgParser->setHook('mysql_query', 'DisplayTag');
 } 
 function DisplayTag($input,$params) {
 //force any page containing this code not to be displayed
 global $wgOut;
 $wgOut->enableClientCache(false);
 //capture output into the buffer(Send any output to buffer)
 ob_start();
 $dbhost="";
 $dbusername="";
 $dbpasswd="";
 $dbname="";
   foreach ($params as $key=>$value) {
     if ($key == "1")
     {
        $dbhost = $value;
     }
      if ($key == "2" )
     {
        $dbusername = $value;
     }
     if ($key =="3" ) 
     {
        $dbpasswd = $value;
     }
     if ($key =="4")
     {
$dbname = $value;
}
}
 $connection = mysql_connect("$dbhost","$dbusername","$dbpasswd") 
 or die('Couldn\'t connect server.');
 mysql_select_db("$dbname",$connection);
 $result = mysql_query("$input",$connection)
 or die ("Could not select all data from table.");
 $output = ob_get_contents();
 for($i=0;$i<mysql_num_fields($result);$i++) 
       { 
        $output .= "  ". mysql_field_name($result, $i); 
       } 
 while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
 foreach ($row as $col_value){
 $output .= $col_value;
 }
 }
 ob_end_clean();
 return($output);
 }
 ?>   

Using <mysql_query> tag: You can run any mysql queries within the tags.

<mysql_query 1="localhost" 2="root" 3="madhu" 4="cs420crs">SELECT classname,description,deptname FROM  
classes,department where classes.deptid=department.deptid </mysql_query>
 
<mysql_query 1="localhost" 2="root" 3="madhu" 4="cs420crs">SELECT userid,cin from student </mysql_query>

Installation of PHP plug-in Netbeans 6.0 :

  • In Netbeans 6.0 IDE. Go to Tools -> Plugins -> Click PHP. Provides tools and support for php development. Includes PHP editor, runtime explorer and documentation.
    • Go To Sevices -> Web Servers -> Right click Add Web server -> Give path of Apache server C:/Program Files/Apache Software Foundation/Apache2.2/htdocs.

Implementing Paging : To show the result of a query in several pages.Paging.php:

<?php
$dbhost = 'localhost:3306'; 
$dbusername = 'root'; 
$dbpasswd = 'madhu'; 
       $database_name = 'cs420crs'; 
       $connection = mysql_connect("$dbhost","$dbusername","$dbpasswd") 
       or die ('Couldn\'t connect to server.'); 
       $db = mysql_select_db("$database_name", $connection) 
       or die('Couldn\'t select database.');
// how many rows to show per page
$rowsPerPage = 10;
// by default we show first page
$pageNum = 1;
// if $_GET['page'] defined, use it as page number
if(isset($_GET['page']))
{	$pageNum = $_GET['page'];
}
// counting the offset
$offset = ($pageNum - 1) * $rowsPerPage;
// Paging is implemented in MySQL using LIMIT that take two arguments. 
//The first argument specifies the offset of the first row to return,
//The second specifies the maximum number of rows to return. 
//The offset of the first row is 0 ( not 1 ).
 $query  = "SELECT classname,description FROM classes LIMIT $offset, $rowsPerPage";
$result = mysql_query($query) or die('Error, query failed');
       for($i=0;$i<mysql_num_fields($result);$i++) 
       { 
           echo mysql_field_name($result, $i); 
       } 
// print the random numbers
while($nt = mysql_fetch_array($result))
{
echo $nt[classname]; 
echo $nt[description];
          }
// how many rows we have in database
$query   = "SELECT count(*) AS numrows  FROM classes";
$result  = mysql_query($query) or die('Error, query failed');
$row     = mysql_fetch_array($result, MYSQL_ASSOC);
$numrows = $row['numrows'];
// how many pages we have when using paging?
$maxPage = ceil($numrows/$rowsPerPage);
// print the link to access each page
$self = $_SERVER['PHP_SELF'];
$nav =" ";
for($page = 1; $page <= $maxPage; $page++)
{	if ($page == $pageNum){$nav .= " $page ";   // no need to create a link to current page
}else{ //a href of $page
$nav .= $page;
}		
}
// creating previous and next link
// plus the link to go straight to
// the first and last page
if ($pageNum > 1)
{
$page = $pageNum - 1;
//a href of [Prev]
$prev = [Prev];//a href of [First Page]
$first = [First Page];
} if ($pageNum < $maxPage)
{
$page = $pageNum + 1;
//a href of [Next]  
$next = [Next];
//a href of [Last Page] i.e $maxPage
$last = [Last Page];
} // print the navigation link
echo $first . $prev . $nav . $next . $last;
// and close the database connection
mysql_close($con); 
?>

Output: As $rowsPerPage = 10; 10 records per page is Displayed and links to Page numbers, Next, Last etc.

[edit] Final Report

[edit] Brief project description

A web application, the Mediawiki extension plug-in adds a user-accessible database capability.The basic capability would be to allow a user to include something like an SQL query in a MediaWiki page and display format. That query would be expanded and the resulting table inserted into the page where the query was found according to user's display format. The basic capability would be useful all by itself without providing a way for users to manipulate a database since there are other tools that do that.

[edit] Anticipated users

The users (authorized users) will be CS Wiki users who want to run SQL queries. Virtually an wiki user might find it useful to view data.

[edit] Main conceptual (i.e., user-level) objects

The cswiki users like developers, administrators, faculty, students shall access the database query plug-in tag. The users shall have access to enter database queries in the Mediawiki edit tabs. This plug-in may be used for various purposes like report generation, database browsing etc. This tool is not providing users to manipulate a database since there are other tools that do that.

[edit] Primary conceptual (i.e., user-level) operations

  • The system will enable any wiki editor to embed an SQL query on a page.
    • Any wiki editor can enter sql queries between tags and able to run the queries. The tag parameters define, which database should be used.
  • The result of the query will be displayed when the page is displayed.
    • When wiki editor clicks save page then the result of the query is displayed.
  • The query author will also be able to describe the format in which the output will be displayed.
    • The query author can also have display options format like how many rows per page, tabular format etc.

[edit] Why I am interested in this project

I got lot of interest in web technologies by taking courses (CS 320, CS 420) with Dr.Sun, Dr. Jeff Miller. I had exposure to web technologies Servlets, JSP. But I never used web technologies PHP, Mediawiki. There is always a strong motivation to develop a product, which would be useful for our college. When Dr.Abbott advised me to write a Mediawiki plug-in, I was excited to learn plug-in development.
Link in cswiki, Project Ideas:[Russ Abbott/Project_ideas ].
I want my project intended to be used after finishing cs491AB.

[edit] Status

I’ve experimented with PHP, Mysql and have produced a very simple version of the project consisting of custom tag that able to run any sql queries in Mediawiki.
  • Developed an idea about requirements of the project.
  • Learned PHP (Hypertext PreProcessor) a server-side scripting language. Played around with PHP programs for practice.
  • Learned how Mediawiki run on PHP and MediaWiki extensions that extend the functionality of MediaWiki by implementing a printSampleTag (plug-in).
  • How to create dynamically generated pages, Special Page plug-in in Mediawiki.
  • How to connect Mediawiki and Mysql.
  • How a tag (<mysql_query> </mysql_query>) run SQL queries in wiki editor and display table when the page is displayed.
Furthermore, planning to provide
  • User display formatting options and also to display image files(blobs).