23+ Impressive Tools for Faster Javascript/Ajax Development

Posted on June 26th, 2008 in JavaScript by Ashish  Tagged

Javascript applications are still one of the most complex issues when it comes to web-development. Many tools and applications could make your developing life pretty fast and simple. Today we wanted to share with you a wide range of tools and applications that could really help you build, test and debug Javascript and Ajax applications. Let us know your experience with the tools listed here or others that are not.
1-Roar – Notifications (v1.0) Roar is a notification widget that streamlines incoming messages, such as updates or errors, without distracting the user from their browser experience or breaking their work-flow by displaying obtrusive alerts.

javascript ajax tools


2-Damn It DamnIT is a free service that emails you when a user encounters a JavaScript error in your webpages.

javascript ajax tools


3-Growl 2.0 with Mootools Growl is a notification system for Mac OS X, it allows applications that support Growl to send you notifications.

javascript ajax tools


APIs

4-Google AJAX Language API With the AJAX Language API, you can translate and detect the language of blocks of text within a webpage using only Javascript. The language API is designed to be simple and easy to use to translate and detect languages on the fly when offline translations are not available.


5-Got API An easy to use interface that helps you reach the methods and functions of many JavaScript frameworks by getting the data from trusted sources and websites.

javascript ajax tools


6-WaveMaker Visual Ajax Studio WaveMaker’s Studio and Framework provides a powerful solution for rapidly developing web-based applications. Drag & drop assembly of widgets and service, code-free integration of web-services, databases and Ajax UI, and one-touch deployment to standard Tomcat servers all work seamlessly together to let you build complete web apps in hours!

javascript ajax tools


FrameWorks

7- SproutCoreSproutCore is a framework for building applications in JavaScript with remarkably little amounts of code. It can help you build full “thick” client applications in the web browser that can create and modify data, often completely independent of your web server, communicating with your server via Ajax only when they need to save or load data.

javascript ajax tools


8-JavaScriptMVCJavaScriptMVC is a framework that brings methods to the madness of JavaScript development. It guides you to successfully completed projects by promoting best practices, maintainability, and convention over configuration.

javascript ajax tools


Amazing Tools

9-Jaxer Jaxer is an Ajax server. HTML, JavaScript, and CSS are native to Jaxer, as are XMLHttpRequests, JSON, DOM scripting, etc. And as a server it offers access to databases, files, and networking, as well as logging, process management, scalability, security, integration APIs, and extensibility.

javascript ajax tools


10-The Regulator The Regulator is an advanced, free regular expressions testing and learning tool that allows you to build and verify a regular expression against any text input, file or web, and displays matching, splitting or replacement results within an easy to understand, hierarchical tree.

javascript ajax tools


11-SnippelySnippely is a basic text and code organizational tool. Instead of storing bits of code, quick notes, and memos in text files all over your hard drive, this application will let you save and organize “snippets” in one convenient location.

javascript ajax tools


12-NitobiBugIt’s a browser-based JavaScript object logger and inspection tool – similar to Firebug. NitobiBug runs across different browsers (IE6+, Safari, Opera, Firefox) to provide a consistent and powerful tool for developing rich Ajax applications. You can check a demo here.

javascript ajax tools


13- Google Mashup EditorThe Google Mashup Editor provides simple tools and features that allow you to create mashups in minutes with the following features:

  • A set of tags that compiles into AJAX UI components.
  • Syntax highlighting
  • Autocomplete of gm tags by pressing the tab button
  • Quick access to documentation for any tag by pressing F2
  • File upload and management
  • Error checking and notification

javascript ajax tools


14- Beautify JavascriptThis tool was intended to explore ugly javascripts, e.g compacted in one line, or just make scripts look more readable.


15- ThemeRollerThemeRoller allows you to design custom jQuery UI themes for tight integration in your projects.

javascript ajax tools


16- JSDocJSDoc is a tool that parses inline documentation in JavaScript source files, and produces an documentation of the JavaScript code.


17- Clean AJAX Clean is an open source engine for AJAX, that provides a high level interface to work with the AJAX technology. It was created to solve real problems found on AJAX applications, and is used in many projects. Clean will help you to adopt AJAX saving your time and your code, reducing your learning curve and the code reengineering.

javascript ajax tools


18- Sajax Sajax is an open source tool to make programming websites using the Ajax framework as easy as possible. Sajax makes it easy to call PHP, Perl or Python functions from your webpages via JavaScript without performing a browser refresh. The toolkit does 99% of the work for you so you have no excuse to not use it.

javascript ajax tools


19- JavaScript Code Improver With JavaScript Code Improver you are just one click away from making any JavaScript clear, easily comprehensible and ready for printing thus saving the time you spend on editing, debugging and modifying it.

javascript ajax tools


Browser Addons and Toolbars

20- Greasemonkey Greasemonkey is a Firefox extension that allows you to customize the way web pages look and function. You can use it to make a web site more readable or more usable. You can fix rendering bugs that the site owner can’t be bothered to fix themselves.


21- Web Developer extension for Firefox This tool is really excellent for quick and easy webdevelopment. It Adds a menu and a toolbar with various web developer tools.

javascript ajax tools


22-Internet Explorer Developer Toolbar The Microsoft Internet Explorer Developer Toolbar provides a variety of tools for quickly creating, understanding, and troubleshooting Web pages.


23-DebugBar An Internet Explorer plug-in that brings you new powerful features :

  • DOM Inspector: View DOM Tree and modify tags attributes and css attributes on the fly to test your page
  • HTTP Inspector: View HTTP/S request to check cookies, GET and POST parameters, view server info
  • Javascript Inspector and Javascript Console: View javascript functions for easier debugging, see Javascript and AJAX code
  • HTML Validator: Validate HTML code to correct and optimize your code and html size of your page
  • And many more features: See page cookies, get pixel color on a page, make a page screenshot.

javascript ajax tools


24-Firebug Firebug integrates with Firefox to put a wealth of web development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page. It can be downloaded from here.

javascript ajax tools

Free PHP Scripts, Source Code and Tutorial Website List

Posted on March 11th, 2008 in PHP by Ashish  Tagged , , ,

Following are the websites list who provide free php scripts. You can find lots of information about PHP as well as free code samples, code galleries, and free scripts for download at these and other sites. There may be some premium php scripts which may come for a price but overall the list is good enough.

http://www.scripts.com/php-scripts/
http://www.best-php-scripts.com/
http://gscripts.net/
http://www.phpjunkyard.com/
http://www.free-php.net/
http://coding.phpground.net/
http://www.atomicphp.com/
http://www.thefreecountry.com/php/index.shtml
http://www.phpbuilder.com/snippet/
http://phpwizard.net/
http://www.devshed.com/Server_Side/PHP
http://www.phpclasses.org/
http://px.sklar.com/
http://zend.com/codex.php
http://www.weberdev.com/
http://www.hotscripts.com/PHP/
http://www.phpresourceindex.com/

I would be adding more to the list soon….

Parsing XML using PHP : Good example

Posted on March 6th, 2008 in PHP, XML by Ashish  Tagged , , ,

The following example illustrates how to use an external entity reference handler to include and parse other documents, as well as how PIs can be processed, and a way of determining "trust" for PIs containing code.

Consider the following XML’s

< ?xml version=’1.0′?>
< !DOCTYPE chapter SYSTEM "/just/a/test.dtd" [
<!ENTITY plainEntity "FOO entity">
< !ENTITY systemEntity SYSTEM "xmltest2.xml">
]>
<chapter>
 <title>Title &plainEntity;</title>
 <para>
  <informaltable>
   <tgroup cols="3">
    <tbody>
     <row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
     <row><entry>a2</entry><entry>c2</entry></row>
     <row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
    </tbody>
   </tgroup>
  </informaltable>
 </para>
 &systemEntity;
 <section id="about">
  <title>About this Document</title>
  <para>
   <!– this is a comment –>
   < ?php echo ‘Hi!  This is PHP version ‘ . phpversion(); ?>
  </para>
 </section>
</chapter>

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY testEnt "test entity">
]>
<foo>
<element attrib="value"/>
&testEnt;
<?php echo "This is some more PHP code being executed."; ?>
</foo>

The following code shows how we can parse the above XML file using PHP

< ?php
$file = "xmltest.xml";

function trustedFile($file)
{
    // only trust local files owned by ourselves
    if (!eregi("^([a-z]+)://", $file)
        && fileowner($file) == getmyuid()) {
            return true;
    }
    return false;
}

function startElement($parser, $name, $attribs)
{
    echo "&lt;<font color=\"#0000cc\">$name";
    if (count($attribs)) {
        foreach ($attribs as $k => $v) {
            echo " <font color=\"#009900\">$k</font>=\"<font color=\"#990000\">$v</font>\"";
        }
    }
    echo "&gt;";
}

function endElement($parser, $name)
{
    echo "&lt;/<font color=\"#0000cc\">$name</font>&gt;";
}

function characterData($parser, $data)
{
    echo "<b>$data</b>";
}

function PIHandler($parser, $target, $data)
{
    switch (strtolower($target)) {
        case "php":
            global $parser_file;
            // If the parsed document is "trusted", we say it is safe
            // to execute PHP code inside it.  If not, display the code
            // instead.
            if (trustedFile($parser_file[$parser])) {
                eval($data);
            } else {
                printf("Untrusted PHP code: <i>%s</i>",
                        htmlspecialchars($data));
            }
            break;
    }
}

function defaultHandler($parser, $data)
{
    if (substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") {
        printf(’<font color="#aa00aa">%s</font>’,
                htmlspecialchars($data));
    } else {
        printf(’<font size="-1">%s</font>’,
                htmlspecialchars($data));
    }
}

function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId,
                                  $publicId) {
    if ($systemId) {
        if (!list($parser, $fp) = new_xml_parser($systemId)) {
            printf("Could not open entity %s at %s\n", $openEntityNames,
                   $systemId);
            return false;
        }
        while ($data = fread($fp, 4096)) {
            if (!xml_parse($parser, $data, feof($fp))) {
                printf("XML error: %s at line %d while parsing entity %s\n",
                       xml_error_string(xml_get_error_code($parser)),
                       xml_get_current_line_number($parser), $openEntityNames);
                xml_parser_free($parser);
                return false;
            }
        }
        xml_parser_free($parser);
        return true;
    }
    return false;
}

function new_xml_parser($file)
{
    global $parser_file;

    $xml_parser = xml_parser_create();
    xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1);
    xml_set_element_handler($xml_parser, "startElement", "endElement");
    xml_set_character_data_handler($xml_parser, "characterData");
    xml_set_processing_instruction_handler($xml_parser, "PIHandler");
    xml_set_default_handler($xml_parser, "defaultHandler");
    xml_set_external_entity_ref_handler($xml_parser, "externalEntityRefHandler");
   
    if (!($fp = @fopen($file, "r"))) {
        return false;
    }
    if (!is_array($parser_file)) {
        settype($parser_file, "array");
    }
    $parser_file[$xml_parser] = $file;
    return array($xml_parser, $fp);
}

if (!(list($xml_parser, $fp) = new_xml_parser($file))) {
    die("could not open XML input");
}

echo "<pre>";
while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d\n",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
echo "</pre>";
echo "parse complete\n";
xml_parser_free($xml_parser);

?>

I hope this will help. Your comments are welcome.

Parsing XML using PHP

Posted on March 6th, 2008 in PHP, XML by Ashish  Tagged , , ,

Load an XML file as data using PHP

By handling mime-types and using browser detection, CodeHelp has already shown how to export XML using a PHP script. PHP can also receive XML as input – using the XML parser:

if (!($fp=@fopen("./contactsbare.xml", "r")))
        die ("Couldn’t open XML.");
$usercount=0;
$userdata=array();
$state=”;
if (!($xml_parser = xml_parser_create()))
        die("Couldn’t create parser.");

Each XML file can have it’s own DTD or structure. The PHP file using the XML parser must be tailored to one particular structure or DTD – it will then be able to read all files that are valid under that DTD. This example will use an over-simplified contacts format for XML – you will need to adapt the details of the tags (or nodes) for your own DTD. To follow the construction of the XML parser, load the example XML file into another window using the link in the Navigation Bar. (If the file doesn’t open in a new window in your browser, right click the link and choose Open in a New Window.) Multiple contacts can be specified by repeating the CONTACT tag and the PHP file therefore needs to keep track of the number of contacts used in this example. In the above code, $usercount is set to zero ready to hold the number of contacts found. $userdata will later be filled with data for each contact and $state is used to keep track of which node the parser is dealing with for each contact.

The PHP XML parser now needs two functions to be declared, one to handle the element data and one to handle the character data within the elements. This is where you need to change the code to reflect your own XML files – change the element and attribute names. I’ll start with the Element Handler. This is in two parts, a function to detect the start of real data and a function to detect when an element comes to an end – in this case to register when more than one contact is specified. Each function is called once for each node – use a switch statement to decide what action to take depending on which node is being processed. The parser will take care of the $name and $attrib variables.

function startElementHandler ($parser,$name,$attrib){
global $usercount;
global $userdata;
global $state;

switch ($name) {
        case $name=="NAME" : {
                $userdata[$usercount]["first"] = $attrib["FIRST"];
                $userdata[$usercount]["last"] = $attrib["LAST"];
                $userdata[$usercount]["nick"] = $attrib["NICK"];
                $userdata[$usercount]["title"] = $attrib["TITLE"];
                break;
                }
        }
}

function endElementHandler ($parser,$name){
global $usercount;
global $userdata;
global $state;
$state=”;
if($name=="CONTACT") {$usercount++;}
}

The function "startElementHandler()" has been abbreviated here by removing the other case $name=="" : {} statements, the full file will be looked at later.

Next, we need the character handler:

function characterDataHandler ($parser, $data) {
global $usercount;
global $userdata;
global $state;
if (!$state) {return;}
if ($state=="COMPANY") { $userdata[$usercount]["bcompany"] = $data;}
if ($state=="GENDER") { $userdata[$usercount]["gender"] = $data;}
}

Finally, tell the parser which functions to use, read the data from the opened file and parse the contents.

xml_set_element_handler($xml_parser,"startElementHandler","endElementHandler");
xml_set_character_data_handler( $xml_parser, "characterDataHandler");

while( $data = fread($fp, 4096)){
if(!xml_parse($xml_parser, $data, feof($fp))) {
break;}}
xml_parser_free($xml_parser);

The data from the XML file is now held in $userdata and can be accessed using a standard PHP loop:

for ($i=0;$i<$usercount; $i++) {
echo "Name: ".$userdata[$i]["title"]." ".
        ucfirst($userdata[$i]["first"])." ". ucfirst($userdata[$i]["last"]);
}

 

All about Extensible Markup Language (XML)

Posted on March 6th, 2008 in XML by Ashish  Tagged , , , ,

Extensible Markup Language (XML) is a general-purpose specification for creating custom markup languages. It is classified as an extensible language because it allows its users to define their own elements. Its primary purpose is to facilitate the sharing of structured data across different information systems, particularly via the Internet, and it is used both to encode documents and to serialize data.

well-formedness is required, XML is a generic framework for storing any amount of text or any data whose structure can be represented as a tree. The only indispensable syntactical requirement is that the document has exactly one root element (alternatively called the document element). This means that the text must be enclosed between a root start-tag and a corresponding end-tag. The following is a "well-formed" XML document:

<book>This is a book…. </book>

The root element can be preceded by an optional XML declaration. This element states what version of XML is in use (normally 1.0); it may also contain information about character encoding and external dependencies.

<?xml version="1.0" encoding="UTF-8"?>

Here is an example of a structured XML document:

<recipe name="bread" prep_time="5 mins" cook_time="3 hours">
   <title>Basic bread</title>
   <ingredient amount="3" unit="cups">Flour</ingredient>
   <ingredient amount="0.25" unit="ounce">Yeast</ingredient>
   <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient>
   <ingredient amount="1" unit="teaspoon">Salt</ingredient>
   <instructions>
     <step>Mix all ingredients together.</step>
     <step>Knead thoroughly.</step>
     <step>Cover with a cloth, and leave for one hour in warm room.</step>
     <step>Knead again.</step>
     <step>Place in a bread baking tin.</step>
     <step>Cover with a cloth, and leave for one hour in warm room.</step>
     <step>Bake in the oven at 350°F for 30 minutes.</step>
   </instructions>
 </recipe>

Entity references

An entity in XML is a named body of data, usually text. Entities are often used to represent single characters that cannot easily be entered on the keyboard; they are also used to represent pieces of standard ("boilerplate") text that occur in many documents, especially if there is a need to allow such text to be changed in one place only.

Special characters can be represented either using entity references, or by means of numeric character references. An example of a numeric character reference is "€", which refers to the Euro symbol by means of its Unicode codepoint in hexadecimal.

An entity reference is a placeholder that represents that entity. It consists of the entity’s name preceded by an ampersand ("&") and followed by a semicolon (";"). XML has five predeclared entities:
&amp;     &     ampersand
&lt;     <     less than
&gt;     >     greater than
&apos;     ‘     apostrophe
&quot;     "     quotation mark

Here is an example using a predeclared XML entity to represent the ampersand in the name "AT&T":

<company_name>AT&amp;T</company_name>

Additional entities (beyond the predefined ones) can be declared in the document’s Document Type Definition (DTD). A basic example of doing so in a minimal internal DTD follows. Declared entities can describe single characters or pieces of text, and can reference each other.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE example [
    <!ENTITY copy "©">
    <!ENTITY copyright-notice "Copyright &copy; 2006, hurricanesoftwares.com">
]>
<example>
    &copyright-notice;
</example>

When viewed in a suitable browser, the XML document above appears as:

<example> Copyright © 2006, Hurricanesoftwares.com </example>

Numeric character references

Numeric character references look like entity references, but instead of a name, they contain the "#" character followed by a number. The number (in decimal or "x"-prefixed hexadecimal) represents a Unicode code point. Unlike entity references, they are neither predeclared nor do they need to be declared in the document’s DTD. They have typically been used to represent characters that are not easily encodable, such as an Arabic character in a document produced on a European computer. The ampersand in the "AT&T" example could also be escaped like this (decimal 38 and hexadecimal 26 both represent the Unicode code point for the "&" character):

<company_name>AT&T</company_name>
<company_name>AT&T</company_name>

Well-formed documents

In XML, a well-formed document must conform to the following rules, among others:

    * Non-empty elements are delimited by both a start-tag and an end-tag.
    * Empty elements may be marked with an empty-element (self-closing) tag, such as <IAmEmpty />. This is equal to <IAmEmpty></IAmEmpty>.
    * All attribute values are quoted with either single (’) or double (") quotes. Single quotes close a single quote and double quotes close a double quote.
    * Tags may be nested but must not overlap. Each non-root element must be completely contained in another element.
    * The document complies with its declared character encoding. The encoding may be declared or implied externally, such as in "Content-Type" headers when a document is transported via HTTP, or internally, using explicit markup at the very beginning of the document. When no such declaration exists, a Unicode encoding is assumed, as defined by a Unicode Byte Order Mark before the document’s first character. If the mark does not exist, UTF-8 encoding is assumed.

Element names are case-sensitive. For example, the following is a well-formed matching pair:

    <Step> … </Step>

whereas this is not

    <Step> … </step>

By carefully choosing the names of the XML elements one may convey the meaning of the data in the markup. This increases human readability while retaining the rigor needed for software parsing.

Choosing meaningful names implies the semantics of elements and attributes to a human reader without reference to external documentation. However, this can lead to verbosity, which complicates authoring and increases file size.

Automatic verification

It is relatively simple to verify that a document is well-formed or validated XML, because the rules of well-formedness and validation of XML are designed for portability of tools. The idea is that any tool designed to work with XML files will be able to work with XML files written in any XML language (or XML application). One example of using an independent tool follows:

    * load it into an XML-capable browser, such as Firefox or Internet Explorer
    * use a tool like xmlwf (usually bundled with expat)
    * parse the document, for instance in Ruby:

irb> require "rexml/document"
irb> include REXML
irb> doc = Document.new(File.new("test.xml")).root

Displaying XML on the web

XML documents do not carry information about how to display the data. Without using CSS or XSL, a generic XML document is rendered as raw XML text by most web browsers. Some display it with ‘handles’ (e.g. + and – signs in the margin) that allow parts of the structure to be expanded or collapsed with mouse-clicks.

In order to style the rendering in a browser with CSS, the XML document must include a reference to the stylesheet:

<?xml-stylesheet type="text/css" href="myStyleSheet.css"?>

Note that this is different from specifying such a stylesheet in HTML, which uses the <link> element.

Extensible Stylesheet Language (XSL) can be used to alter the format of XML data, either into HTML or other formats that are suitable for a browser to display.

To specify client-side XSL Transformation (XSLT), the following processing instruction is required in the XML:

<?xml-stylesheet type="text/xsl" href="myTransform.xslt"?>

Client-side XSLT is supported by many web browsers. Alternatively, one may use XSL to convert XML into a displayable format on the server rather than being dependent on the end-user’s browser capabilities. The end-user is not aware of what has gone on ‘behind the scenes’; all they see is well-formatted, displayable data.

Processing XML files

Three traditional techniques for processing XML files are:

    * Using a programming language and the SAX API.
    * Using a programming language and the DOM API.
    * Using a transformation engine and a filter

More recent and emerging techniques for processing XML files are:

    * Pull Parsing
    * Data binding

Simple API for XML (SAX)

SAX is a lexical, event-driven interface in which a document is read serially and its contents are reported as "callbacks" to various methods on a handler object of the user’s design. SAX is fast and efficient to implement, but difficult to use for extracting information at random from the XML, since it tends to burden the application author with keeping track of what part of the document is being processed. It is better suited to situations in which certain types of information are always handled the same way, no matter where they occur in the document.

DOM

DOM is an interface-oriented Application Programming Interface that allows for navigation of the entire document as if it were a tree of "Node" objects representing the document’s contents. A DOM document can be created by a parser, or can be generated manually by users (with limitations). Data types in DOM Nodes are abstract; implementations provide their own programming language-specific bindings. DOM implementations tend to be memory intensive, as they generally require the entire document to be loaded into memory and constructed as a tree of objects before access is allowed. DOM is supported in Java by several packages that usually come with the standard libraries. As the DOM specification is regulated by the World Wide Web Consortium, the main interfaces (Node, Document, etc.) are in the package org.w3c.dom.*, as well as some of the events and interfaces for other capabilities like serialization (output). The package com.sun.org.apache.xml.internal.serialize.* provides the serialization (output capacities) by implementing the appropriate interfaces, while the javax.xml.parsers.* package parses data to create DOM XML documents for manipulation.

Transformation engines and filters

A filter in the Extensible Stylesheet Language (XSL) family can transform an XML file for displaying or printing.

    * XSL-FO is a declarative, XML-based page layout language. An XSL-FO processor can be used to convert an XSL-FO document into another non-XML format, such as PDF.
    * XSLT is a declarative, XML-based document transformation language. An XSLT processor can use an XSLT stylesheet as a guide for the conversion of the data tree represented by one XML document into another tree that can then be serialized as XML, HTML, plain text, or any other format supported by the processor.
    * XQuery is a W3C language for querying, constructing and transforming XML data.
    * XPath is a DOM-like node tree data model and path expression language for selecting data within XML documents. XSL-FO, XSLT and XQuery all make use of XPath. XPath also includes a useful function library.

Pull parsing

Pull parsing [6] treats the document as a series of items which are read in sequence using the Iterator design pattern. This allows for writing of recursive-descent parsers in which the structure of the code performing the parsing mirrors the structure of the XML being parsed, and intermediate parsed results can be used and accessed as local variables within the methods performing the parsing, or passed down (as method parameters) into lower-level methods, or returned (as method return values) to higher-level methods. Examples of pull parsers include StAX in the Java programming language, SimpleXML in PHP and System.Xml.XmlReader in .NET.

A pull parser creates an iterator that sequentially visits the various elements, attributes, and data in an XML document. Code which uses this ‘iterator’ can test the current item (to tell, for example, whether it is a start or end element, or text), and inspect its attributes (local name, namespace, values of XML attributes, value of text, etc.), and can also move the iterator to the ‘next’ item. The code can thus extract information from the document as it traverses it. The recursive-descent approach tends to lend itself to keeping data as typed local variables in the code doing the parsing, while SAX, for instance, typically requires a parser to manually maintain intermediate data within a stack of elements which are parent elements of the element being parsed. Pull-parsing code can be more straightforward to understand and maintain than SAX parsing code.

Data binding

Another form of XML Processing API is data binding, where XML data is made available as a custom, strongly typed programming language data structure, in contrast to the interface-oriented DOM. Example data binding systems include the Java Architecture for XML Binding (JAXB).

Non-extractive XML Processing API

Non-extractive XML Processing API is a new and emerging category of parsers that aim to overcome the fundamental limitations of DOM and SAX. The most representative is VTD-XML, which abolishes the object-oriented modeling of XML hierarchy and instead uses 64-bit Virtual Token Descriptors (encoding offsets, lengths, depths, and types) of XML tokens. VTD-XML’s approach enables a number of interesting features/enhancements, such as high performance, low memory usage, ASIC implementation, incremental update, and native XML indexing .

Specific XML applications and editors

The native file format of OpenOffice.org, AbiWord, and Apple’s iWork applications is XML. Some parts of Microsoft Office 2007 are also able to edit XML files with a user-supplied schema (but not a DTD), and Microsoft has released a file format compatibility kit for Office 2003 that allows previous versions of Office to save in the new XML based format. There are dozens of other XML editors available.

Advantages of XML

    * It is text-based.
    * It supports Unicode, allowing almost any information in any written human language to be communicated.
    * It can represent common computer science data structures: records, lists and trees.
    * Its self-documenting format describes structure and field names as well as specific values.
    * The strict syntax and parsing requirements make the necessary parsing algorithms extremely simple, efficient, and consistent.
    * XML is heavily used as a format for document storage and processing, both online and offline.
    * It is based on international standards.
    * It can be updated incrementally.
    * It allows validation using schema languages such as XSD and Schematron, which makes effective unit-testing, firewalls, acceptance testing, contractual specification and software construction easier.
    * The hierarchical structure is suitable for most (but not all) types of documents.
    * It is platform-independent, thus relatively immune to changes in technology.
    * Forward and backward compatibility are relatively easy to maintain despite changes in DTD or Schema.
    * Its predecessor, SGML, has been in use since 1986, so there is extensive experience and software available.
    * An element fragment of a well-formed XML document is also a well-formed XML document.

Disadvantages of XML

    * XML syntax is redundant or large relative to binary representations of similar data, especially with tabular data.
    * The redundancy may affect application efficiency through higher storage, transmission and processing costs.
    * XML syntax is verbose, especially for human readers, relative to other alternative ‘text-based’ data transmission formats.
    * The hierarchical model for representation is limited in comparison to an object oriented graph.
    * Expressing overlapping (non-hierarchical) node relationships requires extra effort.
    * XML namespaces are problematic to use and namespace support can be difficult to correctly implement in an XML parser.
    * XML is commonly depicted as "self-documenting" but this depiction ignores critical ambiguities.
    * The distinction between content and attributes in XML seems unnatural to some and makes designing XML data structures harder

CakePHP Naming Conventions, Global Constants, Global Functions

Posted on March 3rd, 2008 in Frameworks by Ashish  Tagged , , ,

config (’file_name’)

Global Functions

up (’string’) r (’search’, ‘replace’, ‘text’) pr (array) am (array, [array, array]) env (’HTTP_HEADER’)

cache (path, data, expires, [target])

Models

Class Name: singular, camel cased (LineItem, Person) File Name: singular, underscored (line_item.php, person.php) Table Name: plural, underscored (line_items, people)

Controllers

Class Name: plural, camel cased, ends in "Controller"

Views

Path: controller name, underscored (app/views/line_items/<file>, app/ views/people/<file>) File Name: action name, lowercase (index.thtml, view.thtml)

uses (’file_name’) vendor (’file_name’) debug (’message’) a (element, [element, element]) aa (key, value, [key, value]) e (’message’) low (’STRING’)

(LineItemsController, People Controller)

File Name: plural, underscored

(line_items_controller.php, people_controller.php)

clearCache ([params, type, ext]) countdim (array)

Model

Properties $cacheQueries $data $displayField $id $name $primaryKey Methods $recursive $useDbConfig $useTable $validate $validationErrors $_tableInfo Association Properties $belongsTo $hasAndBelongsToMany $hasMany $hasOne

Controller

Properties $name $autoLayout $base $cacheAction $data $here $output $params $plugin $view $webroot Methods $action $autoRender $beforeFilter $components $helpers $layout $pageTitle $persistModel $uses $viewPath Properties $action $autoRender $controller $hasRendered $here $loaded $name $params $plugin $themeWeb $viewPath Methods

View

$autoLayout $base $ext $helpers $layout $models $pageTitle $parent $subDir $uses

bindModel (params) create ( ) delete (id, [cascade]) escapeField (field) execute (data) exists ( ) field (name, conditions, order) find ([conditions, fields, order, recursive])

findAll ([conditions, fields, order, limit, page, recur...])

getLastInsertID ( ) getNumRows ( ) hasAny ([conditions]) hasField (name) invalidate (field) invalidFields ([data]) isForeignKey (field) loadInfo ( ) query ([sql]) read ([fields, id]) remove ([id, cascade]) save ([data, validate, fieldList]) saveField ([name, value, validate]) set (one, [two]) setDataSource (dataSource) setSource (tableName) unbindModel (params) validates ([data])

findAllThreaded([conditions, fields, sort]) findCount ([conditions, recursive]) findNeighbours (conditions, field, value)

generateList ([conditions, order, limit, keyPath, val...])

getAffectedRows ( ) getColumnType (column) getColumnTypes ( ) getDisplayField ( ) getID ([list])

cleanUpFields ( ) constructClasses ( ) flash (message, url, [pause]) flashOut (message, url, [pause]) generateFieldNames (data, doCreateO…) postConditions (data) redirect (url, [status]) referer ([default, local]) render([action, layout, file]) set (one, [two]) setAction (action, [param, param, param]) validate ( ) validateErrors ( )

element (name) error (code, name, message) pluginView (action, layout) render ([action, layout, file]) renderCache (filename, timeStart) renderElement (name, [params]) renderLayout (content_for_layout) setLayout (layout)

Helper

Availability: View only

Callbacks afterDelete ( ) beforeDelete ( ) beforeFind (&qu..) afterFind (results)

beforeSave ( ) beforeValidate ( )

afterSave ( )

Callbacks beforeFilter ( ) afterFilter ( )

beforeRender ( )

Global Constants

Core Defines

ACL_CLASSNAME ACL_FILENAME AUTO_SESSION CACHE_CHECK CAKE_ADMIN CAKE_SECURITY

CAKE_SESSION_COOKIE

CAKE_SESSION_STRING

Paths

APP APP_DIR APP_PATH CACHE CAKE COMPONENTS CONFIGS CONTROLLER_TESTS CONTROLLERS CSS ELEMENTS HELPER_TESTS HELPERS

Component

INFLECTIONS JS LAYOUTS LIB_TESTS LIBS LOGS MODEL_TESTS MODELS SCRIPTS TESTS TMP VENDORS VIEWS Availability: Controller / View

CAKE_SESSION_TABLE

CAKE_SESSION_TIMEOUT

Properties

$disableStartup

COMPRESS_CSS DEBUG LOG_ERROR MAX_MD5SIZE WEBSERVICES

Callbacks

startup (&controller)

Properties $tags $base $here $action $themeWeb $view $webroot $params $data $plugin Callbacks

afterRender ( )

CAKE_SESSION_SAVE

Conventions

Class Name: MyCoolComponent

Path: app/controllers/components/my_cool.php

Conventions

Class Name: MyCoolHelper Path: app/views/helpers/my_cool.php

Webroot Configurable Paths

CORE_PATH ROOT WWW_ROOT WEBROOT_DIR

Usage

Controller: $this->MyCool->method( ); View: $this->controller->MyCool->method( );

Usage

View: $myCool->method( );

CAKE_CORE_INCLUDE_PATH

 

Download CakeSheet Pdf for complete reference.

 

PHP vs Ruby

Posted on February 22nd, 2008 in PHP, Ruby On Rails by Ashish  Tagged , , ,

PHP vs Ruby – Practical Language Differences

There are rather significant syntactical differences between PHP and Ruby. For example PHP requires semicolons at the end of lines and generally requires curly brackets to enclose blocks of code. Ruby, on the other hand, uses newline characters to denote the end of a line of code and many code constructs such as function definitions, and various loops are ended with the word “end” rather than being surrounded by curly braces. Below is an example of PHP vs Ruby syntax.

PHP Function

function say_hello($name) {
$out = "Hello $name";
return $out;
}

Ruby Function

def say_hello(name)
out = "Hello ${name}"
return out
end

In Ruby, you don’t have to specify the return line as the return value of the last evaluated line is returned automatically. There are other differences in syntax between PHP and Ruby and, in general, Ruby is more concise yet it is not cryptic. Another general note about PHP is that PHP has a very large number of “built-in” functions – many more than Ruby. The Rails framework adds some nice helper methods for formatting dates, numbers, currency, and the like. PHP, however, has a vast library of functions that can do almost anything you will need. The naming of the PHP functions and the order of the parameters they take are somewhat inconsistent, but the functions are there making PHP an amazingly complete tool set for web application development. An example of the naming inconsistency is evident in function names such as strpos() vs str_replace(). Sometimes an underscore is used to separate words and other times it’s not. While that can be annoying, it’s something you can memorize in time and it’s not a huge deal. What really matters to me is what can PHP do that Ruby can’t and vice versa.

PHP5 was first released over three years ago, July 13, 2007. Frustratingly, and for various compatibility reasons, PHP5 is just now beginning to be an available choice on shared hosting accounts. Nevertheless, my comparison is between PHP5 and Ruby. Both PHP5 and Ruby have object oriented features albeit, Ruby is more sophisticated in terms of OO constructs. But I wanted to know what the real difference is between the languages. When I begin development of my next web application, what will I notice in terms of the differences between the languages.

The Similarities Between PHP and Ruby

Before getting started, I know that PHP and Ruby have very significant syntactic differences and different people may prefer one over the other. So it may be harder to implement certain features in one language over the other. Nevertheless both languages can do almost the same things. Both languages have try/catch/throw style exception handling. Exceptions are new to PHP5 as PHP4 does not have them. Both languages can be used in an object oriented way. Ruby has more powerful object oriented features but most developers probably won’t notice a difference in a normal web application. Both languages have additional functionality that can be added through libraries. In general, when developing web applications, I have not yet run into a time when I was working with one language and hit a road block where the language I was using was not capable of expressing the functionality I needed. Sometimes things are easier in one language versus the other but both PHP and Ruby have been able to “do” the same things.

About Frameworks

You can’t talk about Ruby for web development without mentioning Rails. Rails is fantastic and makes developing web applications much easier due to all of the built-in functionality. My favorite aspect of Rails is the ActiveRecord functionality. Often times, many of the objects in my applications are virtually empty except for inheriting from ActiveRecord. Validation is a breeze with Rails and is usually one line such as:

validates_presence_of :attribte_name

The built-in error handling with error_messages_for is very helpful. If you need more flexibility with the display of error messages, there are plugins to available for that. The ability to turn email sending on and off for testing is extremely nice. Having different configuration files for live, testing, and development environments is great.

PHP has over 40 different frameworks available. I’ve spent a significant amount of time studying PHP frameworks. The most popular ones appear to by CakePHP and Symfony. Both of these frameworks are essentially Rails clones. I think Symfony is the largest, and most comprehensive of the two. My favorite PHP Framework, howevever, is CodeIgniter. It is a Model-View-Controller style framework and has a strong Rails feel to it, but it is much lighter weight. CodeIgniter has no code generators like Rails has. It does have an ActiveRecord style Database class but it is not as powerful as the ActiveRecord in Rails. It is, however, quite nice and very helpful – much better than nothing. CodeIgniter, as far as I know, does not have anything comparable to Migrations in Rails.

PHP Does Not Have Formal Namespaces

PHP does not officially support namespaces and Ruby does. So organizing your code in a PHP application is something that’s left to the developer to figure out. PHP5 has the ability to autoload classess that are undefined. It is a very useful function and one that I have used to organize my code into name spaces. I essentially name classes with underscores separating directory names. Here is my autoload function that replaces underscores with slashes to create a path to the class files that I am using.

define("PROJECT", "/path/to/project/classes/");
define("LIBRARY", "/path/to/my/main/php5/library/classes/");

function __autoload($className) {
$fileName = str_replace("_", DIRECTORY_SEPARATOR, $className) . ".php";
if(preg_match("/^ProjectName_/", $className)) {
include_once(PROJECT . $fileName);
}
else {
include_once(LIBRARY . $fileName);
}
}

I have a bunch of classes that I continually reuse in my PHP applications. The path to the root directory of my library is stored in the LIBRARY constant. Any classes I write that either extend my core library or are specific to the project I am working on get stored in the location specified by the PROJECT constant. This has been a system that works really well for me and is a good workaround for PHP not having namespaces. So PHP not having formal namespaces has not really hindered my development efforts.

Documentation

PHP kills Ruby and Rails when it comes to ease of finding, reading, and even generating documentation. The PHP website has wonderful, helpful, searchable documentation. The Rails Documentation is comprehensive but much harder to navigate and has far fewer code examples. PHPDocumentor also produces much better looking documentation that is easier to navigate than RDoc does.

Hosting Ruby (on Rails) Is Painful And Expensive

All the Ruby applications I have developed to date have used the Rails framework. So this is a comparison between hosting a PHP Application and a Ruby on Rails application. PHP has several good MVC style frameworks. My favorite is CodeIgniter and I’ll be posting an article about it soon. Using a framework or not, PHP is extremely easy to host. Locate virtually any hosting company, sign up for an account and start dropping your files on the server. I can’t say the same for Ruby on Rails.

I started off with a DreamHost account but performance and reliability were miserable. I ended up switching to a virtual dedicated server at Rimu Hosting and have been extremely please with their service. I’m running Apache 2.0 + Mongrel + ISPConfig and it’s working out nicely. But every time I want to deploy a new application I have to…

* Set up a mongrel cluster
* Configure 2 or three ports for the mongrel cluster
* Create a map file for my random load balancer
* Set up a way to restart the cluster if the server reboots
* Configure Apache to forward requests to the mongrel cluster
* Configure capistrano to deploy the application.

Fortunately capistrano handles all of the annoying tedium associated with deploying the application and restarting the server. So once capistrano is setup and working, future deployments are a breeze. Also worth noting, this assumes you have your source code in Subversion. So you have to make sure that Subversion is set up and accessible over the internet to the deployment server as well as your development machine. It is good practice to have you source code in version control and you should be doing this whether the project is PHP or Ruby. If you are not using subversion and, therefore, not using capistrano, deploy a rails application is very time consuming and frustrating. Lastly, you need ssh access to your deployment server if you are going to be using Ruby on Rails whereas PHP can be deployed entirely over FTP.

To have a reasonable and reliable hosting environment for Ruby on Rails applications, you should have a virtual private server (VPS) or a dedicated server. So that will cost you at least $50 per month. You can host multiple Rails applications on the same VPS but the RAM requirements for running the mongrel clusters will quickly catch up to you. While you could host well over 50 PHP sites running on your VPS you will only be able to have a handful of Rails applications.

Conclusion

I suspect very few people will argue that PHP is a more elegant language or is more powerful than Ruby. Frankly, Ruby is probably may favorite language that I have ever worked with and I have worked with Classic ASP, ASP.NET, VB.NET, C#, Java, and Perl all rather extensively over the years. Ruby is both highly expressive and concise which is rare and refreshing.

Rails is a very comprehensive and effective web development Framework and there’s nothing exactly like it in PHP. You get a huge amount of functionality for free. Developing in Ruby on Rails is also a very fast process because Ruby is a very concise language requiring much less typing than any other language I’ve worked with. CodeIgniter is a really nice PHP framework. It will give you a great boost when developing your next PHP application.

The hosting and deployment struggles with Ruby on Rails is a major sticking point for me though. As the owner of a web development company many of our smaller clients do not have the budget for their own VPS account and even if they did, we don’t have the staff to manage a large number of VPS accounts or dedicated servers. Keeping the security updates current, managing any issues that may occur with email, and all the other headaches that go along with managing your own VPS or Dedicated server is more than we care to take on for the relatively small, practical dfference between PHP and Ruby. For large projects, it may be worth the trouble, but for small to medium sized projects, PHP is much easier to deploy, less expensive to host, and the language is capable of taking on everything those types of sites require. For our projects, development time with PHP is not noticeably longer than with Ruby on Rails. Ruby on Rails integrates a lot of things for the developer.

There is ActiveRecord for managing the link between models and the database, migrations for keeping development and live databases in sync, built in testing, the ajax – prototype javascript library is included, and you get a well defined file system structure. While it may not all be packaged together as well, PHP can do all of the above.

Ruby or PHP which one is for you

Posted on February 22nd, 2008 in PHP, Ruby On Rails by Ashish  Tagged , , ,

Will Ruby kill PHP?

With the recent rise in popularity of the Ruby programming language (largely driven by the excellent but not perfect web framework called Rails), I’ve noticed a little fear in the air … fear on the part of some people in the PHP community.

Will Ruby kill PHP?

The short answer is: NO.

MY REASONING

Though Ruby and PHP are both scripting languages that make developing web applications much easier than it is, say in the Java world, they are very different beasts … each appeals to a different audience.

RUBY IS ELEGENT BUT COMPLEX

Before I go on, I want to point out that Ruby is a great language and I think it makes perfect sense for PHP developers to learn a little Ruby: it is always a good idea to learn other languages because it will make you a better programmer.

That said, I believe Ruby will not appeal to, or fill the need of most PHP’ers – Ruby can be a little too abstract.

JAVA NERDS LOVE RUBY

Ruby is attracting many from the Java world because it expresses very advanced concepts in a simple syntax – contrast this to Java’s (often times) kludgy and verbose representation.

Ruby appeals to the Java crowd because Java people have been trained to think in terms of large scale enterprise applications – regardless of the size of the project.

… These ‘abstractions’ (generally speaking) lend themselves well to larger projects.

WHY PHP WORKS

PHP is often criticized because it has both a procedural and an object oriented way of doing things. Some people think that this divergence (within the language), takes away from it … I think this is part of its strength!

Objected oriented constructs are great for creating cleaner designs that are easier to maintain and promote the possibility of code reusability. Code reuseability is an often touted advantage of OOP, but from what I’ve seen in the Java world, it is not achieved so often.

With OOP, there is a cost of added complexity and overhead – you simply have to write more code to do things when you do it via OOP.

PHP PROVES THAT NON OO LANGUAGES STILL HAVE THEIR PLACE

I would suggest that the vast majority of PHP work is found in simple projects:

* Email from a web page.
* Process a simple form and save to a database.
* Create a simple store with 10 items.

My point is, that for many PHP projects, OOP may be a little overkill.

WHY RUBY WILL NOT KILL PHP

In Ruby everything is an object (even numbers!) and the core language has very sophisticated constructs that need to be understood to use Ruby effectively – Ruby strength is also its’ weakness.

… I don’t see the majority of PHP users wanting to jump that deep into the world of programmatic abstraction – for most, there is simply no point.

Ruby is a very clean language and it has lots of things going for it. But PHP has lots of things going for it too. You can point out spots where Ruby code is cleaner than PHP, but you can point out spots where (I think) PHP code is cleaner than Ruby …

Today I would consider PHP the better choice because it is well established (lots of IDEs, open source projects, easy hosting etc ..) and proven.

Ruby is just starting to get into the mainstream … and there are still some fundamental issues with Ruby and web development.

For example: Ruby integration with APACHE is still not stable. It works … but there are known problems and can be a hassle to set up.

Ruby has a long way to go, I can’t argue for the programming details as I still like my Perl but from the SysAdmin side Ruby and Rails for the matter are an absolute nightmare.

Ruby in itself is slow, doesn’t understand threads like every other language out there so it doesn’t integrate into apache like PHP or Perl or Python or the other hundreds of web scripting languages.

Until Mongrel came out you were forced to use fast_cgi, which is a dead method of rendering pages, apache’s mod_fcgi is crap and lighttpd’s fcgi is better but the server itself is not stable enough for production.

Ruby has to start by modernizing it’s preprocessor before it even has a small chance in hell of overtaking PHP and even then Rails has a long way to go before it’s ready for the primetime, the ease at which a programmer can cause Rails to leak memory is astounding.

By: Stefan Mischook in Killersite.com

symfony Open-Source PHP Web Framework

Posted on February 19th, 2008 in Frameworks by Ashish  Tagged , , ,

Symfony in Brief

A framework streamlines application development by automating many of the patterns employed for a given purpose. A framework also adds structure to the code, prompting the developer to write better, more readable, and more maintainable code. Ultimately, a framework makes programming easier, since it packages complex operations into simple statements.

Symfony is a complete framework designed to optimize the development of web applications by way of several key features. For starters, it separates a web application’s business rules, server logic, and presentation views. It contains numerous tools and classes aimed at shortening the development time of a complex web application. Additionally, it automates common tasks so that the developer can focus entirely on the specifics of an application. The end result of these advantages means there is no need to reinvent the wheel every time a new web application is built!

Symfony was written entirely in PHP 5. It has been thoroughly tested in various real-world projects, and is actually in use for high-demand e-business websites. It is compatible with most of the available databases engines, including MySQL, PostgreSQL, Oracle, and Microsoft SQL Server. It runs on *nix and Windows platforms. Let’s begin with a closer look at its features.

Symfony Features

Symfony was built in order to fulfill the following requirements:

* Easy to install and configure on most platforms (and guaranteed to work on standard *nix and Windows platforms)
* Database engine-independent
* Simple to use, in most cases, but still flexible enough to adapt to complex cases
* Based on the premise of convention over configuration–the developer needs to configure only the unconventional
* Compliant with most web best practices and design patterns
* Enterprise-ready–adaptable to existing information technology (IT) policies and architectures, and stable enough for long-term projects
* Very readable code, with phpDocumentor comments, for easy maintenance
* Easy to extend, allowing for integration with other vendor libraries

Automated Web Project Features

Most of the common features of web projects are automated within symfony, as follows:

* The built-in internationalization layer allows for both data and interface translation, as well as content localization.
* The presentation uses templates and layouts that can be built by HTML designers without any knowledge of the framework. Helpers reduce the amount of presentation code to write by encapsulating large portions of code in simple function calls.
* Forms support automated validation and repopulation, and this ensures a good quality of data in the database and a better user experience.
* Output escaping protects applications from attacks via corrupted data.
* The cache management features reduce bandwidth usage and server load.
* Authentication and credential features facilitate the creation of restricted sections and user security management.
* Routing and smart URLs make the page address part of the interface and search-engine friendly.
* Built-in e-mail and API management features allow web applications to go beyond the classic browser interactions.
* Lists are more user-friendly thanks to automated pagination, sorting, and filtering.
* Factories, plug-ins, and mixins provide a high level of extensibility.
* Ajax interactions are easy to implement thanks to one-line helpers that encapsulate cross-browser-compatible JavaScript effects.

Development Environment and Tools

To fulfill the requirements of enterprises having their own coding guidelines and project management rules, symfony can be entirely customized. It provides, by default, several development environments and is bundled with multiple tools that automate common software-engineering tasks:

* The code-generation tools are great for prototyping and one-click back-end administration.
* The built-in unit and functional testing framework provides the perfect tools to allow test-driven development.
* The debug panel accelerates debugging by displaying all the information the developer needs on the page he’s working on.
* The command-line interface automates application deployment between two servers.
* Live configuration changes are possible and effective.
* The logging features give administrators full details about an application’s activities.

Who Made Symfony and Why?

The first version of symfony was released in October 2005 by project founder Fabien Potencier, coauthor of this book. Fabien is the CEO of Sensio (http://www.sensio.com/), a French web agency well known for its innovative views on web development.

Back in 2003, Fabien spent some time inquiring about the existing open source development tools for web applications in PHP. He found that none fulfilled the previously described requirements. When PHP 5 was released, he decided that the available tools had reached a mature enough stage to be integrated into a full-featured framework. He subsequently spent a year developing the symfony core, basing his work on the Mojavi Model-View-Controller (MVC) framework, the Propel object-relational mapping (ORM), and the Ruby on Rails templating helpers.

Fabien originally built symfony for Sensio’s projects, because having an effective framework at your disposal presents an ideal way to develop applications faster and more efficiently. It also makes web development more intuitive, and the resulting applications are more robust and easier to maintain. The framework entered the proving grounds when it was employed to build an e-commerce website for a lingerie retailer, and subsequently was applied to other projects.

After successfully using symfony for a few projects, Fabien decided to release it under an open source license. He did so to donate this work to the community, to benefit from user feedback, to showcase Sensio’s experience, and because it’s fun.

Why "symfony" and not "FooBarFramework"? Because Fabien wanted a short name containing an s, as in Sensio, and an f, as in framework–easy to remember and not associated with another development tool. Also, he doesn’t like capital letters. symfony was close enough, even if not completely English, and it was also available as a project name. The other alternative was "baguette."

For symfony to be a successful open source project, it needed to have extensive documentation, in English, to increase the adoption rate. Fabien asked fellow Sensio employee François Zaninotto, the other author of this book, to dig into the code and write an online book about it. It took quite a while, but when the project was made public, it was documented well enough to appeal to numerous developers. The rest is history.

The Symfony Community

As soon as the symfony website (http://www.symfony-project.org/) was launched, numerous developers from around the world downloaded and installed the framework, read the online documentation, and built their first application with symfony, and the buzz began to mount.

Web application frameworks were getting popular at that time, and the need for a full-featured framework in PHP was high. Symfony offered a compelling solution due to its impressive code quality and significant amount of documentation–two major advantages over the other players in the framework category. Contributors soon began to surface, proposing patches and enhancements, proofreading the documentation, and performing other much-needed roles.

The public source repository and ticketing system offer a variety of ways to contribute, and all volunteers are welcome. Fabien is still the main committer in the trunk of the source code repository, and guarantees the quality of the code.

Today, the symfony forum, mailing lists, and Internet Relay Chat (IRC) channel offer ideal support outlets, with seemingly each question getting an average of four answers. Newcomers install symfony every day, and the wiki and code snippets sections host a lot of user-contributed documentation. The number of known symfony applications increases by an average of five per week, and counting.

Is Symfony for Me?

Whether you are a PHP 5 expert or a newcomer to web application programming, you will be able to use symfony. The main factor in deciding whether or not to do so is the size of your project.

If you want to develop a simple website with five to ten pages, limited access to a database, and no obligations to ensuring its performance or providing documentation, then you should stick with PHP alone. You wouldn’t gain much from a web application framework, and using object orientation or an MVC model would likely only slow down your development process. As a side note, symfony is not optimized to run efficiently on a shared server where PHP scripts can run only in Common Gateway Interface (CGI) mode.

On the other hand, if you develop more complex web applications, with heavy business logic, PHP alone is not enough. If you plan on maintaining or extending your application in the future, you will need your code to be lightweight, readable, and effective. If you want to use the latest advances in user interaction (like Ajax) in an intuitive way, you can’t just write hundreds of lines of JavaScript. If you want to have fun and develop fast, then PHP alone will probably be disappointing. In all these cases, symfony is for you.

And, of course, if you are a professional web developer, you already know all the benefits of web application frameworks, and you need one that is mature, well documented, and has a large community. Search no more, for symfony is your solution.

If you would like a visual demonstration, take a look at the screencasts available from the symfony website. You will see how fast and fun it is to develop applications with symfony.

Fundamental Concepts

Before you get started with symfony, you should understand a few basic concepts. Feel free to skip ahead if you already know the meaning of OOP, ORM, RAD, DRY, KISS, TDD, YAML, and PEAR.

PHP 5

Symfony is developed in PHP 5 (http://www.php.net/) and dedicated to building web applications with the same language. Therefore, a solid understanding of PHP 5 is required to get the most out of the framework.

Developers who already know PHP 4 but not PHP 5 should mainly focus on the language’s new object-oriented model.

Object-Oriented Programming (OOP)

Object-oriented programming (OOP) will not be explained in this chapter. It needs a whole book itself! Because symfony makes extensive use of the object-oriented mechanisms available as of PHP 5, OOP is a prerequisite to learning symfony.

Wikipedia explains OOP as follows:

The idea behind object-oriented programming is that a computer program may be seen as comprising a collection of individual units, or objects, that act on each other, as opposed to a traditional view in which a program may be seen as a collection of functions, or simply as a list of instructions to the computer.

PHP 5 implements the object-oriented paradigms of class, object, method, inheritance, and much more. Those who are not familiar with these concepts are advised to read the related PHP documentation, available at http://www.php.net/manual/en/language.oop5.basic.php.
Magic Methods

One of the strengths of PHP’s object capabilities is the use of magic methods. These are methods that can be used to override the default behavior of classes without modifying the outside code. They make the PHP syntax less verbose and more extensible. They are easy to recognize, because the names of the magic methods start with two underscores (__).

For instance, when displaying an object, PHP implicitly looks for a __toString() method for this object to see if a custom display format was defined by the developer:

$myObject = new myClass();
echo $myObject;
// Will look for a magic method
echo $myObject->__toString();

Symfony uses magic methods, so you should have a thorough understanding of them. They are described in the PHP documentation (http://www.php.net/manual/en/language.oop5.magic.php).

PHP Extension and Application Repository (PEAR)

PEAR is "a framework and distribution system for reusable PHP components." PEAR allows you to download, install, upgrade, and uninstall PHP scripts. When using a PEAR package, you don’t need to worry about where to put scripts, how to make them available, or how to extend the command-line interface (CLI).

PEAR is a community-driven project written in PHP and shipped with standard PHP distributions.

The PEAR website, http://pear.php.net/, provides documentation and packages grouped by categories.

PEAR is the most professional way to install vendor libraries in PHP. Symfony advises the use of PEAR to keep a central installation point for use across multiple projects. The symfony plug-ins are PEAR packages with a special configuration. The symfony framework itself is available as a PEAR package.

You don’t need to know all about the PEAR syntax to use symfony. You just need to understand what it does and have it installed. You can check that PEAR is installed in your computer by typing the following in a CLI:

> pear info pear

This command will return the version number of your PEAR installation.

The symfony project has its own PEAR repository, or channel. Note that channels are available only since version 1.4.0 of PEAR, so you should upgrade if your version is older. To upgrade your version of PEAR, issue the following command:

> pear upgrade PEAR

Object-Relational Mapping (ORM)

Databases are relational. PHP 5 and symfony are object-oriented. In order to access the database in an object-oriented way, an interface translating the object logic to the relational logic is required. This interface is called an object-relational mapping, or ORM.

An ORM is made up of objects that give access to data and keep business rules within themselves.

One benefit of an object/relational abstraction layer is that it prevents you from using a syntax that is specific to a given database. It automatically translates calls to the model objects to SQL queries optimized for the current database.

This means that switching to another database system in the middle of a project is easy. Imagine that you have to write a quick prototype for an application, but the client has not decided yet which database system would best suit his needs. You can start building your application with SQLite, for instance, and switch to MySQL, PostgreSQL, or Oracle when the client is ready to decide. Just change one line in a configuration file, and it works.

An abstraction layer encapsulates the data logic. The rest of the application does not need to know about the SQL queries, and the SQL that accesses the database is easy to find. Developers who specialize in database programming also know clearly where to go.

Using objects instead of records, and classes instead of tables, has another benefit: you can add new accessors to your tables. For instance, if you have a table called Client with two fields, FirstName and LastName, you might like to be able to require just a Name. In an object-oriented world, this is as easy as adding a new accessor method to the Client class, like this:

public function getName()
{
return $this->getFirstName().’ ‘.$this->getLastName();
}

All the repeated data-access functions and the business logic of the data can be maintained within such objects. For instance, consider a class ShoppingCart in which you keep items (which are objects). To retrieve the full amount of the shopping cart for the checkout, you can add a getTotal() method, like this:

public function getTotal()
{
$total = 0;
foreach ($this->getItems() as $item)
{
$total += $item->getPrice() * $item->getQuantity();
}
return $total;
}

And that’s it. Imagine how long it would have required to write a SQL query doing the same thing!

Propel, another open source project, is currently one of the best object/relational abstraction layers for PHP 5. Symfony integrates Propel seamlessly into the framework, so most of the data manipulation described in this book follows the Propel syntax. This book will describe how to use the Propel objects, but for a more complete reference, a visit to the Propel website (http://propel.phpdb.org/trac/) is recommended.

Rapid Application Development (RAD)

Programming web applications has long been a tedious and slow job. Following the usual software engineering life cycles (like the one proposed by the Rational Unified Process, for instance), the development of web applications could not start before a complete set of requirements was written, a lot of Unified Modeling Language (UML) diagrams were drawn, and tons of preliminary documentation were produced. This was due to the general speed of development, to the lack of versatility of programming languages (you had to build, compile, restart, and who knows what else before actually seeing your program run), and most of all, to the fact that clients were quite reasonable and didn’t change their minds constantly.

Today, business moves faster, and clients tend to constantly change their minds in the course of the project development. Of course, they expect the development team to adapt to their needs and modify the structure of an application quickly. Fortunately, the use of scripting languages like Perl and PHP makes it easy to apply other programming strategies, such as rapid application development (RAD) or agile software development.

One of the ideas of these methodologies is to start developing as soon as possible so that the client can review a working prototype and offer additional direction. Then the application gets built in an iterative process, releasing increasingly feature-rich versions in short development cycles.

The consequences for the developer are numerous. A developer doesn’t need to think about the future when implementing a feature. The method used should be as simple and straightforward as possible. This is well illustrated by the maxim of the KISS principle: Keep It Simple, Stupid.

When the requirements evolve or when a feature is added, existing code usually has to be partly rewritten. This process is called refactoring, and happens a lot in the course of a web application development. Code is moved to other places according to its nature. Duplicated portions of code are refactored to a single place, thus applying the Don’t Repeat Yourself (DRY) principle.

And to make sure that the application still runs when it changes constantly, it needs a full set of unit tests that can be automated. If well written, unit tests are a solid way to ensure that nothing is broken by adding or refactoring code. Some development methodologies even stipulate writing tests before coding–that’s called test-driven development (TDD).

There are many other principles and good habits related to agile development. One of the most effective agile development methodologies is called Extreme Programming (abbreviated as XP), and the XP literature will teach you a lot about how to develop an application in a fast and effective way. A good starting place is the XP series books by Kent Beck (Addison-Wesley).

Symfony is the perfect tool for RAD. As a matter of fact, the framework was built by a web agency applying the RAD principle for its own projects. This means that learning to use symfony is not about learning a new language, but more about applying the right reflexes and the best judgment in order to build applications in a more effective way.

The symfony project website proposes a step-by-step tutorial illustrating the development of an application in an agile way. It is called askeet (http://www.symfony-project.org/askeet), and is recommended reading for those who want to learn more about agile development.

YAML

According to the official YAML website (http://www.yaml.org/), YAML is "a straightforward machine parsable data serialization format designed for human readability and interaction with scripting languages." Put another way, YAML is a very simple language used to describe data in an XML-like way but with a much simpler syntax. It is especially useful to describe data that can be translated into arrays and hashes, like this:

$house = array(
‘family’ => array(
‘name’ => ‘Doe’,
‘parents’ => array(’John’, ‘Jane’),
‘children’ => array(’Paul’, ‘Mark’, ‘Simone’)
),
‘address’ => array(
‘number’ => 34,
’street’ => ‘Main Street’,
‘city’ => ‘Nowheretown’,
‘zipcode’ => ‘12345′
)
);

This PHP array can be automatically created by parsing the YAML string:

house:
family:
name: Doe
parents:
- John
- Jane
children:
- Paul
- Mark
- Simone
address:
number: 34
street: Main Street
city: Nowheretown
zipcode: "12345"

In YAML, structure is shown through indentation, sequence items are denoted by a dash, and key/value pairs within a map are separated by a colon. YAML also has a shorthand syntax to describe the same structure with fewer lines, where arrays are explicitly shown with [] and hashes with {}. Therefore, the previous YAML data can be written in a shorter way, as follows:

house:
family: { name: Doe, parents: [John, Jane], children: [Paul, Mark, Simone] }
address: { number: 34, street: Main Street, city: Nowheretown, zipcode: "12345" }

YAML is an acronym for "YAML Ain’t Markup Language" and pronounced "yamel". The format has been around since 2001, and YAML parsers exist for a large variety of languages.

The specifications of the YAML format are available at http://www.yaml.org/.

As you can see, YAML is much faster to write than XML (no more closing tags or explicit quotes), and it is more powerful than .ini files (which don’t support hierarchy). That is why symfony uses YAML as the preferred language to store configuration. You will see a lot of YAML files in this book, but it is so straightforward that you probably don’t need to learn more about it.

For Installation Instruction Please Visit Here.

CakePHP an Open Source PHP Framework

Posted on February 18th, 2008 in Frameworks by Ashish  Tagged , , ,

CakePHP is a free open-source rapid development framework for PHP. Its a structure of libraries, classes and run-time infrastructure for programmers creating web applications originally inspired by the Ruby on Rails framework. Primary goal is to enable developers to work in a structured and rapid manner – without loss of flexibility.

In 2005, Michal Tatarynowicz wrote a minimal version of a Rapid Application Framework in PHP. He found that it was the start of a very good framework. Michal published the framework under the MIT license, dubbing it Cake, and opened it up to a community of developers, who now maintain Cake under the name CakePHP.

Features of CakePHP

CakePHP has several features that make it a great choice as a framework for developing applications swiftly and with the least amount of hassle. Here are a few in no particular order:

1. Active, friendly community
2. Flexible Licensing
3. Compatibility with PHP4 and PHP5
4. Integrated CRUD for database interaction and simplified queries
5. Application Scaffolding
6. Model View Controller (MVC) Architecture
7. Request dispatcher with good looking, custom URLs
8. Built-in Validation
9. Fast and flexible templating (PHP syntax, with helpers)
10. View Helpers for AJAX, Javascript, HTML Forms and more
11. Security, Session, and Request Handling Components
12. Flexible access control lists
13. Data Sanitization
14. Flexible View Caching
15. Works from any web site subdirectory, with little to no Apache configuration involved

Requirements

In order use CakePHP you must first have a server that has all the required libraries and programs to run CakePHP:
Server Requirements

Here are the requirements for setting up a server to run CakePHP:

1. An HTTP server (like Apache) with the following enabled: sessions, mod_rewrite (not absolutely necessary but preferred)
2. PHP 4.3.2 or greater. Yes, CakePHP works great in either PHP 4 or 5.
3. A database engine (right now, there is support for MySQL 4+, PostgreSQL and a wrapper for ADODB).

Installing CakePHP : Getting the most recent stable version

There are a few ways you can secure a copy of CakePHP: getting a stable release from CakeForge, grabbing a nightly build, or getting a fresh version of code from SVN.

To download a stable version of code, check out the files section of the CakePHP project at CakeForge by going to http://cakeforge.org/projects/cakephp/.

To grab a nightly, download one from http://cakephp.org/downloads/index/nightly. These nightly releases are stable, and often include the bug fixes between stable releases.

To grab a fresh copy from our SVN repository, use your favorite SVN client and connect to https://svn.cakephp.org/repo/trunk/cake/ and choose the version you’re after.

Unpacking

Once you’ve downloaded the most recent release, place that compressed package on your web server in the webroot. Now you need to unpack the CakePHP package. There are two ways to do this, using a development setup, which allows you to easily view many CakePHP applications under a single domain, or using the production setup, which allows for a single CakePHP application on the domain.

Setting Up CakePHP

The first way to setup CakePHP is generally only recommended for development environments because it is less secure. The second way is considered more secure and should be used in a production environment.

NOTE: /app/tmp must be writable by the user that your web server runs as.

Development Setup

For development we can place the whole Cake installation directory inside the specified DocumentRoot like this:

/wwwroot
/cake
/app
/cake
/vendors
.htaccess
index.php

In this setup the wwwroot folder acts as the web root so your URLs will look something like this (if you’re also using mod_rewrite):

www.example.com/cake/controllerName/actionName/param1/param2

Production Setup

In order to utilize a production setup, you will need to have the rights to change the DocumentRoot on your server. Doing so, makes the whole domain act as a single CakePHP application.

The production setup uses the following layout:

../path_to_cake_install
/app
/config
/controllers
/models
/plugins
/tmp
/vendors
/views
/webroot <– This should be your new DocumentRoot
.htaccess
index.php
/cake
/vendors
.htaccess
index.php

Suggested Production httpd.conf

DocumentRoot /path_to_cake/app/webroot

In this setup the webroot directory is acting as the web root so your URLs might look like this (if you’re using mod_rewrite):

http://www.example.com/controllerName/actionName/param1/param2

Advanced Setup: Alternative Installation Options

There are some cases where you may wish to place Cake’s directories on different places on disk. This may be due to a shared host restriction, or maybe you just want a few of your apps to share the same Cake libraries.

There are three main parts to a Cake application:

1. The core CakePHP libraries – Found in /cake
2. Your application code (e.g. controllers, models, layouts and views) – Found in /app
3. Your application webroot files (e.g. images, javascript and css) – Found in /app/webroot

Each of these directories can be located anywhere on your file system, with the exception of the webroot, which needs to be accessible by your web server. You can even move the webroot folder out of the app folder as long as you tell Cake where you’ve put it.

To configure your Cake installation, you’ll need to make some changes to /app/webroot/index.php (as it is distributed in Cake). There are three constants that you’ll need to edit: ROOT, APP_DIR, and CAKE_CORE_INCLUDE_PATH.

1. ROOT should be set to the path of the directory that contains your app folder.
2. APP_DIR should be set to the path of your app folder.
3. CAKE_CORE_INCLUDE_PATH should be set to the path of your Cake libraries folder.

/app/webroot/index.php (partial, comments removed)
if (!defined(’ROOT’))
{
define(’ROOT’, dirname(dirname(dirname(__FILE__))));
}

if (!defined(’APP_DIR’))
{
define (’APP_DIR’, basename(dirname(dirname(__FILE__))));
}

if (!defined(’CAKE_CORE_INCLUDE_PATH’))
{
define(’CAKE_CORE_INCLUDE_PATH’, ROOT);
}

An example might help illustrate this better. Imagine that I wanted to set up Cake to work with the following setup:

1. I want my Cake libraries shared with other applications, and placed in /usr/lib/cake.
2. My Cake webroot directory needs to be /var/www/mysite/.
3. My application files will be stored in /home/me/mysite.

Here’s what the file setup looks like:

/home
  /me
   /mysite <– Used to be /cake_install/app
      /config
      /controllers
      /models
      /plugins
      /tmp
      /vendors
      /views
      index.php

/var
   /www
     /mysite <– Used to be /cake_install/app/webroot
       /css
       /files
       /img
       /js
       .htaccess
        css.php
        favicon.ico
        index.php

/usr
    /lib
        /cake <– Used to be /cake_install/cake
            /cake
                /config
                /docs
                /libs
                /scripts
                app_controller.php
                app_model.php
                basics.php
                bootstrap.php
                dispatcher.php
                /vendors

Given this type of setup, I would need to edit my webroot index.php file (which should be at /var/www/mysite/index.php, in this example) to look like the following:

It is recommended to use the ‘DS’ constant rather than slashes to delimit file paths. This prevents any ‘missing file’ errors you might get as a result of using the wrong delimiter, and it makes your code more portable.
if (!defined(’ROOT’))
{
define(’ROOT’, DS.’home’.DS.’me’);
}

if (!defined(’APP_DIR’))
{
define (’APP_DIR’, ‘mysite’);
}

if (!defined(’CAKE_CORE_INCLUDE_PATH’))
{
define(’CAKE_CORE_INCLUDE_PATH’, DS.’usr’.DS.’lib’.DS.’cake’);
}

Configuring Apache and mod_rewrite

While CakePHP is built to work with mod_rewrite out of the box, we’ve noticed that a few users struggle with getting everything to play nicely on their systems. Here are a few things you might try to get it running correctly:

1. Make sure that an .htaccess override is allowed: in your httpd.conf, you should have a section that defines a section for each Directory on your server. Make sure the AllowOverride is set to All for the correct Directory.
2. Make sure you are editing the system httpd.conf rather than a user- or site-specific httpd.conf.
3. For some reason or another, you might have obtained a copy of CakePHP without the needed .htaccess files. This sometimes happens because some operating systems treat files that start with ‘.’ as hidden, and don’t copy them. Make sure your copy of CakePHP is from the downloads section of the site or our SVN repository.
4. Make sure you are loading up mod_rewrite correctly! You should see something like LoadModule rewrite_module libexec/httpd/mod_rewrite.so and AddModule mod_rewrite.c in your httpd.conf.
5. If you are installing Cake into a user directory (http://example.com/~myusername/), you’ll need to modify the .htaccess files in the base directory of your Cake installation, and in the app/webroot folder. Just add the line "RewriteBase /~myusername/".
6. If for some reason your URLS are suffixed with a long, annoying session ID (http://example.com/posts/?CAKEPHP=4kgj577sgabvnmhjgkdiuy1956if6ska), you might also add "php_flag session.trans_id off" to the .htaccess file at the root of your installation as well.

Database Configuration

Your app/config/database.php file is where your database configuration all takes place. A fresh install doesn’t have a database.php, so you’ll need to make a copy of database.php.default. Once you’ve made a copy and renamed it you’ll see the following:

app/config/database.php

var $default = array(’driver’ => ‘mysql’,
‘connect’ => ‘mysql_connect’,
‘host’ => ‘localhost’,
‘login’ => ‘user’,
‘password’ => ‘password’,
‘database’ => ‘project_name’,
‘prefix’ => ”);

Replace the information provided by default with the database connection information for your application.

One note about the prefix key: the string you enter there will be prepended to any SQL call that Cake makes to your database when working with tables. You define it here once so you don’t have to specify it in other places. It also allows you to follow Cake’s table naming conventions if you’re on a host that only gives you a single database. Note: for HABTM join tables, you only add the prefix once: prefix_apples_bananas, not prefix_apples_prefix_bananas.

CakePHP supports the following database drivers:

1. mysql
2. postgres
3. sqlite
4. pear-drivername (so you might enter pear-mysql, for example)
5. adodb-drivername

The ‘connect’ key in the $default connection allows you to specify whether or not the database connection will be treated as persistent or not. Read the comments in the database.php.default file for help on specifying connection types for your database setup.

Your database tables should also follow the following conventions:

1. Table names used by Cake should consist of English words in plural, like "users", "authors" or "articles". Note that corresponding models have singular names.
2. Your tables must have a primary key named ‘id’.
3. If you plan to relate tables, use foreign keys that look like: ‘article_id’. The table name is singular, followed by an underscore, followed by ‘id’.
4. If you include a ‘created’ and/or ‘modified’ column in your table, Cake will automatically populate the field when appropriate.

You’ll also notice that there is a $test connection setting included in the database.php file. Fill out this configuration (or add other similarly formatted configurations) and use it in your application by placing something like:
var $useDbConfig = ‘test’;

Inside one of your models. You can add any number of additional connection settings in this manner.

Global Configuration

CakePHP’s global configuration can be found in app/config/core.php. While we really dislike configuration files, it just had to be done. There are a few things you can change here, and the notes on each of these settings can be found within the comments of the core.php file.

DEBUG: Set this to different values to help you debug your application as you build it. Specifying this setting to a non-zero value will force Cake to print out the results of pr( ) and debug( ) function calls, and stop flash messages from forwarding automatically. Setting it to 2 or higher will result in SQL statements being printed at the bottom of the page.

Also when in debug mode (where DEBUG is set to 1 or higher), Cake will render certain generated error pages, i.e. "Missing Controller," "Missing Action," etc. In production mode, however (where DEBUG is set to 0), Cake renders the "Not Found" page, which can be overridden in app/views/errors/error404.thtml.

CAKE_SESSION_COOKIE: Change this value to the name of the cookie you’d like to use for user sessions in your Cake app.

CAKE_SECURITY: Change this value to indicate your preferred level of sessions checking. Cake will timeout sessions, generate new session ids, and delete old session files based on the settings you provide here. The possible values are:

1. high: sessions time out after 20 minutes of inactivity, and session id’s are regenerated on each request
2. medium: sessions time out after 200 minutes of inactivity
3. low: sessions time out after 600 minutes of inactivity

CAKE_SESSION_SAVE: Specify how you’d like session data saved. Possible values are:

1. cake: Session data is saved in tmp/ inside your Cake installation
2. php: Session data saved as defined in php.ini
3. database: Session data saved to database connection defined by the ‘default’ key.

Routes Configuration

"Routing" is a pared-down pure-PHP mod_rewrite-alike that can map URLs to controller/action/params and back. It was added to Cake to make pretty URLs more configurable and to divorce us from the mod_rewrite requirement. Using mod_rewrite, however, will make your address bar look much more tidy.

Routes are individual rules that map matching URLs to specific controllers and actions. Routes are configured in the app/config/routes.php file. They are set-up like this:

Route Pattern
<?php
$Route->connect (
‘URL’,
array(’controller’=>’controllername’,
‘action’=>’actionname’, ‘firstparam’)
);
?>

Where:

1. URL is the regular expression Cake URL you wish to map,
2. controllername is the name of the controller you wish to invoke,
3. actionname is the name of the controller’s action you wish to invoke,
4. and firstparam is the value of the first parameter of the action you’ve specified.

Any parameters following firstparam will also be passed as parameters to the controller action.

Next Page »