<?xml version="1.0"?>
<record><wiki id="wiki?page_id=100">
	<page_name>calendar</page_name>
	<page_id>100</page_id>
	<page_title>Calendar Widget</page_title>
	<content>Back to [[widget:type]]

[[toc]]

===Synopsis===

The calendar widget is the default widget for editing date and datetime fields.  It is javascript pop-up calendar that allows users to select date and time visually.  It can be configured to allow different date and time formats, themes, starting days of the week, and more.

[[image:http://media.weblite.ca/files/photos/calendar_widget.png?max_width=400]]

===Usage===

For DATE and DATETIME fields, the calendar widget is the default widget used, so you need not specify it explicitly in the fields.ini file.  For other types of fields you may designate them to use the calendar widget in the [[fields.ini file]] as follows:

&lt;code&gt;
[my_field]
    widget:type=calendar
&lt;/code&gt;

===Configuration Options===

The calendar widget supports some configuration options that can be set in the [[fields.ini file]].  These options are as follows:

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Default
! Version
|-
| [[widget:lang]]
| The language to use for the calendar.  This is a 2-digit ISO language code.
| en
| 0.5.3
|-
| [[widget:theme]]
| The theme to use for the calendar.  It only ships with one theme at present.
| calendar-win2k-2
| 0.5.3
|-
| [[widget:firstDay]]
| The first day of the week  (e.g. Monday=1)
| 1
| 0.5.3
|-
| [[widget:showsTime]]
| Boolean value indicating whether the calendar should show the time as well.
| 0 for DATE fields, 1 for DATETIME fields.
| 0.5.3
|-
| [[widget:ifFormat]]
| The input format of the date.  This takes a formatting string as supported by [http://ca2.php.net/strftime the strftime function].
| %Y-%m-%d %I:%M %P
| 0.5.3
|-
| [[widget:timeFormat]]
| Whether to use 12 hour or 24 hour time format.
| 12
| 0.5.3
|}

===Examples===

====Setting the time to use 24 hour format====

In your [[fields.ini file]]:
&lt;code&gt;
[my_field]
    wiget:type=calendar
    widget:timeFormat = 24
&lt;/code&gt;


===See Also===

* [[date]] Widget - A widget for editing date and time using select drop-down lists.
* [[time]] Widget - A widget for selecting time from a set of possibilities in a single select list.</content>
	<keywords>calendar widget, fields.ini file, widget:type</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=70">
	<page_name>documentation_guide</page_name>
	<page_id>70</page_id>
	<page_title>Documentation Guide</page_title>
	<content>Xataface uses a wiki to manage its online documentation which can be edited by anyone.  All you have to do is [http://xataface.com/wiki/index.php?-action=login login with your forum username and password] ([http://xataface.com/forum/profile.php?mode=register register for the forum here]).  Then when you are browsing a page of the wiki, you&apos;ll see an &apos;Edit&apos; tab along the top.  Click on this tab to start editing the page in your browser.  Wiki markup is a little simpler than HTML and a little more complex than plain text.  It is easy to get a handle on once you get started.  If you aren&apos;t sure how to format it exactly how you want, don&apos;t worry.  Someone may come by after you and improve on your formatting.  That&apos;s what the community approach is all about.

==The Documentation Team==

Join the Xataface documentation team to help participate in the planning of the documentation.  If you want to help out, contact [mailto:steve@weblite.ca Steve Hannah] and he&apos;ll add you to the documentation group where you can access the private documentation forums and meet the rest of the team.

==Using the Wiki==

The following is a brief guide in using the Xataface Wiki.  All following instructions assume that you are already [http://xataface.com/wiki/index.php?-action=login logged in] to the wiki.  You can use your forum username and password to login.

===Editing an Existing Page===

# Navigate to the page that you want to edit
# Click on the &quot;Edit&quot; tab along the top.
# Make changes to your page.
# Save the changes.

===Adding a New Page===

====Method 1: Add a link from an existing page===

# Navigate to an existing page that you want to link to your new page.
# Click on the &quot;Edit&quot; tab along the top.
# Somewhere in the content of the page, add a link to your new page (which doesn&apos;t exist yet), by adding the following markup&lt;code&gt;
[[The name of your new page]]
&lt;/code&gt;
# Save your changes.
# Click on the &quot;view&quot; tab along the top and find the place where you added your link.  It should be displayed with a &apos;?&apos; right after it.  Click on the &apos;?&apos; and it will bring you to the &quot;new page form&quot;.
# fill in the form with your page contents and click save.

====Method 2: Accessing new page form directly====

# Access the [http://xataface.com/wiki/index.php?-action=new&amp;-table=wiki new page form] directly.


===Uploading Images===

Image can be uploaded at [http://media.weblite.ca The Web Lite Media Manager].  You&apos;ll need an account to access this site.  If you are a member of the documentation team you can request an account from [mailto:steve@weblite.ca Steve Hannah] so that you can upload images here.

Steps:

# Log into [http://media.weblite.ca the Web Lite Media Manager].
# Click on &quot;Add New File&quot; in the menu on the left.
# Select a name for the file, and browse to the image you want to upload in the file upload field.  You don&apos;t need to check any category boxes.  Press save.
# Click on the &quot;View&quot; tab for your newly uploaded image.
# Copy the embed code for the image from the &quot;Embed Code&quot; field.
# In the wiki page add the embed code where you want your image to appear as follows:&lt;code&gt;
[[Image:EMBED_CODE]]
&lt;/code&gt; Where EMBED_CODE is the URL for the image as you copied and pasted out of the media manager.
# Save your changes.

===Uploading Video===

===Adding Source Code Snippets===</content>
	<keywords>documentation wiki</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=71">
	<page_name>GettingStarted:Introduction</page_name>
	<page_id>71</page_id>
	<page_title>Introduction</page_title>
	<content>Web Lite is a simple framework for building data-driven web applications in PHP and MySQL. This section introduces some of the concepts and applications of Dataface.

To fully understand what Xataface is, we must first define a few key terms:

&apos;&apos;&apos;Framework&apos;&apos;&apos; - A set of software routines that provide a foundation structure for an application. Frameworks take the tedium out of writing an application from scratch. (From Answers.com)

&apos;&apos;&apos;Data-driven design&apos;&apos;&apos;- Designing an application around the data that it will store.

Xataface is a &apos;&apos;Framework&apos;&apos; in the sense that it is a set of classes and libraries that take the tedium out of writing web applications. It provides a simple web interface to a MySQL database enabling users to update, delete, and find data in the underlying database. The interface is targeted at secretaries and end-users as opposed to database administrators.

Xataface enables &apos;&apos;data-driven design&apos;&apos; because it allows developers to develop web sites by first designing the database that will be used to store the data on the website, and then design the pages used to display the data. The developer can focus on the data because he or she does not have to worry about having to build forms to update the data. If the requirements of the application change, the developer can simply add a field to the database table and all associated web forms will be updated automatically (because they are all dynamically generated using the database schema).


===Requirements===

* [http://php.net PHP] &gt;= 4.3
* [http://mysql.com MySQL] &gt;= 3.2.3

===Key Technologies===

* [http://pear.php.net PEAR class libraries] (HTML_QuickForm, etc...)
* [http://smarty.net Smarty Templating Engine]
* [http://plone.org Plone] Javascript and CSS style sheets

===Development Procedures===

# Identify the data that will need to be stored for a web site.
##[[Image:http://xataface.com/documentation/tutorial/getting_started/er-diagram.png]]
# Design the database using your favorite database administration program (e.g., PHPMyAdmin)
##[[Image:http://xataface.com/documentation/tutorial/getting_started/phpMyAdmin-1-small.gif]]
# Tell Xataface some DB connection info, and voila! You have an application:
##[[Image:http://xataface.com/documentation/tutorial/getting_started/new-record-form-1-small.gif]]

===Where to go from here===

This tutorial will teach you the basics of Xataface and how to construct a simple application using the Xataface. After reading this tutorial you will be ready to tackle some medium to large web sites with the help of the Xataface reference documentation. You are also encouraged to mail the [http://xataface.com/forum Xataface forum] if you have questions.</content>
	<keywords>introduction requirements getting started</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=72">
	<page_name>GettingStarted:Why_Use_Xataface</page_name>
	<page_id>72</page_id>
	<page_title>Why Use Xataface</page_title>
	<content>==Why Use Xataface?==

Some simple examples similar to those that are frequently encountered by web developers, and how dataface can be used to acheive a solution.
As a web services developer in the Faculty of Applied Sciences at Simon Fraser University, I am frequently getting requests to build websites that are manageable by the site owner. Most of these requests also specify certain types of content that must be stored on the website, and much of this content needs to be n-ary (i.e., there will be multiple instances of each type of content). Let me give you an example.

===Example 1: Website for Faculty of Widgetry===

The Faculty of Widgetry needs a website to publish information about its undergraduate programs. It is important for them to be able to publish admission requirements, and program overviews for each program. It is also important to have course outlines and timetables for each course. The Faculty of Widgetry has 12 undergraduate programs and over 100 courses offered.

====Solution 1: Static HTML====

To build this web site using only static HTML pages using Dreamweaver or some other HTML editor would require at least 112 pages to be created (one for each course and program). However, once we recognize that there are only 2 types of pages required (one for courses and one for programs), we can reduce the task down to creating 2 templates and filling in the main content for each program and course individually. Most HTML editors have some templating ability so you can make changes to the template and have the changes propogated to all pages that use that template with the click of a button.

This works great, but courses are added frequently, and outlines are changed. Do you really want to receive requests to update all of these pages every time there are changes to make? (If your answer is &apos;yes&apos;, then you probably won&apos;t be interested in reading the rest of this tutorial). Whether the Dean of the faculty knows it or not, it is very important for the program assistants to be able to update these web pages on their own. To acheive these goals you can:

* Install Dreamweaver on the Program Assistants&apos; computers, teach them how to use it, and allow them to perform updates.
* Install Contribute, which is a scaled down version of Dreamweaver to make it easier for the Program Assistants to edit the content.
* Use another solution that is equivalent to one of the above 2 solutions.

Installing Dreamweaver for each Program Assistant is a little overkill, and since it has the ability to do much more than just update content. In addition, Dreamweaver is really a developer&apos;s tool - not a secretary&apos;s tool, so it can be difficult to learn at first. The best reason NOT to install Dreamweaver on the Program Assistant&apos;s computer, however, is that it enables him/her to muck things up by accident (believe me, I has happened to me more times than I care to count).

Admittedly, Contribute is a viable option as it controls access to only certain portions of web pages to be edited, and it is targetted at secretaries (not developers) so it is easier to use. In fact, given the requirements for this web site (as stated above), this is a perfectly good solution. However you better hope that none of the following requirements are added:

* Each program web page should contain an up-to-date list of all of the courses required for the program, along with a link to the course outline for that course.
* Course outlines should be available in PDF format as well as HTML format.
* An index page showing all of the courses available should be added. This page must allow courses to be organized by program, course subject, or course number.
* Any other requirement that would have information formatted in more than one way.

If any of these requirements are likely to be added (EVER) then you would be well-advised to look into solutions that use a database back-end.

====Solution 2: Use a Content Management System (CMS)====

There are hundreds of content management systems available that will allow you to store and update content through the web (TTW). Some of them even have an assortment of add-ons that will allow you to store more specific types of information. Some good CMS&apos;s include Plone, Drupal, and Xoops. Suppose we want to develop the Faculty of Widgetry website using one of these CMS&apos;s. Any good CMS will allow you to create and edit HTML documents easily (without having to write any custom products). However, it is often the case that our documents require the content to be structured. For example, each program has some common data associated with it: Program Name, Admission Deadline, Program Description, Outline, Courses, etc... If we want to properly separate data from presentation, we would need to build a special content-type to store our programs. Most CMS&apos;s allow you to develop custom content-types using the underlying programming language and an API (Application Programming Interface). Some API&apos;s are easier to use than others and some are documented better than others. The common element is that each has its own proprietary interface for writing these add-ons.

If you are using a CMS and you are proficient in the creation of add-on content-types, then you will be able to build the Faculty of Widgetry website without great difficulty. However there are a number of reasons why you may choose NOT to use a CMS:

* Steep learning curve: Depending on the CMS it can be very time consuming and difficult to learn how to use and modify the CMS to suit you purposes.
* It is over-kill: Most CMS&apos;s are filled with features and modules that you will never need. In fact it can even be a pain to turn them off if you don&apos;t want them.
* You can get tied into the CMS: When you are using a CMS, you will start developing for the CMS. With all of your content in the CMS it may be difficult to migrate to a different solution later on. (The truth of this statement will vary for different CMS&apos;s). Choose your CMS carefully.

====Solution 3: Use an existing Application====

OK, OK, let&apos;s not get too carried away with trying to develop the website until we have checked the market to see if someone else has already done it better. Maybe there is already a PHP application that makes websites for Faculties easy. I mean, I can&apos;t be the first person that needed to build a website for a Faculty. In fact if you do a search or go to Hotscripts.com, you will probably find a handful of applications or scripts that almost do what you need. If you&apos;re lucky, maybe you can find an application that does exactly what you need (but frankly, I&apos;ve never been that lucky). If you find one, maybe it&apos;s worth taking it for a test drive. But beware. Using a system that almost does what you need but is difficult to modify to your needs can be worse than building it by scratch. Make sure that you are able to modify the application to suit your needs exactly.

====Solution 4: Use PHP and MySQL====

If all we want to do is separate the data from the presentation and allow the Program Assistants to update data on the website, why not just design a MySQL database with the appropriate tables and fields to store the required data. In our case we will need 2 tables:

&apos;&apos;&apos;Programs&apos;&apos;&apos;: 

* Fields:
** ProgramID : int
** ProgramName : varchar
** ProgramDescription: text
** AdmissionDeadline: date
** Outline_HTML : text
** Outline_PDF : blob


&apos;&apos;&apos;Courses&apos;&apos;&apos;:
* Fields:
** CourseID : int
** CourseSubject : varchar
** CourseTitle : varchar
** CourseNumber : int
** ProgramID : int
** CourseDescription : text
** Outline_HTML : text
** Outline_PDF : blob


Now it&apos;s easy to create a few web pages that extract data from the database and displays it as HTML. In fact if there is an existing page template that you can use for the header and footer, you can develop the entire Faculty website in under an hour (you just have to create 3 pages).

&apos;&apos;&apos;Question&apos;&apos;&apos;: How will the Program Assistants update the information in the database?

&apos;&apos;&apos;Answer&apos;&apos;&apos;: OK, let&apos;s assume that you&apos;re not going to teach them SQL and that a DB Admin tool will also be too difficult to learn. Then you have to create HTML forms to update records in the database.

Ouch! What was easy just became hard. Making HTML forms is a real pain, because you have to validate the input, deal with file uploads, and also make sure that everything is stored to the database OK without losing any information. Such a basic task, but it can be very difficult. This is when it is time to use Xataface.

====Solution 5: Use Xataface====

OK, this isn&apos;t really its own solution. It is more like &quot;Solution 4 Part II&quot;, because Xataface is intended to complement your custom application you built with solution 4, by providing an easy-to-use, configurable user interface that is targeted at secretaries and normal users (as opposed to database administrators). A Xataface application takes only seconds to set up and it will provide you with a full user interface for your users to edit information in the database.</content>
	<keywords>introduction motivation why</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=73">
	<page_name>GettingStarted:Installation</page_name>
	<page_id>73</page_id>
	<page_title>Installation</page_title>
	<content>==Installation==

Download and installation instructions for the Web Lite framework.
Xataface is a 100% PHP Framework that comes with all dependencies as part of the installation. The framework itself lives inside a single directory that should be placed inside the document root of your web server so that it can be accessed from the web. You can install a single copy of Xataface to be used by multiple applications on your web server. Each application just &quot;requires&quot; the key files from the Web Lite framework.

===Downloading===

# Go to the Xataface Sourceforge project file releases page
# Download the latest file release.

===Installing===

# Unpack the gzipped tar archive that you downloaded somewhere in your web server&apos;s document root (i.e., make sure that the &apos;dataface&apos; directory is in a web-accessible location).
# Make the dataface/Dataface/templates_c directory writable by the web server.  An unsafe way to do this is to 
 chmod 777 Dataface/templates_c
But it would be better to just give write access to the web server user.
# Confirm that the installation worked by pointing the web browser to http://yourdomain.com/path/to/dataface/dataface_info.php . If it worked OK, you should receive a web page that says &quot;Dataface is installed correctly&quot;, along with some basic instructions for creating a Xataface Application. (Note: Sometimes this page will give you a false positive. i.e., it may say the installation worked but then your Xataface application receives errors. Check the troubleshooting section below to deal with these issues).

===Troubleshooting===

If your installation is not going as planned, don&apos;t panic. There is a possiblity that your system has a slightly different configuration and you have to make some small adjustments to make the installation work.

The general procedure for troubleshooting the installation is as follows:

# Check the [[Troubleshooting]] page.
# Look through the [http://xataface.com/forum forum] to see if others have experienced the same thing.
# Post your question in the forum if you can&apos;t find the answer already.

</content>
	<keywords>installation troubleshooting downloading </keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=74">
	<page_name>GettingStarted:first_application</page_name>
	<page_id>74</page_id>
	<page_title>Creating your First Application</page_title>
	<content>==Creating Your First Application==

Build a simple Xataface application.

For our first Xataface application we will try to build a web site for Faculty of Widgetry (From the example in the &quot;Why Use Xataface&quot; page). The web site needs to store information about programs and courses. An entity-relationship diagram (ERD) for this website is included below:

[[Image:http://xataface.com/documentation/tutorial/getting_started/er-diagram.png]]

As the ERD shows, our database will need 2 tables (Course and Program). Our next step is to build this database. You can use any MySQL database administration tool to builld the database. My personal tool of choice is PHPMyAdmin.

===Step 1: Creating the database using PHPMyAdmin===

The following steps describe the procedure for creating this database using PHPMyAdmin.

# At the main menu of PHPMyAdmin, type &apos;FacultyOfWidgetry&apos; into the &apos;Create new database field&apos; as follows: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/new_database.gif]] &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;Then click &apos;Create&apos;.
# First we will create the &apos;Course&apos; table to hold course information. In the &apos;FacultyOfWidgetry&apos; page, fill in the &apos;Create new table text field as follows: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/create_table.gif]] &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt; Then click &apos;Go&apos;.
# This should bring up a form to specify the fields for the course table: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/course-table-def-small.gif]] &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt; Then click &quot;Save&quot;. The resulting SQL to create the Course table is as follows:&lt;code&gt;
CREATE TABLE `Course` (
 `CourseID` int(11) NOT NULL auto_increment,
 `ProgramID` int(11),
 `CourseTitle` varchar(64) NOT NULL default &apos;&apos;,
 `CourseDescription` text NOT NULL,
 `HTMLOutline` text NOT NULL,
 `PDFOutline` longblob NOT NULL,
 `PDFOutline_mimetype` varchar(64),
 `Subject` varchar(128) NOT NULL default &apos;&apos;,
 `CourseNumber` varchar(10) NOT NULL default &apos;&apos;,
 `Credits` int(5) NOT NULL default &apos;0&apos;,
 `LastModified` timestamp NOT NULL default CURRENT_TIMESTAMP,
 PRIMARY KEY (`CourseID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT=&apos;Store courses&apos; AUTO_INCREMENT=1 ;
&lt;/code&gt;
#In a similar fashion, create the Program table. The resulting SQL for this table is:&lt;code&gt;
CREATE TABLE `Program` (
 `ProgramID` int(11) NOT NULL auto_increment,
 `ProgramName` varchar(64) NOT NULL default &apos;&apos;,
 `ProgramDescription` text NOT NULL,
 `HTMLOutline` text NOT NULL,
 `PDFOutline` longblob NOT NULL,
 `PDFOutline_mimetype` varchar(32),
 `AdmissionDeadline` date NOT NULL default &apos;0000-00-00&apos;,
 `LastModified` timestamp NOT NULL default CURRENT_TIMESTAMP,
 PRIMARY KEY (`ProgramID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT=&apos;Academic Program&apos; AUTO_INCREMENT=1 ;
&lt;/code&gt;
# The database has been created with 2 tables: Program and Course. We can now move on to building the Xataface application.

===Step 2: Create Xataface Application===

Our Xataface application will provide a user-friendly front-end to our database. A basic application consists of a directory with a configuration file and an entry page (PHP file). Xataface comes with a PHP setup script (called makesite) to create the skeleton for your application. Alternatively you can set up the application manually.

Note: For the following instructions and examples, my Daface installation is located at /Users/shannah/Sites/dataface and the URL for the installation is http://localhost/~shannah/dataface.

====Method 1: Setting up application with the &apos;makesite&apos; script====

# From the command prompt, navigate to the dataface directory. (in my case &apos;&apos;/Users/shannah/Sites/dataface&apos;&apos;).
# This directory contains a file named &apos;makesite&apos;. It is a PHP script that can be used to build a website powered by Xataface. To find out the usage options for this script you can simply call the script with no parameters. E.g.,&lt;code&gt; 
stevepbook:~/Sites/dataface shannah$ ./makesite
&lt;/code&gt;
# This will give you usage instructions for the script as follows:&lt;code&gt;
makesite: invalid options entered.

 Usage: makesite &lt;site_path&gt; &lt;db_user&gt;:&lt;db_pass&gt;@&lt;db_host&gt;/&lt;db_name&gt; &lt;dataface_url&gt;
 or
 php makesite &lt;site_path&gt; &lt;db_user&gt;:&lt;db_pass&gt;@&lt;db_host&gt;/&lt;db_name&gt; &lt;dataface_url&gt;
 where 
 &lt;site_path&gt; = The path (absolute or relative) to your application directory.
 &lt;db_user&gt; = The MySQL username to connect to the database
 &lt;db_pass&gt; = The User&apos;s password to connect to the database
 &lt;db_host&gt; = The MySQL host name.
 &lt;db_name&gt; = The name of the mysql database for the application.
 &lt;dataface_url&gt; = The URL to the Xataface installation

 Examples:

 makesite ../FacultyOfWidgetry root:password@localhost/FacultyOfWidgetry /dataface

 The above command would create a site at ../FacultyOfWidgetry (i.e., the Faculty of 
 Widgetry directory in the parent directory. The database used for this site is 
 located at localhost, and the database name is FacultyOfWidgetry. The username
 to connect to the database is root and his password is password.
&lt;/code&gt;
# We create our FacultyOfWidgetry site using the following command:&lt;code&gt;
./makesite ../FacultyOfWidgetry \
    root@localhost/FacultyOfWidgetry \
    http://localhost/~shannah/dataface
&lt;/code&gt;
# This will create our application in the FacultyOfWidgetry folder if everything worked ok. The contents of the folder will look like: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/directory-structure-1.gif]]

You may be wondering what these files. Here is the short version (Read the next section &quot;Creating applications manually&quot; for more detailed information about the contents of these files.

The index.php file is the entry point for your application (i.e., you point the web browser at this file to use the application. 
The conf.ini file contains database connection settings and some other minor settings, like what should appear in the navigation menu.
The tables/Program (tables/Course) directory can contain configuration files specific to the Program (Course) table. More on that later. 

# Point your web browser to the FacultyOfWidgetry directory to see the application: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-application-1.gif]]
#Your application is now created. It will enable you to add, edit, delete, and find records in either the Course table or the Program table. There will be more on the basics of using this application in the next section.	

====Method 2: Setting up application manually====

Using the makesite script as described above is the recommended way to set up an application because it saves time. However, it is very easy to set up the application manually. Just follow these steps:

# Create a directory for the application somewhere in your web site (preferably outside your xataface directory). We will call our directory &apos;FacultyOfWidgetry&apos;. ):&lt;code&gt;
mkdir FacultyOfWidgetry
&lt;/code&gt;
# Create a PHP file to serve as the access point for the application. Generally we will name this file &apos;index.php&apos;, but you can name it anything. Place the following contents in the index.php file:&lt;code&gt;
&lt;?
require_once &apos;/path/to/dataface/dataface-public-api.php&apos;;
df_init(__FILE__, &apos;http://yourdomain.com/dataface&apos;);
$app =&amp; Dataface_Application::getInstance();
$app-&gt;display();
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;OK, I guess some explanations are in order.&lt;/p&gt;&lt;p&gt;
The first line imports the all of the public functions for dataface from the dataface-public-api.php file.&lt;/p&gt;&lt;p&gt;
The second line initializes the application for the current directory and specifies the URL to the dataface installation.&lt;/p&gt;&lt;p&gt;
The third line obtains an instance to the Application object - the core of your Dataface application.&lt;/p&gt;&lt;p&gt;
The fourth line simply displays the application.&lt;/p&gt;&lt;/nowiki&gt;
# Create a file named &apos;conf.ini&apos; to contain database connection information. Its contents should be:&lt;code&gt;
[_database]
	host = &quot;localhost&quot;
	user = &quot;dbuser&quot;
	password = &quot;secret&quot;
	name = &quot;FacultyOfWidgetry&quot;

[_tables]
	Course = &quot;Course&quot;
	Program = &quot;Program&quot;
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;&lt;b&gt;Explanations:&lt;/b&gt;&lt;/p&gt;&lt;p&gt;There are 2 sections in this INI file: &apos;_database&apos;, and &apos;_tables&apos;.&lt;/p&gt;&lt;p&gt;
The &apos;_database&apos; section specifies the database connection information for the MySQL database.&lt;/p&gt;&lt;p&gt;
The &apos;_tables&apos; section specifies which tables will be included in the navigation menu for the application.&lt;/p&gt;&lt;/nowiki&gt;
# At this point, the application is functional. However there is one more thing that should be done for security reasons. The conf.ini file contains sensitive password information and should not be served to the web. We will create an .htaccess file to tell Apache NOT to serve this (or any) .ini file. The .htaccess file should contain:&lt;code&gt;
&lt;FilesMatch &quot;\.ini$&quot;&gt;
	Deny from all
&lt;/FilesMatch&gt;&lt;/code&gt;
# The directory structure of your application will now look like: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-app-dir-structure-manual-1.gif]]&lt;nowiki&gt;&lt;p&gt;
Note, however, that there is also an .htaccess file that is hidden from this image.&lt;/p&gt;&lt;p&gt;You may be wondering why there is no &apos;tables&apos; directory like the directory structure that was generated by the makesite script. The &apos;tables&apos; directory is not required for the application to be functional. It will be required later on when we start to decorate the database.&lt;/p&gt;&lt;/nowiki&gt;
# The application is now ready to go. Point your web browser to the index.php file that you created. It will look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-application-1.gif]]

===Download source files===

[[File:http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-4-tar.gz|Download the source files]] for this application at a tar.gz archive.
These files reflect the state of the application at this point of the tutorial. As later sections make changes to the application you will be able to download those versions also.</content>
	<keywords>htaccess first application installation</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=75">
	<page_name>GettingStarted:using_first_app</page_name>
	<page_id>75</page_id>
	<page_title>Using Your First Application</page_title>
	<content>==Using Your First Application==

A Web Lite application, at its core, provides 4 standard operations: Add new records, edit existing records, delete records, and find records. This section gives a brief overview of how to use your first Dataface application.
When you first create your Xataface application and there are no records in the database, the application will look quite plain. If you point your web browser to your newly created application it will look something like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-application-1.gif]]

You may be wondering why it says &quot;No records matched your request&quot; when you haven&apos;t even really made a request. This is because the &apos;default&apos; request that is performed if no other request is specified is to show the first record from the first table in the navigation menu. Since there are no records, it is true that there are NO records matching the default request.
So what can you do with this application anyways? Essentially there are 4 operations you will want to perform:

# Create new records
# Edit Existing records
# Find records
# Delete records

==Basic Navigation==

The navigation tabs (aka Navigation menu) at the top left represent the tables in your database. You can navigate to any of the tables in this list by clicking on that table:

[[Image:http://xataface.com/documentation/tutorial/getting_started/navmenu-1.gif]]

There are 3 &quot;views&quot; associated with tables in the database:

* &apos;&apos;&apos;Details&apos;&apos;&apos; - Shows the details of a single record in the table
* &apos;&apos;&apos;List&apos;&apos;&apos; - Shows the records in the current &quot;found set&quot; as a list. (in a table).
* &apos;&apos;&apos;Find&apos;&apos;&apos; - Allows users to find records matching certain criteria.

You can toggle between these 3 views using the tabs at the top of the page:

[[Image:http://xataface.com/documentation/tutorial/getting_started/basic-tabs-1.gif]]

===The &quot;Found Set&quot;===

Throughout this tutorial you will see the phrase &quot;found set&quot; an awful lot, so it is important to understand just what this means. A &quot;found set&quot; is the set of all records in the current table that match the current &quot;find criteria&quot;. This begs the question, &quot;what is &apos;find criteria&apos;?&quot;. By default there is no find criteria. When you perform a search or a find on the current table, you add &quot;find criteria&quot; so that only the records satisfying these criteria will be included in the &quot;found set&quot;.

For example, if you click on the &quot;find&quot; tab, you will get a search form that allows you to search for records that match certain criteria. The &quot;find&quot; tab for the &quot;Course&quot; table in our application looks like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/find-form-1.gif]]

If you type in &quot;English&quot; in the &quot;Subject&quot; field and click &quot;Find&quot;, then the &quot;found set&quot; will consist of only records that contain the word &quot;English&quot; in their subject fields.

On the top left of the application window there will always be a &quot;Found&quot; line that indicates how many records are currently in the found set. e.g., 

This indicates that there are 256 records in the current table (which is the &apos;Groups&apos; table). There are currently only 225 records in the current &quot;found set&quot; (meaning that we have performed a &quot;find&quot; operation and it matched 225 of the records). It also indicates that the currently displayed record is record number 1 out of the 225 found records.

===The Actions Menu===

Just below the view tabs (&apos;details&apos;, &apos;list&apos;, and &apos;find&apos;) there are a few buttons that allow you to perform actions such as create new records, clear find parameters (i.e. Show All), and delete records.

[[Image:http://xataface.com/documentation/tutorial/getting_started/actions-menu-1.gif]]

&apos;&apos;&apos;Descriptions:&apos;&apos;&apos;

* &apos;&apos;&apos;new record&apos;&apos;&apos; - Creates a new record in the current table.
* &apos;&apos;&apos;show all&apos;&apos;&apos; - Clears all find criteria on current table so that all records are shown.
* &apos;&apos;&apos;delete&apos;&apos;&apos; - Deletes the current record in the table.
* &apos;&apos;&apos;delete found records&apos;&apos;&apos; - Deletes all records in the current &quot;found set&quot;. If no find criteria is specified this will delete all records in the table. 

===Creating new records===

The basic FacultyOfWidgetry application that we created in the previous section isn&apos;t very interesting when it doesn&apos;t contain any records, so let&apos;s create some Program records.

# Select the &quot;Program&quot; table by clicking on the &quot;Program&quot; option of the navigation menu.
# Click &quot;new record&quot; in the actions menu (top left).
# This will bring up a form to insert a new record that looks like: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/new-record-1.gif]]
# Fill in the form and click &quot;Save&quot;. If everything went OK, you will see the same form again, but with a &quot;success&quot; message at the top of the page: &lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/successfully-saved-1.gif]]

===Editing an existing record===

The &quot;details&quot; view allows you to view details or edit the current record. There should be at least 2 sub-tabs: &apos;View&apos; and &apos;Edit&apos;. If you click on the &apos;Edit&apos; tab, you will be presented with a form to edit the record. The form is identical to the &quot;create new record&quot; form.

===Deleting records===

If the &apos;list&apos; tab is selected, then you will see a button called &apos;delete found records&apos; in the actions menu (just below the view tabs). Alternatively if the &apos;details&apos; tab is selected, you will see a button called simply &apos;delete&apos;. 

[[Image:http://xataface.com/documentation/tutorial/getting_started/actions-menu-1.gif]]

Select &quot;delete&quot; to delete only the current record you are viewing in the &quot;details&quot; view.

Select &quot;delete found records&quot; to delete all of the records in the current found set. 

In either case, you will be prompted to confirm your decision before the records are actually deleted.

===Interface Overview===

Xataface applications provide an intuitive and consistent interface throughout. The following screenshot contains a map of some comment interface components along with some explanations:

[[Image:http://xataface.com/documentation/tutorial/getting_started/interface-schematic.png]]


Other topics
This short section is only intended to get you acquainted with the basics of Xataface applications. As your application becomes more complex with relationships and value-lists, there will be other usage scenarios of interest.</content>
	<keywords>&quot;find form&quot;,&quot;edit form&quot;,&quot;delete record&quot;,&quot;user interface&quot;,ui,template,look and feel</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=76">
	<page_name>GettingStarted:customizing</page_name>
	<page_id>76</page_id>
	<page_title>Customizing Field labels, descriptions, and widgets</page_title>
	<content>==Customizing Field labels, descriptions, and widgets==

Using simple INI configuration files, you can customize the look and feel of your application. You can change widgets, labels, field descriptions, and more.
In the previous 2 sections we learned how to create a simple application by desiging a database and then installing the basic directory structure to make our application operational. Now it is time to &quot;decorate&quot; the application a little bit. Decoration occurs by way of simple configuration files that are placed in strategic locations in the application. We can customize such things as:

* Widget types (e.g., use a select list for a field rather than a text field)
* Labels (e.g., The ProgramName field&apos;s label can say &quot;Program Name&quot; instead of just &quot;ProgramName&quot;)
* Field Descriptions . You can add descriptions to fields to help explain their meaning and how to use the application.
* HTML attributes. (e.g., Make a text field 50 characters wide)

===Table Configuration Directories===

You will recall, that when we used the &apos;makesite&apos; script to generate the directory structure for our web application, it created a directory named &apos;tables&apos;, with subdirectories named after each of the tables in our database. The directory structure of the application looked like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/directory-structure-1.gif]]

The &apos;tables/Program&apos; and &apos;tables/Course&apos; are refered to as &quot;table configuration directories&quot; . All of the configuration files a table in a Xataface application are stored in its associated table configuration directory. For example all configuration files for the &apos;Program&apos; table are located in the &apos;tables/Program&apos; directory.

There are 4 main files that are generally contained in a table&apos;s configuration directory:

* &apos;&apos;&apos;fields.ini&apos;&apos;&apos; - Contains configuration for the fields of the table (e.g., field labels, descriptions, widget types, etc...)
* &apos;&apos;valuelists.ini&apos;&apos;&apos; - Contains value lists (vocabularies) that can be used in the table to limit input into certain fields like select lists.
* &apos;&apos;&apos;relationships.ini&apos;&apos;&apos; - Defines the relationships between this table and other tables in the application.
* &apos;&apos;&apos;&lt;TableName&gt;.php&apos;&apos;&apos; (where &lt;TableName&gt; is the name of the table. - A delegate PHP class that allows you to further customize the behavior of the application with respect to this table. May contain custom fields, importing/exporting functionality, permissions information, and more...

===Customizing Labels and Descriptions===

We will start off by adding custom labels and descriptions to the &apos;Program&apos; table of our &apos;FacultyOfWidgetry&apos; application. This sort of customization settings are placed in a file named &apos;fields.ini&apos; inside the table&apos;s configuration directory.

# Create the &apos;fields.ini&apos; file in the Program table configuration directory (i.e., tables/Programs/fields.ini).
# Add the following to this file:&lt;code&gt;
[ProgramName]
	widget:label = &quot;Program Name&quot;
	widget:description = &quot;Enter the name of the program&quot;
&lt;/code&gt;&lt;nowiki&gt;&lt;br&gt;&lt;/nowiki&gt;Now look at the &quot;Edit Record&quot; form in the Xataface application:

[[Image:http://xataface.com/documentation/tutorial/getting_started/program-name-label-1.gif]]


Notice how the label for the &quot;ProgramName&quot; now says &quot;Program Name&quot; (note the space between &quot;Program&quot; and &quot;Name&quot;). And its description matches the description specified in the fields.ini file.

The widget:label and widget:description attributes can be defined for any field in any table of the application.

===Using different widgets===

If no widgets are defined in the fields.ini file, a Xataface application will make a best guess at the type of widget that should be used to edit the value in a field. In general, the widgets used by default are as follows:

* VARCHAR, CHAR, INT : html text field
* DATE, DATETIME fields: calendar widget
* TEXT fields : html text area
* BLOB fields : html file upload field
* INT Fields with &quot;AUTO INCREMENT&quot; : html hidden field
* VARCHAR or CHAR fields with &quot;Password&quot; or &quot;password&quot; as part of the name : html password field
* ENUM fields : html select list
* SET fields : html checkbox group (not yet supported as of this writing).

You can change the widget that is used to edit a field by specifying a &quot;widget:type&quot; attribute for the field in the fields.ini file. For more information about the available widgets, see [[widget:type]].

====Example: Using HTML Editor to edit the HTMLOutline field====

Clearly the HTMLOutline field in the Program table is intended to store HTML content. By default our application only provides a text area to do the editing so the user is expected to enter the HTML markup by hand. It would be much better to provide the user with a WYSIWYG (What you see is what you get) HTML editor widget. That is exactly what we are going to do.
We will add a section to the fields.ini file so that it now looks like: &lt;code&gt;
[ProgramName]
	widget:label = &quot;Program Name&quot;
	widget:description = &quot;Enter the name of the program&quot;

[HTMLOutline]
	widget:type = &quot;htmlarea&quot;
&lt;/code&gt;

Now refresh the Xataface application in your web browser and look at the edit form for a record of the Program table:

[[Image:http://xataface.com/documentation/tutorial/getting_started/htmlarea-1.gif]]

As you can see, the HTMLOutline field now has an HTML Editor widget for editing. Most users will find this much nicer to work with than a normal text area. Xataface uses FCKEditor for its html editor widget.

There are a number of widgets that can be specified in the [[widget:type]] parameter:

* &apos;&apos;&apos;[[checkbox]]&apos;&apos;&apos; - An HTML checkbox (or checkbox group depending on context).
* &apos;&apos;&apos;[[date]]&apos;&apos;&apos; - Month/Day/Year select lists for selecting dates.
* &apos;&apos;&apos;[[calendar]]&apos;&apos;&apos; - A text field with a button that opens a small calendar widget when clicked.
* &apos;&apos;&apos;[[group]]&apos;&apos;&apos; - A complex widget type for editing multiple values as a group (useful for XML fields)
* &apos;&apos;&apos;[[hidden]]&apos;&apos;&apos; - a hidden field
* &apos;&apos;&apos;[[password]]&apos;&apos;&apos; - An HTML password widget
* &apos;&apos;&apos;[[select]]&apos;&apos;&apos; - An HTML select list (requires the &apos;vocabulary&apos; attribute)
* &apos;&apos;&apos;[[static]]&apos;&apos;&apos; - an uneditable field
* &apos;&apos;&apos;[[table]]&apos;&apos;&apos; - A complex widget type for editing multiple values in a tabular format (Useful for XML fields)
* &apos;&apos;&apos;[[text]]&apos;&apos;&apos; - an html text field
* &apos;&apos;&apos;[[textarea]]&apos;&apos;&apos; - an html text area

===Changing HTML attributes of widgets===

Sometimes you may want even finer grained control of your widgets&apos; appearance than to just specify the type, label, and desription. Perhaps you want to make a text field 50 characters wide, or to set the CSS class of the html element. This can be done using the &apos;widget:atts:&apos; parameter for a field. A short example is the easiest way to explain how this works.

Modify the fields.ini for the Program table so it looks like:&lt;code&gt;
[ProgramName]
widget:label = &quot;Program Name&quot;
widget:description = &quot;Enter the name of the program&quot;
widget:atts:size = 50
widget:atts:style = &quot;font-size: 24pt; font-family: Apple Chancery&quot;

[HTMLOutline]
widget:type = htmlarea
&lt;/code&gt;

We have added 2 lines:&lt;code&gt;
widget:atts:size = 50
widget:atts:style = &quot;font-size: 24pt; font-family: Apple Chancery&quot;
&lt;/code&gt;

What this does is add the html attributes size=&quot;50&quot; and style=&quot;font-size: 24pt; font-family: Apple Chancery&quot; to the html text field that is used to edit the ProgramName field.
Look at the results:

[[Image:http://xataface.com/documentation/tutorial/getting_started/widget-atts-1.gif]]

The HTML tag for the text field now looks like:&lt;code&gt;
&lt;input class=&quot;default&quot; id=&quot;ProgramName&quot; name=&quot;ProgramName&quot; 
	type=&quot;text&quot; size=&quot;50&quot; 
	style=&quot;font-size: 24pt; 
		font-family: Apple Chancery&quot; 
	value=&quot;Basic Widgetry&quot; 
/&gt;	
&lt;/code&gt;
In fact you can add arbitrary attributes to any of the fields using the same convention. Some useful examples are:

* &apos;&apos;&apos;[[widget:atts:rows]]&apos;&apos;&apos; for text areas to set the number of rows of text they should display.
* &apos;&apos;&apos;[[widget:atts:cols]]&apos;&apos;&apos; for text areas to set the number of columns (1 character = 1 column)
You can even use javascript calls in here if you like:
* &apos;&apos;&apos;[[widget:atts:onclick]]&apos;&apos;&apos; = &quot;doJsFunction();&quot;

===Download source files===

[http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-6-tar.gz Download the source files] for this application as a tar.gz archive
These source files reflect the state of the application at the current point of the tutorial. As changes are made to the application in later sections, downloads of those versions are made available for download also.

===Summary===
In this section we learned how to change the labels, descriptions, and widgets for fields. We also learned how to add HTML attributes to the widgets to achieve very fine-grained control over the display of our forms.</content>
	<keywords>widget labels descriptions onclick handlers</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=77">
	<page_name>GettingStarted:valuelists</page_name>
	<page_id>77</page_id>
	<page_title>Using Valuelists</page_title>
	<content>==Using Value-lists==

Value-lists serve as vocabularies that can be used for fields such as select lists, checkbox groups, and auto-complete fields.

So far we have not used any enumerated fields such as select lists, checkbox groups, or auto-completion fields in our examples. This is because we are missing a key ingredient that is required by all of these widget types: a vocabulary. We need a way to define options for these fields.

This is where &apos;valuelists&apos; come into play. A valuelists is essentially a list of key-value pairs that can be used as a vocabulary in enumerated fields like checkbox groups, select lists, and auto-completion fields. Valuelists are defined in the valuelists.ini file in each table&apos;s configuration directory.

===Example 1: Use a select list for the Subject field in the Course table===

The &quot;Subject&quot; field in the &quot;Course&quot; table really shouldn&apos;t be a free-form field that will accept any value. The user should just be able to pick from a finite list of subjects in a select list. To make these changes we will follow these steps:

# Create the configuration directory for the &quot;Course&quot; table if it does not exist yet.
# Create a file named &apos;fields.ini&apos; inside the Course table&apos;s configuration directory (i.e., tables/Course/fields.ini), if it does not already exist.
# Create a file named &apos;valuelists.ini&apos; inside the Course table&apos;s configuration directory (i.e., tables/Course/valuelists.ini) if it does not already exist.
Your application directory structure should now look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/application-structure-valuelists.gif]]
# Edit the valuelists.ini file so that it looks like:&lt;code&gt;
[Subjects]
	ENGL = English
	MATH = Math
	PHYS = Physics
	CHEM = Chemistry
&lt;/code&gt; This defines a valuelist named &apos;Subjects&apos; with values {ENGL, MATH, PHYS, CHEM} and associated labels {English, Math, Physics, Chemistry}. The values (i.e., ENGL, MATH, etc..) represent what will be stored in the database, and the values is a user-friendly representation that will be displayed on the screen.
# Now we edit the fields.ini file so that it looks like:&lt;code&gt;
[Subject]
	widget:type = select
	vocabulary = Subjects
&lt;/code&gt; This tells Xataface that we want to use a select widget to edit the &quot;Subject&quot; field, and its values should be drawn from the &quot;Subjects&quot; valuelist.
#Navigate to the &quot;Course&quot; table in our application and select &quot;new record&quot; from the &quot;Actions to be performed menu&quot; in the top left.&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/actions-menu-1.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;br/&gt;&lt;/nowiki&gt;This will bring up a form to create a new Course record, so that we can see what the form looks like. It should look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/new-course-form-1.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;Notice that the &quot;Subject&quot; field is represented by a select widget, its options are as follows:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/course-subject-pulldown-1.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt; And if you look at the HTML source code for this select list, it would look like:&lt;code&gt;
&lt;select class=&quot;default&quot; id=&quot;Subject&quot; name=&quot;Subject&quot;&gt;
	&lt;option value=&quot;&quot;&gt;Please Select...&lt;/option&gt;
	&lt;option value=&quot;ENGL&quot;&gt;English&lt;/option&gt;
	&lt;option value=&quot;MATH&quot;&gt;Math&lt;/option&gt;
	&lt;option value=&quot;PHYS&quot;&gt;Physics&lt;/option&gt;
	&lt;option value=&quot;CHEM&quot;&gt;Chemistry&lt;/option&gt;
&lt;/select&gt;
&lt;/code&gt;

===Example 2: Using a checkbox group for the &apos;Subject&apos; field===

In Example 1, we showed how to use a select list for the &apos;Subject&apos; field in the &apos;Course&apos; table. This is great if each course can only be one subject. But what if a course can be categorized in 2 subject areas. Then we will need a widget the allows you to select multiple items. Checkbox groups work well for this.
Make a change to the &apos;fields.ini&apos; file for the &apos;Course&apos; table to change the widget:type attribute of the &apos;Subject&apos; field to &apos;checkbox&apos; as follows:&lt;code&gt;
[Subject]
widget:type = checkbox
vocabulary = Subjects
&lt;/code&gt;

Now load the form again and notice that the &apos;Subject&apos; field is now represented by checkboxes.

[[Image:http://xataface.com/documentation/tutorial/getting_started/checkbox-group-1.gif]]

You may be wondering how we store multiple values in a single field. In this case Subject is treated as a &apos;repeat&apos; field where each value is on a separate line. I.e., with the form above, if we clicked &apos;save&apos; and checked the values stored in the database we would see:&lt;code&gt;
PHYS
CHEM
&lt;/code&gt;

As the value in the &apos;Subject&apos; field. Please note that if you are going to use a repeating field like this, you should make sure that the field is &apos;big&apos; enough to store all of the values. E.g., I think my Subject field was a VARCHAR(64) (64 characters long), so the sum of the lengths of all of the values &apos;checked&apos; for &apos;Subject&apos; should be less than 64.

===Example 3: Dynamic Valuelists based on the results of SQL queries===

Example 1 &amp; 2 demonstrated the basic idea of valuelists and how they can be used as values for select lists and checkbox groups. However defining valuelists &quot;statically&quot; inside the valuelists.ini file doesn&apos;t really seem to offer anything over using and ENUM or SET field in the MySQL database. In many cases we want the user to be able to choose from a number of options that are pulled from the database. For example, we may want the user to be able to specify the Program that a Course belongs to, using a pull-down list.

Recall that when we created the &apos;Course&apos; table we included a field named &apos;ProgramID&apos; to store the ID number of the Program that this course belongs to. It would be unreasonable to expect the users of your application to remember the ID number of the Program to which the course belongs when they are filling in the &apos;Course&apos; form. It would be much better if the user could choose the program from a list of available programs. Fortunately, this functionality is simple to add:

# Add a valuelist named &apos;Programs&apos; to the valuelists.ini file for the &apos;Course&apos; table as follows:&lt;code&gt;
[Programs]
	__sql__ = &quot;SELECT ProgramID, ProgramName FROM Program ORDER BY ProgramName&quot;
&lt;/code&gt; &apos;&apos;&apos;Note: Make sure you use two underscores on either side of &apos;sql&apos; in the above example. It should be &apos;__sql__&apos; not &apos;_sql_&apos;.&apos;&apos;&apos;&lt;nowiki&gt;&lt;p&gt;&lt;/nowiki&gt;This valuelist will be a list of the records in the &apos;Program&apos; table in alphabetical order on the program name. Note that this query selects 2 columns. The first column is always taken to be the ID column of the value-list and the 2nd column (if specified) is the Name column of the valuelist. The ID column is what will actually be stored in the database, and the Name column is what will be shown to the user in place of the ID.&lt;nowiki&gt;&lt;/p&gt;&lt;/nowiki&gt;
# Add a field definition for the ProgramID field in the fields.ini file of the &apos;Course&apos; table as follows:&lt;code&gt;
[ProgramID]
	widget:type = select
	vocabulary = Programs
&lt;/code&gt;

Now we can load up our form and see what it looks like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/programid-select-list.gif]]

We can see that the ProgramID field now appears with a select list of all of the programs in the database. The HTML code for the select list is:&lt;code&gt;
&lt;select class=&quot;default&quot; id=&quot;ProgramID&quot; name=&quot;ProgramID&quot;&gt;
	&lt;option value=&quot;&quot;&gt;Please Select...&lt;/option&gt;
	&lt;option value=&quot;2&quot;&gt;Advanced Widgetry&lt;/option&gt;
	&lt;option value=&quot;1&quot;&gt;Basic Widgetry&lt;/option&gt;
	&lt;option value=&quot;3&quot;&gt;International Widgetry&lt;/option&gt;
&lt;/select&gt;&lt;/code&gt;

===Download Source Files===

[http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-7-tar.gz Download application source files as tar.gz archive]

These source files reflect the application&apos;s state at this point in the tutorial. As changes are made to the application in later sections, modified source archives will be available to be downloaded.

===Summary===

In this section, we have learned how to use valuelists to add selection lists and checkbox groups to our web forms. We also shows how valuelists can be dynamically defined using SQL. Using valuelists in this way is like defining a many-to-one relationship to our database (in example 3, it was many &apos;Course&apos; records to one &apos;Program&apos; record). In the next section we will learn how to add many-to-many and one-to-many relationships to our database in such a way that records can be easily added and removed from relationships using Xataface.</content>
	<keywords>valuelists, __sql__, select lists, checkbox options,checkbox groups,vocabularies</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=78">
	<page_name>GettingStarted:relationships</page_name>
	<page_id>78</page_id>
	<page_title>Relationships</page_title>
	<content>==Relationships==

Xataface allows you to define relationships between tables using the relationships.ini file.

Xataface applications without relationships between tables can be quite boring. In our FacultyOfWidgetry application, we have implicitly defined a relationship between the Program table and the Course table by adding a ProgramID field to the Course table. In the previous section we saw how to configure this relationship from the context of a &apos;Course&apos; by adding a select list to the Course table form to select the Program that the Course belongs to.

From the &apos;Program&apos; side it is a little bit more complicated. There are no fields in the &apos;Program&apos; table that can be edited to add a &apos;Course&apos; to the list of courses in a &apos;Program&apos;, and it would be highly inconvenient to have to edit a &apos;Course&apos; record in order to add the course to a &apos;Program&apos;. What we want is a sort of &apos;Add Course&apos; button to add a course to a &apos;Program&apos;. 

===Concepts, Definitions, and Terminology===

Before we can delve into examples, it will help to go over some of the concepts and terminology involved in relationships using Xataface. Xataface relationships are always defined in a one-way fashion from the point of view of one table. For example, if you define a one-to-many relationship from the &apos;Program&apos; table to the &apos;Course&apos; table, the mirror (many-to-one) relationship from &apos;Course&apos; to &apos;Program&apos; is not automatically created. This method of defining relationships allows us to unambiguously refer to the source and destination tables of a relationship.

&apos;&apos;&apos;Definition 1:&apos;&apos;&apos; The &apos;&apos;source table&apos;&apos; of a relationship is the table on which a relationship is defined. For example if we define a relationship named &apos;Courses&apos; on the &apos;Program&apos; table to associate courses in a given program, then the &apos;Program&apos; table would be considered the source table of the relationship, and the &apos;Course&apos; table would be a destination table of the relationship.

&apos;&apos;&apos;Definition 2:&apos;&apos;&apos; The &apos;&apos;destination table&apos;&apos; of a relationship a table from which related records are selected.

There may be multiple destination tables in a given relationship but only one source table. If there are multiple destination tables, then one of these tables is designated as the domain table and the remaining destination tables are called join tables. 

&apos;&apos;&apos;Definition 3:&apos;&apos;&apos; A &apos;&apos;domain table&apos;&apos; is a destination table which stores the object of the relationship. For example if we define a many-to-many relationship between the &apos;Program&apos; table and the &apos;Course&apos; table, (i.e., each program can contain multiple courses and each course can be part of multiple programs), then we would need to add a join table to map &apos;Course&apos; records to &apos;Program&apos; records. Let&apos;s call this table &apos;ProgramCourses&apos;. Each record of the &apos;ProgramCourses&apos; table would contain a 2 fields: a &apos;ProgramID&apos; field (to reference the program) and a &apos;CourseID&apos; field to reference the course. If we define the relationship from the point of view of a &apos;Program&apos; then the &apos;Program&apos; table would be the source table, the &apos;ProgramCourses&apos; table would be the join table, and the &apos;Course&apos; table would be the domain table.

Don&apos;t worry if these definitions and terms aren&apos;t clear at this point. Use this section as a reference for when you run across the terms later in the tutorial.

===Defining a relationship===

To define a relationship in Xataface, all you need to do is tell Xataface how to select the related records using SQL. Xataface will be able to figure out how to add/remove records to the relationship from this information. This information is defined inside a the &apos;relationships.ini&apos; file inside the configuration folder for the table.

====Example 1: Adding a &apos;Courses&apos; relationship to the &apos;Program&apos; table====

We want to be able to associate multiple courses with each program. We do this by defining a relationship on the &apos;Program&apos; table as follows:

# Add a file named &apos;relationships.ini&apos; to the &apos;Program&apos; table&apos;s configuration folder (i.e., tables/Program/relationships.ini). Your application&apos;s directory structure should now look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/directory-structure-relationships.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;Notice, in particular the addition of the &apos;relationships.ini&apos; file in the &apos;Program&apos; directory.
# Add the following to the &apos;relationships.ini&apos; file:&lt;code&gt;
[Courses]
	Course.ProgramID = &quot;$ProgramID&quot;
&lt;/code&gt;	

This little snippet defines a relationship named &apos;Courses&apos; on the &apos;Program&apos; table. &apos;Program&apos; is the source table. &apos;Course&apos; is the destination table. There are no join tables because this is only a one-to-many relationship. You may be wondering what the $ProgramID means. This is a variable that represents the value of the &apos;ProgramID&apos; field in the source record. This relationship specifies that courses whose &apos;ProgramID&apos; field matches the value of the &apos;ProgramID&apos; field in the source record, are related to the source record. The english language makes this seem more difficult and complex than it really is.

Let&apos;s check out our changes. Since we have defined the relationship on the &apos;Program&apos; table, we will click on the &apos;Program&apos; link in the navigation menu:
[[Image:http://xataface.com/documentation/tutorial/getting_started/course-relationship-defined-1.gif]]

Notice that there is now a &apos;course&apos; tab at the top of the page. Click on this tab to see the courses that are related to this Program (as defined by our &apos;Courses&apos; relationship). If it says that &quot;No records matched the request&quot; or something to that effect, then you don&apos;t have any Course records in the relationship yet. Just click the &quot;Add New Courses Record&quot; button in the upper left to add a course. If there are courses in the relationship, then the Courses tab will look something like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/courses-related-records.gif]]

Currently there is only one course in the program, but we can add more. If you click on the &quot;Add New Courses&quot; button in the upper left, you will be presented with a new course form that will allow you to add a new course in this Program.

===Example 2: Making the &apos;Courses&apos; relationship a Many-to-Many relationship===

Example 1 shows how Xataface can handle a one-to-many relationship. Now we will alter the database a little bit and turn this into a many-to-many relationship.

# Add a table named &apos;ProgramCourses&apos; to the database. The SQL table definition for this table should be something like:&lt;code&gt;
CREATE  TABLE  `ProgramCourses` (
	`ProgramID` INT( 11  )  NOT  NULL ,
	`CourseID` INT( 11  )  NOT  NULL ,
	PRIMARY  KEY (  `ProgramID` ,  `CourseID`  ) 
	) 
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;Note that it is important for ALL of your tables to have Primary keys. If a table is missing its primary keys, some strange behavior may occur with relationships involving that table.&lt;/p&gt;
&lt;p&gt;
The above defined table will serve as a join table between &apos;Program&apos; and &apos;Course&apos;
&lt;/p&gt;&lt;/nowiki&gt;
# Since this is now going to be a many-to-many relationship, we no longer need the &apos;ProgramID&apos; field in the &apos;Course&apos; table. (Do not confuse this with the ProgramID field in the &apos;Program&apos; table. That field is important and needed.). Before removing this field, we will transfer the information across so that the existing relationships are maintained. The following SQL query will effectively all of the old one-to-many relationships into equivalent many-to-many relationships:&lt;code&gt;
INSERT  INTO ProgramCourses( ProgramID, CourseID ) 
	SELECT ProgramID, CourseID
	FROM Course
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;	
And now we can remove the &apos;ProgramID&apos; field from the &apos;Course&apos; table.
ALTER  TABLE  Course  DROP  ProgramID&lt;/p&gt;&lt;/nowiki&gt;
# Finally, we will need to modify the relationship definition in the relationships.ini file of the &apos;Program&apos; table:&lt;code&gt;
[Courses]
	Course.CourseID = ProgramCourses.CourseID
	ProgramCourses.ProgramID = &quot;$ProgramID&quot; 
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;
This means that all courses for which a (ProgramID, CourseID) pair matches the CourseID of the course and the ProgramID of the source Program record are included in the relationship.&lt;/p&gt;&lt;/nowiki&gt;
# Now we can check our application for changes. Go to the &apos;Program&apos; table in your application (using your web browser) and click on the &apos;courses&apos; tab once again:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/multi-relationship.gif]]&lt;nowiki&gt;
&lt;p&gt;
This looks almost the same as before. Notice, however that now there is an &quot;Add Existing Courses Record&quot; button at the top. This is because with a many-to-many relationship, you are able to add related records in 2 ways:&lt;/p&gt;&lt;/nowiki&gt;
## Adding a completely new record that did not exist before.
## Selecting a record that already exists and adding it to the relationship.

===Example 3: Defining Relationships using SQL===

The previous examples used a simple INI file syntax to define relationships. However, some people may be more comfortable defining their relationships using SQL. This is also possible. Let&apos;s look at the relationships.ini file from example 1:&lt;code&gt;
[Courses]
	Course.ProgramID = &quot;$ProgramID&quot;
&lt;/code&gt;

This also could have been defined as follows:&lt;code&gt;
[Courses]
	__sql__ = &quot;SELECT * FROM Course WHERE ProgramID=&apos;$ProgramID&apos;&quot;
&lt;/code&gt;

&apos;&apos;&apos;Note: Make sure you use two underscores on either side of &apos;sql&apos; in the above example. It should be &apos;__sql__&apos; not &apos;_sql_&apos;.&apos;&apos;&apos;

The two syntaxes are equivalent. In fact, the former will be converted into the later by Xataface behind the scenes.

Now let&apos;s look at example 2&apos;s relationships.ini file:&lt;code&gt;
[Courses]
	Course.CourseID = ProgramCourses.CourseID
	ProgramCourses.ProgramID = &quot;$ProgramID&quot; 
&lt;/code&gt;

This could have been written as:&lt;code&gt;
[Courses]
	__sql__ = &quot;SELECT * 
		FROM ProgramCourses, Course 
		WHERE Course.CourseID = ProgramCourses.CourseID 
		AND ProgramCourses.ProgramID = &apos;$ProgramID&apos;&quot;
&lt;/code&gt;

The two are equivalent. This example, however, shows how defining a relationship using SQL can be beneficial. The above SQL query will work but it can be done better using Joins as follows:&lt;code&gt;
[Courses]
	__sql__ = &quot;SELECT * 
		FROM ProgramCourses pc 
		INNER JOIN Course c ON pc.CourseID = c.CourseID 
		WHERE pc.ProgramID = &apos;$ProgramID&apos;&quot;
&lt;/code&gt;

All of these 3 methods will produce the same results, but the last one will probably give a little bit better performance.

===Relationship Restrictions===

Xataface has built-in logic to figure out how to add new and existing records to relationships that you define, as long as your relationships obey a few guidelines.

# All tables must have a Primary key
# The WHERE clause of your SQL definition for the relationship must contain only &apos;=&apos; comparisons, and &apos;AND&apos; conjunctions. i.e., it cannot receive an &apos;OR&apos; conjunction, nor can comparisons be done using &apos;&gt;&apos;, or &apos;&lt;&apos;. This is because given &apos;AND&apos; and &apos;=&apos; conjunctions it is easy for Xataface to be able to add records that will satisfy the relationship. If an &apos;OR&apos; conjunction is used, it makes it ambiguous (though this will probably be corrected in future Xataface releases.

===Download Source Files===

[http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-8-tar.gz Download the source files for this application as a tar.gz archive]</content>
	<keywords>relationships</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=79">
	<page_name>GettingStarted:validation</page_name>
	<page_id>79</page_id>
	<page_title>Form Validation</page_title>
	<content>==Form Validation==

Xataface allows you to add validation rules to fields using the fields.ini file
A common requirement for forms is to have some validation rules. Here are some example validation rules:

* The Username field is required.
* The Username must be between 6 and 16 characters long.
* The password must have at least one letter and one digit.
* The Email field must contain a valid email address.

There is no end to the types of things that you will need to validate. Xataface takes care of most of this for you with both client-side (javascript) and server-side validation. All you have to do is define some validation rules in the fields.ini file.

===Example 1: Make &apos;Username&apos; a required field===
&lt;code&gt;
[Username]
	validators:required = true
	validators:required:message = &quot;Username is required&quot;
&lt;/code&gt;

Placing the above inside the fields.ini file will cause the Username field to be a required field.

===Example 2: Username must be between 6 and 16 characters long===

For this rule we will use a regular expression.
&lt;code&gt;
[Username]
	validators:regex = &quot;/^.{6,16}$/&quot;
	validators:regex:message = &quot;Username must be between 6 and 16 characters long&quot;
&lt;/code&gt;

===Example 3: Email field must contain a valid email address===

&lt;code&gt;
[Email]
	validators:email = true
	validators:regex:message = &quot;Email must contain a valid email address&quot;
&lt;/code&gt;

===Available validation rules===

Xataface uses the PEAR library HTML_Quickform for validation, so any of the validators available in this package will be available in Xataface. Some of the available validation rules include:

* required
* maxlength
* rangelength
* regex
* email
* emailorblank
* lettersonly
* alphanumeric
* numeric
* nopunctuation
* nonzero

===Default validation rules===

There are certain validation rules that are automatically applied to fields of with certain characteristics. For example, any field designated NOT NULL in the SQL table definition will automatically be a &apos;required&apos; field. At the time of this writing, that is the only &apos;default&apos; validation rule applied, but more may be added in the future if their addition makes sense.

</content>
	<keywords>form validation,required field,validation rules</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=80">
	<page_name>GettingStarted:delegate_classes</page_name>
	<page_id>80</page_id>
	<page_title>Delegate Classes</page_title>
	<content>==Delegate Classes==

Use Delegate classes to add permissions, custom serialization, display filters, calculated fields, import/export functionality, and other custom functionality to your application.

For many applications, the configuration files provide sufficient to make them fit the requirements. However, in some cases you may feel the need to &quot;extend&quot; or &quot;bend&quot; your application even more. For these situations, there are delegate classes.

===What is a delegate class?===

A delegate class is a PHP class that defines custom behavior, functions, and fields for a table in a Xataface application. A table may have only 1 delegate class.

What kinds of things can a delegate class do?

* Define permission rules for tables, records, and relationships.
* Define calculated fields.
* Define custom serialization/deserialization of fields (useful for XML storage)
* Define custom event handlers (actions to be performed when certain events take place)
* Define import / export filters.
* Define custom titles for records
* more ...

===How to create a delegate class===

I will describe the creation process with an example. 

Referring back to our FacultyOfWidgetry application, let&apos;s add a delegate class for the &apos;Program&apos; table. This is done as follows:

# Create a file named &apos;Program.php&apos; in the Program table configuration directory (i.e., &apos;tables/Program/Program.php). Your application directory structure should now look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/delegate-class-fs-1.gif]]
# Add the following contents to your newly created &apos;Program.php&apos; file:&lt;code&gt;&lt;?
class tables_Program {}
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;
In other words, you are creating a class named &apos;tables_Program&apos;. The above delegate class doesn&apos;t do anything yet, but it is a start.
The fun part doesn&apos;t start until you start defining methods in your delegate class. There are prescribed interfaces that you will need to implement to make this work.&lt;/p&gt;&lt;/nowiki&gt;


===Example 1: Creating a custom title for records===
The &quot;Title&quot; of a record is a string that represents the record. It is used by Xataface in the navigation controller (forward and back buttons) and in the &quot;Jump&quot; menu as well as various places around the interface for referring to that record. As an example, take a look at this partial screen shot of the &apos;details&apos; tab in a Xataface application.

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/getTitle-1.gif]]

I have circled the parts of the interface that use a record&apos;s title in some way. (1), (2), and (4) show the title of the current record and (3) shows the title of the next record in the found set. You will notice that the title is just the value of the first field in the Program record. In fact, the way that Xataface generates titles is by selecting the first VARCHAR or CHAR field in the table to be the Title for records of that table. In the above example this seems like a good choice, but it may not always be what you want.

We can use our delegate class to customize the way that these titles are generated. By defining a method named getTitle(), we can customize the way that titles are generated. Let&apos;s add such a method to our delegate class as follows:
&lt;code&gt;
&lt;?
class tables_Program {

	function getTitle(&amp;$record){
		return $record-&gt;val(&apos;ProgramName&apos;).&apos; Program&apos;;
	}
}
&lt;/code&gt;

OK, you are probably wondering what this $record object is. The $record object is a Dataface_Record object that represents a record of the &apos;Program&apos; table (if you want to take a look at the source code for this class it can be found in the &apos;Dataface/Record.php&apos; file). This object allows you to access all of the information about the record so that you can generate a title for the record. 

The &apos;val&apos; method simply returns the value of a field in the record.
In the above example, we are telling Xataface that the title of all records of the &apos;Program&apos; table is the value of the ProgramName field with the string &apos;Program&apos; appended to it. For example, if the ProgramName of a record was &apos;Foo&apos;, then its title woud be &apos;Foo Program&apos;.

Lets take a look at our application now to see the changes that we have made.

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/getTitle-2.gif]]

Notice that the (1) now has &apos;Program&apos; appended to the end of the title, but (2) and (3) do not. This is because (2) and (3) are part of the result controller (for navigating through results in the table) and it needs to be able to load hundreds of record titles at a time, but the getTitle() method requires that the entire record be loaded into memory for it to work which would be unfeasible when we need the title of hundreds of records. The result controller titles can also be customized, however, using the titleColumn() method, which simply returns the name of the column that should be used as the title. It can also return MySQL clauses that are equivalent to a column name (e.g., CONCAT(&apos;FirstName&apos;, &apos; &apos;, &apos;LastName&apos;) would be valid).

Okay, let&apos;s add a titleColumn() method to our delegate class so that we can customize the way our records are represented in the result controller:

&lt;code&gt;
&lt;?
class tables_Program {

	function getTitle(&amp;$record){
		return $record-&gt;val(&apos;ProgramName&apos;).&apos; Program&apos;;
	}
	
	function titleColumn(){
		return &apos;AdmissionDeadline&apos;;
	}
}
&lt;/code&gt;


All that the titleColumn method does is return the name of a column to be used as the title for records of the &apos;Program&apos; table. In this case, we making the &apos;AdmissionDeadline&apos; field the title column which results in the result controller looking like this:

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/titleColumn-1.gif]]


This was a simple example, but it is possible to do more with the titleColumn() method than just specify the name of a column. Any valid MySQL calculation that can be placed in a SELECT list can be returned here. For example, we can make use of the MySQL &apos;CONCAT&apos; function to append the string &apos;Program&apos; to the &apos;ProgramName&apos; field and achieve the same results as our previous getTitle() method:

&lt;code&gt;
&lt;?
class tables_Program {

	function getTitle(&amp;$record){
		return $record-&gt;val(&apos;ProgramName&apos;).&apos; Program&apos;;
	}
	
	function titleColumn(){
		return &quot;CONCAT(ProgramName, &apos; Program&apos;)&quot;;
	}
}

&lt;/code&gt;

And now we can see the changes in our application:

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/titleColumn-2.gif]]

It may seem a little bit inconvenient to have to define 2 methods to effectively customize the title of a record. Future versions may attempt to address this issue so that one or the other can be implemented, but for now, both methods must be implemented to effectively customize the title. In addition, future versions will likely add the &apos;titleColumn&apos; functionality to an INI file since it is more or less static.

===Summary===

In this section we learned how to add a delegate class to our tables to customize the behavior of our applications. Delegate class become more important when you need very fine-grained customizations to your application, as you will see in later sections. One important feature of delegate classes is the ability to add security permissions to tables and records to limit who can view, edit, and delete certain records. This will be covered in the next section.

</content>
	<keywords>delegate classes,getTitle,getPermissions</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=81">
	<page_name>GettingStarted:triggers</page_name>
	<page_id>81</page_id>
	<page_title>Triggers</page_title>
	<content>==Triggers==

Triggers are methods that can be defined to carry out custom behaviors when certain events occur in the application (e.g., when records are saved, inserted, or deleted).

Triggers are generally regarded as one of the more advanced features of database applications. Despite the &quot;advanced&quot; status of triggers, however, they are very simple to use and can be leveraged by Xataface developers to add powerful functionality to their applications.

So what can you do with a trigger?

* Send a confirmation email every time a new record is inserted into a table.
* Delete records related to a record that is being deleted (to maintain the consistency of the database).
* Add custom logging functionality.
* Add extra permissions or validation rules (although these are probably better handled with the validation framework).

You can really do just about anything you want with a trigger. A trigger is essentially just a custom PHP method that is called by Xataface when certain events occur.

===What triggers are available?===

As of version 0.5.3 Xataface supports the following triggers:

* &apos;&apos;&apos;beforeSave&apos;&apos;&apos; : called just before a record is saved (either inserted or updated).
* &apos;&apos;&apos;afterSave&apos;&apos;&apos; : called just after a record is saved (either inserted or updated).
* &apos;&apos;&apos;beforeInsert&apos;&apos;&apos; : called just before a record is inserted.
* &apos;&apos;&apos;afterInsert&apos;&apos;&apos; : called just after a record is inserted.
* &apos;&apos;&apos;beforeUpdate&apos;&apos;&apos; : called just before a record is updated.
* &apos;&apos;&apos;afterUpdate&apos;&apos;&apos; : called just after a record is updated.
* &apos;&apos;&apos;beforeDelete&apos;&apos;&apos; : called just before a record is deleted.
* &apos;&apos;&apos;afterDelete&apos;&apos;&apos; : called just after a record is deleted.
* &apos;&apos;&apos;beforeAddRelatedRecord&apos;&apos;&apos; : called just before a related record (new or existing) is added to a relationship.
* &apos;&apos;&apos;afterAddRelatedRecord&apos;&apos;&apos; : called just after a related record (new or existing) is added to a relationship.
* &apos;&apos;&apos;beforeAddNewRelatedRecord&apos;&apos;&apos; : called just before a new related record is added.
* &apos;&apos;&apos;afterAddNewRelatedRecord&apos;&apos;&apos; : called just after a new related record is added.
* &apos;&apos;&apos;beforeAddExistingRelatedRecord&apos;&apos;&apos; : called just before an existing related record is added.
* &apos;&apos;&apos;afterAddExistingRelatedRecord&apos;&apos;&apos; : called just after an existing related record is added.

===How do you define a trigger?===

Triggers are always defined as methods of the delegate class for a table. As an example, suppose we wanted to add a trigger to send a the administrator a notification email every time a new record is inserted into the &apos;Course&apos; table. The steps would be as follows:

# Create a delegate class for the &apos;Course&apos; table (if one does not already exist) by creating a file named &apos;Course.php&apos; inside the &apos;tables/Course&apos; directory.
# Add the following to the Delegate class file to make it a valid delegate class:&lt;code&gt;&lt;?
class tables_Course {}
&lt;/code&gt;
# Okay, we want our trigger to be called every time a record is inserted. There are 2 possible triggers that can be defined, then:&lt;nowiki&gt;
&lt;ul&gt;
&lt;li&gt;beforeInsert&lt;/li&gt;
&lt;li&gt;afterInsert&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this case it is probably more appropriate to define the afterInsert trigger because we really only want to send the notification email after the insert has successfully taken place. Therefore, we will define the afterInsert() method in our delegate class as follows:&lt;/p&gt;
&lt;/nowiki&gt;&lt;code&gt;
&lt;?
class tables_Course {
	....
    /**
     * Trigger that is called after Course record is inserted.
     * @param $record Dataface_Record object that has just been inserted.
     */
    function afterInsert(&amp;$record){
        mail(&apos;admin_email@yourdomain.com&apos;,&apos;Subject Line&apos;, &apos;Message body&apos;); 
    }
}
&lt;/code&gt;
# That&apos;s all for now. The afterInsert() method defined above will automatically be called every time a record is inserted into the Course table. This method, as we have defined it, will send a notification email to the administrator email.

===Sending feedback to the user===

The above example sends the email without any feedback to the application&apos;s user of whether the email succeeded or not. When the user inserts a new Course he will only see that the record was succesfully saved, but no mention is made of the email. The following example does the same thing as the previous one, except that it sends a confirmation to the user when the email has been successfully sent:
&lt;code&gt;
function afterInsert(&amp;$record){
    $response =&amp; Dataface_Application::getResponse();
        // get reference to response array

    if ( mail(&apos;shannah@sfu.ca&apos;, &apos;Subject Line&apos;, &apos;Message Body&apos;) ){
        $response[&apos;--msg&apos;] .= &quot;\nEmail sent to shannah@sfu.ca successfully.&quot;;
    } else {
        $response[&apos;--msg&apos;] .= &quot;\nMail could not be sent at this time.&quot;;
    }
}
&lt;/code&gt;

Now, when the user inserts a new record he will see a confirmation as follows:

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/trigger-after-insert-confirm.gif]]

Notice that we used the Dataface_Application::getResponse() function to obtain a reference to the application&apos;s response array. The response array is just a global array that is shared by the entire application that allows you to pass information easily from one part of the application to another. The &apos;--msg&apos; index of array is where you can place text that you wish to have displayed to the user as a confirmation.

&apos;&apos;&apos;Note&apos;&apos;&apos;: It is important to use &apos;=&amp;&apos; to assign the result of Dataface::getResponse() and not just &apos;=&apos;. e.g.:
&lt;code&gt;
$response =&amp; Dataface_Application::getResponse(); // correct!
$response = Dataface_Application::getResponse(); // WRONG!!
&lt;/code&gt;

This is because we need a reference to the response array, not a copy. That way when we assign a value to the &apos;--msg&apos; index it is applied to the actual response array and not a copy of it.

===Handling Errors===

The above method of sending messages to the user is useful for notifications and confirmations. However, in some cases you want to inform the user that an error occurred and cancel further operations. For example you may want to disallow a record to be inserted if a confirmation email cannot be sent. In this case we define the beforeInsert() trigger and return a PEAR_Error object if the email fails as follows:
&lt;code&gt;
&lt;?
class tables_Course {
    function beforeInsert(&amp;$record){
        $response =&amp; Dataface_Application::getResponse();
        if ( mail(&apos;shannah@sfu.ca&apos;, &apos;Notification&apos;, &apos;Your record was created&apos;)){
            $response[&apos;--msg&apos;] .= &quot;\nEmail sent successfully to shannah@sfu.ca&quot;;
        } else {
            return PEAR::raiseError(
                &quot;Errors occurred while sending email.  Record could not be inserted&quot;,
                 DATAFACE_E_NOTICE
            );
        }
    }
     
}
&lt;/code&gt;

This trigger is called just before a course record is inserted into the database. If the mail succeeds, then the user sees a success message. If it fails, on the other hand, the insert is cancelled, and the user will see a message as follows:

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/trigger-error.gif]]


&apos;&apos;&apos;Note&apos;&apos;&apos;: Notice the use of the DATAFACE_E_NOTICE constant as a second parameter for PEAR::raiseError(). This is important as without it Xataface will display a less user-friendly error message complete with stack trace. If the error is such that you want a complete stack trace, you can use the DATAFACE_E_ERROR constant instead.</content>
	<keywords>triggers, beforeSave, afterSave, beforeInsert, afterInsert,sending email</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=82">
	<page_name>Creating_Printable_Reports</page_name>
	<page_id>82</page_id>
	<page_title>Creating a Custom Printable Report</page_title>
	<content>==Creating a Printable Report==

[[toc]]

It is often useful to provide your users with a printable report that is generated from your database.  Although Xataface doesn&apos;t include an explicit reporting module to allow the end users to create their own reports, you (the developer) can still quite easily produce a report by creating a custom action.  

This report will be subject to the user&apos;s sorting and searching preferences.  E.g. if the user searches for only books about &quot;frogs&quot;, then when he clicks on your printable report it will only display those records that match the query (i.e. only books about frogs).

===Requirements for our report===

# Report will be run against the &quot;products&quot; table (using the WebAuction application).
# Report should be accessible by clicking an icon in the top right of the list view (i.e. the resultlist actions).
# Report should display the product ID, product name, photo, and description.  One product per page.


===Adding the Icon to our Application===

We&apos;ll start out by finding an appropriate icon to use for our action.  There are loads of free icons that you can download (please observe and respect the license agreement of any icon library that you use).  Two good free icon libraries include:

# [http://www.famfamfam.com/lab/icons/silk/ FamFamFam Silk Icons]
# [http://tango.freedesktop.org/Tango_Icon_Library Tango Icon Library]

Once you have found the icon you want to use, just upload it somewhere inside your application&apos;s directory.  It might be a good idea to create a directory to store your images if you haven&apos;t already.  An appropriate name might by &apos;&apos;images&apos;&apos;.  For this example, we&apos;ll use the [[Image:http://dev.weblite.ca/phpimageserver/photos/icons/printer.png]] icon from the FamFamFam icon library.  So we upload this icon to
 %APPLICATION_PATH%/images/printer.png

Next we need to create an entry in our application&apos;s [[actions.ini file]] so that Xataface knows about our action, and where we want its icon to be displayed.  We&apos;ll start out with a basic definition that just specifies the icon for the action, and the &apos;&apos;category&apos;&apos; of the action.

&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
&lt;/code&gt;

The &apos;&apos;result_list_actions&apos;&apos; category setting means that the icon for our action will be included along with the result list actions, which are located in the top right corner in the list tab.  Now if we reload our application and look at the &quot;list&quot; tab, you&apos;ll see that the icon group in the top right now includes our icon:

[[Image:http://media.weblite.ca/files/photos/Picture%20-5.png?max_width=640]]

If you don&apos;t see this icon, but see the text &quot;printable_report&quot; instead, then you have entered an incorrect path to the icon in the &apos;&apos;icon&apos;&apos; directive.  If you don&apos;t see an icon at all or any text, then your &apos;&apos;category&apos;&apos; directive may be incorrect.  Check that it is exactly &quot;result_list_actions&quot;.

If you mouse over your icon you&apos;ll see the text that you specified as your &apos;&apos;description&apos;&apos; directive for the action:

[[Image:http://media.weblite.ca/files/photos/Picture%20-6.png?max_width=640]]

You&apos;ll notice, if you try to click on your icon, that nothing happens.  This is because we haven&apos;t yet specified a URL for your action.  We&apos;ll wait to specify our URL, until we&apos;ve built the back-end of our action (i.e. the actual report).

===Creating the Actual Report===

Most reports involve the following pieces:

# Fetch the found set of records from the database.
# Loop through the found set and output some information about each record.
# Optionally use a template to integrate the report into your application&apos;s look and feel.

All reports will be placed in the framework of a custom Xataface action.  In our case we add a file to our application &apos;&apos;actions&apos;&apos; directory named after our action:
 %APPLICATION_PATH%/actions/printable_report.php

with the following contents:

&lt;code&gt;
&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	echo &quot;Hello world!!!&quot;;
    }
}
&lt;/code&gt;

Please note the following about this snippet:

# The action was placed in a file &apos;&apos;actions/printable_report.php&apos;&apos; because the action is named &apos;&apos;printable_report&apos;&apos; (referring to our definition in the &apos;&apos;[[actions.ini file]]&apos;&apos;.  If the action was named &apos;&apos;foo&apos;&apos;, then we would place our action in file &apos;&apos;actions/foo.php&apos;&apos;.
# The &apos;&apos;printable_report.php&apos;&apos; file contains a single class named &apos;&apos;actions_printable_report&apos;&apos; after the name of the action.
# The action class contains a single method &apos;&apos;handle&apos;&apos; which handles the request for the action (i.e. outputs the report the way we like).  This method must exist and me named exactly &apos;&apos;handle&apos;&apos;.
# The &apos;&apos;handle&apos;&apos; method takes a single &apos;&apos;&amp;$params&apos;&apos; parameter which contains some parameters that may be passed to the action.  We won&apos;t be dealing with these in this example.


Before proceeding, let&apos;s try accessing our action just to make sure that we&apos;re on the right track.  Point your browser to 
 http://example.com/yourapplication/index.php?-action=printable_report

Note that you don&apos;t point our web browser directly to your action php file (in the &apos;&apos;actions&apos;&apos; directory.  Rather you point it to your application&apos;s entry point (index.php file), and specify the action via the &apos;&apos;-action&apos;&apos; GET parameter.  Your web browser should display something like:

[[Image:http://media.weblite.ca/files/photos/Picture%204.png?max_width=640]]

If you get a blank white screen, then you should check your error log to see where the error is occuring.  See [[Troubleshooting]] for general Xataface troubleshooting strategies in this case.

Now that we have all of the formalities out of the way, we can proceed to meat of our report.

====Retrieving the Found Set====

Let&apos;s build onto our action now.  First we will load the found set of records as follows:

&lt;code&gt;
&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	$app =&amp; Dataface_Application::getInstance();
    	$query =&amp; $app-&gt;getQuery();
    	
    	if ( $query[&apos;-table&apos;] != &apos;products&apos; ){
    		return PEAR::raiseError(&apos;This action can only be called on the Products table.&apos;);
    	}
    	
    	$products = df_get_records_array(&apos;products&apos;, $query);
    	
    }
}
&lt;/code&gt;

Things to note in this snippet:

# We start be loading a reference to the &apos;&apos;Dataface_Application&apos;&apos; object.
# We then use the &apos;&apos;Dataface_Application&apos;&apos; object to load the current query.  This is essentially an associative array of all of the GET parameters, but with some guaranteed attributes such as &apos;&apos;-table&apos;&apos; and &apos;&apos;-action&apos;&apos;.
# In our particular action we are designing it to only work for the &apos;&apos;products&apos;&apos; table so we do a check on the query parameters to make sure that this is the case.  If someone tries to run this action from outside the products table (e.g. if -action=foo) then an error will be displayed.
# We use the df_get_records_array() function to return all matching records on the products table.  It returns an array of [[Dataface_Record]] objects.


====Overriding -skip and -limit====

Xataface allows the user to specify the number of records to display and the position in the found set to start from by adding the &apos;&apos;-skip&apos;&apos; and &apos;&apos;-limit&apos;&apos; GET parameters to a request.  If these are omitted, then default values of 0 and 30 are used respectively.  You may notice that if you click &quot;Next&quot; in list view, you see &apos;-skip&apos; and &apos;-limit&apos; parameters automatically added to the URL.

&apos;&apos;df_get_records_array&apos;&apos; respects the -limit and -skip parameters that are specified in the query.  I.e. if -skip and -limit are omitted it will return only the first 30 records from the found set.  If -skip=1 and -limit=10 then it will return 10 records starting from the 2nd record (2nd becuase -skip=0 would point to the first record).  This may be desired behavior for your report, but in some reports you may want to print off the entire found set.  If this is the case, you will want to explicitly set the -skip and -limit parameters in the &apos;&apos;$query&apos;&apos; array before passing it to &apos;&apos;df_get_records_array&apos;&apos;.  E.g.:

&lt;code&gt;
$query =&amp; $app-&gt;getQuery();
$query[&apos;-skip&apos;] = 0;
$query[&apos;-limit&apos;] = 10000;
$products = df_get_records_array(&apos;products&apos;, $query);
&lt;/code&gt;


====Looping through and Printing Product Info====

Now comes the fun part.  We&apos;re just going to loop through our found set and print off the product information:

&lt;code&gt;


foreach ($products as $p){
	

	echo &apos;&lt;table&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Product ID&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_id&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Product Name&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_name&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_description&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Photo&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_image&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;/table&gt;&apos;;
}

&lt;/code&gt;


The entire action at this point will look like:

&lt;code&gt;

&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	$app =&amp; Dataface_Application::getInstance();
    	$query =&amp; $app-&gt;getQuery();
    	$query[&apos;-skip&apos;] = 0;
		$query[&apos;-limit&apos;] = 10000;
		
    	if ( $query[&apos;-table&apos;] != &apos;products&apos; ){
    		return PEAR::raiseError(&apos;This action can only be called on the Products table.&apos;);
    	}
    	
    	$products = df_get_records_array(&apos;products&apos;, $query);
    	foreach ($products as $p){
	

			echo &apos;&lt;table&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product ID&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_id&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product Name&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_name&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_description&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Photo&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_image&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;/table&gt;&apos;;
		}
    	
    }
}
&lt;/code&gt;

Now we refresh our action in the web browser, or point the browser again to:
 http://example.com/yourapplication/index.php?-action=printable_report&amp;-table=products
 
It should display something like:

[[Image:http://media.weblite.ca/files/photos/Picture%205.png?max_width=640]]

If you get a blank white screen, please check out the [[Troubleshooting]] section for general Xataface troubleshooting strategies.

====Adding a Little Style====

It is a good idea to at least provide the proper HTML HEAD and BODY tags for your report.  And to help make things a little nicer looking we&apos;re going to add some CSS styles to:

# Make the table field labels vertically aligned to the top.
# Change the font to helvetica.

This is easy to do with simple echo statements:

&lt;code&gt;
echo &apos;&lt;html&gt;&lt;head&gt;&apos;
	.&apos;&lt;title&gt;Printable Report&lt;/title&gt;&apos;
	.&apos;&lt;style type=&quot;text/css&quot;&gt;&apos;
	.&apos;	th { vertical-align: top}&apos;
	.&apos;&lt;/style&gt;&apos;
	.&apos;&lt;/head&gt;&apos;
	.&apos;&lt;body&gt;&apos;;
	
	//...
	


&lt;/code&gt;

So our finished action looks like:


&lt;code&gt;
&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	$app =&amp; Dataface_Application::getInstance();
    	$query =&amp; $app-&gt;getQuery();
    	$query[&apos;-skip&apos;] = 0;
		$query[&apos;-limit&apos;] = 10000;
		
    	if ( $query[&apos;-table&apos;] != &apos;products&apos; ){
    		return PEAR::raiseError(&apos;This action can only be called on the Products table.&apos;);
    	}
    	
    	$products = df_get_records_array(&apos;products&apos;, $query);
    	
    	
    	
    	echo &apos;&lt;html&gt;&lt;head&gt;&apos;
			.&apos;&lt;title&gt;Printable Report&lt;/title&gt;&apos;
			.&apos;&lt;style type=&quot;text/css&quot;&gt;&apos;
			.&apos;	th { vertical-align: top}&apos;
			.&apos;&lt;/style&gt;&apos;
			.&apos;&lt;/head&gt;&apos;
			.&apos;&lt;body&gt;&apos;;
    	foreach ($products as $p){
	

			echo &apos;&lt;table&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product ID&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_id&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product Name&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_name&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_description&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Photo&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_image&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;/table&gt;&apos;;
		}
		
		echo &apos;&lt;/body&gt;&lt;/html&gt;&apos;;
    	
    }
}
&lt;/code&gt;



===Connecting the Icon to the Action===

FInally it is time to connect our Icon to our Action.  We do this by adding a &apos;&apos;url&apos;&apos; directive for the action in the &apos;&apos;[[actions.ini file]]&apos;&apos;:


&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
    url=&quot;{$app-&gt;url(&apos;-action=printable_report&apos;)}&quot;
&lt;/code&gt;

Explanation of the &apos;&apos;url&apos;&apos; directive in this snippet:

* The &apos;&apos;url&apos;&apos; method of the &apos;&apos;[[Dataface_Application]]&apos;&apos; object is used to generate a URL with the user&apos;s current query settings, but with the &apos;&apos;-action&apos;&apos; parameter set to &apos;&apos;printable_report&apos;&apos;.

Now if we reload our application, go to the list tab of the &apos;&apos;products&apos;&apos; table and click on our icon, it should take us to our action:

[[Image:http://media.weblite.ca/files/photos/Picture%207.png?max_width=640]]

===Trying out the action on different found sets with different sort orders===

One of the cool things about this action is that it is tied directly into the Xataface find settings so that th user is able to search for a subset of products and run our report on only those products that were found.  The user can also perform a sort on any column and this sort will be respected by our report.

===Hiding Icon from Other Tables===

Since our action is only intended to operate on the &apos;&apos;products&apos;&apos; table it probably isn&apos;t a good idea to make the icon visible for every other table.  For example, if you go to the list view of the &apos;&apos;users&apos;&apos; table, you&apos;ll see the printer icon in the top right just like it appears for the &apos;&apos;products&apos;&apos; table.  Clicking on it should display our error:

[[Image:http://media.weblite.ca/files/photos/Picture%206.png?max_width=640]]

We will use a &apos;&apos;condition&apos;&apos; directive for our action to hide it from tables other than the &apos;&apos;products&apos;&apos; table as follows:

 condition=&quot;$query[&apos;-table&apos;] == &apos;products&apos;&quot;
 
So our action will now look like:

&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
    url=&quot;{$app-&gt;url(&apos;-action=printable_report&apos;)}&quot;
    condition=&quot;$query[&apos;-table&apos;] == &apos;products&apos;&quot;
&lt;/code&gt;

Now if you reload the list for the &apos;&apos;users&apos;&apos; table you&apos;ll notice that the printer icon is now gone.  But returning to the &apos;&apos;products&apos;&apos; table shows our action still alive and well.

===Locking Down our Action with Permissions===

In our case we don&apos;t want our action to be accessible to all users.  Only administrators.  Xataface permissions and all its possibilities are beyond the scope of this tutorial, but we still want to demonstrate how to lock down this action.  The WebAuction application into which this action is being installed defines a permission called &apos;&apos;reports&apos;&apos; which only administrators have.  We will use this permission to limit access to this action as follows in the actions.ini file:
 permission=reports

So the actions.ini file will now look like:
&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
    url=&quot;{$app-&gt;url(&apos;-action=printable_report&apos;)}&quot;
    condition=&quot;$query[&apos;-table&apos;] == &apos;products&apos;&quot;
    permission=reports
&lt;/code&gt;

Now only administrators will see our icon, and if non-administrators attempt to access out action by typing in its URL directly, they will receive an &quot;Access Denied&quot; message.

</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=83">
	<page_name>Key</page_name>
	<page_id>83</page_id>
	<page_title>fields.ini Directive: Key</page_title>
	<content>The &apos;&apos;&apos;Key&apos;&apos;&apos; directive is used only when the table is a view and you need to explicitly define which columns are part of the primary key.  For example, if we created a view on the books table to only show books in a given year as follows:
&lt;code&gt;
create view books_2000 as
select * from books where year=&apos;2000&apos;
&lt;/code&gt;

And we wanted to use this view as a table in our Xataface application we would need to tell it that the primary key of this view is the book_id field.  So in the fields.ini file we would add:

&lt;code&gt;
[book_id]
    Key=PRI
&lt;/code&gt;

Note that this is case sensitive.  key=PRI will not work.

===Compound Primary Keys===

For primary keys comprising multiple columns we would add this directive for each field in the key.  E.g. if our books_2000 view had 2 fields in the primary key, say author_id and book_index, we would have in the books_2000 fields.ini file:
&lt;code&gt;
[author_id]
    Key=PRI

[book_index]
    Key=PRI
&lt;/code&gt;

Links:
* [http://xataface.com/forum/viewtopic.php?f=4&amp;t=6723 Lookup widget on view with compound primary key]

Return to [[fields.ini file]]</content>
	<keywords>Key, Views, MySQL Views, Create View, PRI, Primary Keys</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=84">
	<page_name>http://xataface.com/documentation/how-to/site_with_backoffice_How_to_build_a_site_with_a_backoffice_</page_name>
	<page_id>84</page_id>
	<page_title>A site with a backoffice</page_title>
	<content>==A site with a backoffice==
To create a site with a backoffice for the administrator, so that the visitors do not have to log in to read the pages, you add this code in the ApplicationDelegate.php file in the conf directory :
&lt;code&gt;

function getPermissions(&amp;$record){
    if ( isAdmin() ) return Dataface_PermissionsTool::ALL();
    else return Dataface_PermissionsTool::READ_ONLY();
}
 
&lt;/code&gt;
</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=85">
	<page_name>http://xataface.com/documentation/how-to/site_with_backoffice</page_name>
	<page_id>85</page_id>
	<page_title>How to build a site with an optional login form</page_title>
	<content>==How to build a site with an optional login form==
To publish a public site with data without any need to login to access, here is the code :
&lt;code&gt;
function getPermissions(&amp;$record){
    if ( isAdmin() ) return Dataface_PermissionsTool::ALL();
    else return Dataface_PermissionsTool::READ_ONLY();
} 
&lt;/code&gt;
In this way, you still can login to administrate your data.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=86">
	<page_name>site_with_backoffice</page_name>
	<page_id>86</page_id>
	<page_title></page_title>
	<content>==How to build a site with an optional login form==
To publish a public site with data without any need to login to access, here is the code :
&lt;code&gt;
function getPermissions(&amp;$record){
    if ( isAdmin() ) return Dataface_PermissionsTool::ALL();
    else return Dataface_PermissionsTool::READ_ONLY();
} 
&lt;/code&gt;
In this way, you still can login to administrate your data.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=87">
	<page_name>sql_delegate_method</page_name>
	<page_id>87</page_id>
	<page_title>__sql__ Delegate Method</page_title>
	<content>return to [[Delegate class methods]]

===Synopsis===

The __sql__ delegate class method can be defined in any delegate class to specify the SQL query that should be used to fetch records for a given table.  This method overrides the [[__sql__]] directive of the fields.ini file.  This strategy is primarily used to graft columns from another table onto the base table.

=====Use Caution=====

This is an advanced feature and, if used incorrectly, can muck up your application. Make sure that your SQL query includes a superset of the columns in the base table, and is a row-for-row match for the rows in the base table.  I.e. you should never use an internal join.  Always use a left join so that all of the rows of the base table are returned even if the join table doesn&apos;t have a corresponding row.

If you want to simply filter a table&apos;s records, and don&apos;t need to graft any additional columns onto the table, you should use the [[setSecurityFilters]] method.

===Example===

Given the table foo, its delegate class:

&lt;code&gt;
class tables_foo {
    function __sql__(){
        return &quot;select f.*, c.category_name from foo f left join categories c on f.category_id=c.category_id&quot;;
    }
}
&lt;/code&gt;

This effectively grafts a column &quot;category_name&quot; onto the foo table based on a join with the categories table.

</content>
	<keywords>__sql__, SQL queries, delegate class</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=88">
	<page_name>secure</page_name>
	<page_id>88</page_id>
	<page_title>secure fields.ini directive</page_title>
	<content>[[fields.ini file]] directive used only with [[container fields]].  If this flag is set, then the field contents will be treated in a secure manner and will obey the application permissions.  If this directive is not set, then uploaded files in [[container fields]] are served directly by the web server without considering application permissions.  Setting this directive will cause the application use a special get_blob action to serve the uploaded file, and this obeys application permissions.

==Example==

Given a field to upload a PDF report, your [[fields.ini file]] section for this field might be something like:

&lt;code&gt;
[pdf_report]
    Type=container
    allowed_extensions=&quot;pdf&quot;
    savepath=&quot;uploads&quot;
    url=&quot;uploads&quot;
&lt;/code&gt;


Now if we upload a file named &quot;foo.pdf&quot; in this field, it will be uploaded to:
 http://www.example.com/path/to/myapp/uploads/foo.pdf

Now we change the field definition to use the secure directive:

&lt;code&gt;
[pdf_report]
    Type=container
    allowed_extensions=&quot;pdf&quot;
    savepath=&quot;uploads&quot;
    url=&quot;uploads&quot;
    secure=1
&lt;/code&gt;

In this case it will still upload files to the &apos;&apos;uploads&apos;&apos; directory, but all of the links generated in the Xataface interface (and via the &apos;&apos;display()&apos;&apos; and &apos;&apos;htmlValue()&apos;&apos; methods) will be for a URL like:
  http://www.example.com/path/to/myapp/index.php?-action=getBlob&amp;-table=mytable&amp;-field=pdf_report&amp;record_id=10

Which will serve up the PDF file as an attachment.

===Restricting Direct Access to uploads directory===

Note: You still need to restrict access to the uploads directory or it may be possible for users to still guess the absolute URL to files in it.  You can restrict access by placing an .htaccess file in the uploads directory (if you are using Apache) with the following contents:
&lt;code&gt;
deny from all
&lt;/code&gt;

If you are using IIS or another web server you should look into the methods available for you to restrict access to directories.

===HTTP Response Codes===

The [[getBlob action]] will return the following HTTP Response Codes:

* &apos;&apos;&apos;404&apos;&apos;&apos; - If either the record does not exist, or the record&apos;s specified container field is empty.
* &apos;&apos;&apos;403&apos;&apos;&apos; - If the current user doesn&apos;t have permission to access this record.
* &apos;&apos;&apos;500&apos;&apos;&apos; - If there is another error.  The actual error will be written to the error log.</content>
	<keywords>secure,fields.ini file</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=89">
	<page_name>file</page_name>
	<page_id>89</page_id>
	<page_title></page_title>
	<content>==Dynamic select boxes==

To create two select boxes whose one is dependent (slave) of the other (master), we need to use some javascript with Jason.

Create the valuelists.ini:
&lt;code&gt;

;valuelist for the slave
[slaves_list]
__sql__ = &quot;select slave_id, slave_name, master_id from slaves&quot;

; valuelist for the masters
[masters_list]
__sql__ = &quot;select master_id,master_name from masters&quot;
&lt;/code&gt;

fields.ini:
&lt;code&gt;
[master]
vocabulary=masters_list

[slave]
vocabulary=slaves_list
&lt;/code&gt;

delegate class in the table directory :
&lt;code&gt;
...
function block__after_new_record_form(){
echo &lt;&lt;&lt;END
&lt;script language=&quot;javascript&quot;&gt;&lt;!--
var slave_field= document.getElementById(&apos;slave&apos;);
var master_field = document.getElementById(&apos;master&apos;);
END;
// Let&apos;s get all the slaves available.
$app =&amp; Dataface_Application::getInstance();
$query =&amp; $app-&gt;getQuery();
$table =&amp; Dataface_Table::loadTable($query[&apos;-table&apos;]);
$slaves = $table-&gt;getValuelist(&apos;slaves_list&apos;);
$slave_masters = $table-&gt;getValuelist(&apos;slaves_list__meta&apos;);
// Note that the slaves_list__meta valuelist is automatically created
// because we had three columns in the slaves valuelist.
// The first and third columns effectively create a 2nd valuelist
// named &apos;slaves_list__meta&apos;

// $slaves is an array with keys slave_id and values slave_name
// slave_masters is an array with keys slave_id and values master_id

import(&apos;Services/JSON.php&apos;);
$json =&amp; new Services_JSON(); // A JSON encoder to allow us to easily
// convert PHP arrays to javascript arrays.
echo &apos;
var slaves_options = &apos;.$json-&gt;encode($slaves).&apos;;
var slaves_master = &apos;.$json-&gt;encode($slave_masters).&apos;;
&apos;;

echo &lt;&lt;&lt;END
master_field.onchange = function(){
var selected_master = master_field.options[master_field.selectedIndex].value;
slave_field.options.length = 0;
var index = 0;
for ( slave_id in slaves_options){
if ( selected_master == slaves_master[slave_id] ){
slave_field.options[index++] = new Option(slaves_options[slave_id], slave_id);
}
}
};
//--&gt;&lt;/script&gt;
END;
}

// Also place this javascript after an edit record form...
function block__after_edit_record_form(){
return $this-&gt;block__after_new_record_form();
}


&lt;/code&gt; </content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=90">
	<page_name>Dynamic_select_boxes</page_name>
	<page_id>90</page_id>
	<page_title></page_title>
	<content>==Dynamic select boxes==

To create two select boxes whose one is dependent (slave) of the other (master), we need to use some javascript with Jason.

Create the valuelists.ini:
&lt;code&gt;

;valuelist for the slave
[slaves_list]
__sql__ = &quot;select slave_id, slave_name, master_id from slaves&quot;

; valuelist for the masters
[masters_list]
__sql__ = &quot;select master_id,master_name from masters&quot;
&lt;/code&gt;

fields.ini:
&lt;code&gt;
[master]
vocabulary=masters_list

[slave]
vocabulary=slaves_list
&lt;/code&gt;

delegate class in the table directory :
&lt;code&gt;
...
function block__after_new_record_form(){
echo &lt;&lt;&lt;END
&lt;script language=&quot;javascript&quot;&gt;&lt;!--
var slave_field= document.getElementById(&apos;slave&apos;);
var master_field = document.getElementById(&apos;master&apos;);
END;
// Let&apos;s get all the slaves available.
$app =&amp; Dataface_Application::getInstance();
$query =&amp; $app-&gt;getQuery();
$table =&amp; Dataface_Table::loadTable($query[&apos;-table&apos;]);
$slaves = $table-&gt;getValuelist(&apos;slaves_list&apos;);
$slave_masters = $table-&gt;getValuelist(&apos;slaves_list__meta&apos;);
// Note that the slaves_list__meta valuelist is automatically created
// because we had three columns in the slaves valuelist.
// The first and third columns effectively create a 2nd valuelist
// named &apos;slaves_list__meta&apos;

// $slaves is an array with keys slave_id and values slave_name
// slave_masters is an array with keys slave_id and values master_id

import(&apos;Services/JSON.php&apos;);
$json =&amp; new Services_JSON(); // A JSON encoder to allow us to easily
// convert PHP arrays to javascript arrays.
echo &apos;
var slaves_options = &apos;.$json-&gt;encode($slaves).&apos;;
var slaves_master = &apos;.$json-&gt;encode($slave_masters).&apos;;
&apos;;

echo &lt;&lt;&lt;END
master_field.onchange = function(){
var selected_master = master_field.options[master_field.selectedIndex].value;
slave_field.options.length = 0;
var index = 0;
for ( slave_id in slaves_options){
if ( selected_master == slaves_master[slave_id] ){
slave_field.options[index++] = new Option(slaves_options[slave_id], slave_id);
}
}
};
//--&gt;&lt;/script&gt;
END;
}

// Also place this javascript after an edit record form...
function block__after_edit_record_form(){
return $this-&gt;block__after_new_record_form();
}


&lt;/code&gt; 

The 2.0 version has a [http://xataface.com/dox/modules/depselect/latest| depselect module] to produce cascading dynamic select boxes very simply.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=91">
	<page_name>setSecurityFilters</page_name>
	<page_id>91</page_id>
	<page_title>setSecurityFilter() method</page_title>
	<content>== Example ==

In the delegate class for the users table:

&lt;code&gt;
&lt;?php
class tables_users {
    function init(&amp;$table){
        if ( !isAdmin() ){
            $table-&gt;setSecurityFilter(array(&apos;group_id&apos;=&gt;10));
        }
    }
}
&lt;/code&gt;

This will only set the filter on non-admin users (assuming that you have defined a function isAdmin() to tell you if the current user is an admin user.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=92">
	<page_name>Authenticating_Against_the_PHPBB_Users_table</page_name>
	<page_id>92</page_id>
	<page_title>Authenticating Against the PHPBB Users Table</page_title>
	<content>Return to [[authentication]]

[[toc]]

Xataface is able to use the PHPBB users table to authenticate against so that, you can allow your users to log into your Xataface application using the same credentials as they use to access your PHPBB message forum.  Achieving this level of integration requires 2 simple steps:

# Set up the [[_auth]] section of your [[conf.ini file]] to reference the PHPBB users table and the correct username and password columns.
# Specify the correct encryption on the password column.  This step will be different for different versions of PHPBB.

==PHPBB 2==

PHPBB version 2 and lower simply use MD5 encryption on the password column, which Xataface supports natively via the [[encryption]] directive of the [[fields.ini file]].  Therefore we can set up our Xataface application to authenticate against our PHPBB2 database (&apos;&apos;&apos;assuming that our PHPBB is set up in the same database as our Xataface app&apos;&apos;&apos;) by doing the following:

# Set up the [_auth] section of the [[conf.ini file]] as follows:&lt;code&gt;
[_auth]
users_table = phpbb_users
username_column = username
password_column = user_password
&lt;/code&gt;
# Set up the user_password field to use md5 encryption in the &apos;&apos;tables/phpbb_users/fields.ini&apos;&apos; file &lt;code&gt;
[user_password]
encryption=md5
&lt;/code&gt;

That&apos;s it!  Now you should be able to log into your Xataface application using the username/password from PHPBB.


==PHPBB 3==

PHPBB version 3 and higher uses a custom encryption function for the password column so it is a little more complicated (but not that much).  Step one (the [[conf.ini file]]) is the same as for PHPBB version 2 listed above.  The 2nd part, however, requires us to implement a custom serialization for the user_password field.  So the steps are below:

# Set up the [_auth] section of the [[conf.ini file]] as follows:&lt;code&gt;
[_auth]
users_table = phpbb_users
username_column = username
password_column = user_password
&lt;/code&gt;
# Implement the user_password__serialize() method in your phpbb_users delegate class (i.e. the &apos;&apos;tables/phpbb_users/phpbb_users.php&apos;&apos; file):&lt;code&gt;
&lt;?php
class tables_phpbb_users {
	

	function user_password__serialize($password){
		$itoa64 = &apos;./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&apos;;
		$sql = &quot;select user_password from phpbb_users where username=&apos;&quot;.addslashes($_POST[&apos;UserName&apos;]).&quot;&apos;&quot;;
		$res = mysql_query($sql, df_db());
		if ( !$res ) throw new Exception(mysql_error(df_db()));
		$row = mysql_fetch_assoc($res);
		mysql_free_result($res);
		$hash = $this-&gt;_hash_crypt_private($password, $row[&apos;user_password&apos;], $itoa64);
		return $hash;
	}
	
	
	/**
	* The crypt function/replacement
	*/
	function _hash_crypt_private($password, $setting, &amp;$itoa64)
	{
		$output = &apos;*&apos;;
	
		// Check for correct hash
		if (substr($setting, 0, 3) != &apos;$H$&apos;)
		{
			return $output;
		}
	
		$count_log2 = strpos($itoa64, $setting[3]);
	
		if ($count_log2 &lt; 7 || $count_log2 &gt; 30)
		{
			return $output;
		}
	
		$count = 1 &lt;&lt; $count_log2;
		$salt = substr($setting, 4, 8);
	
		if (strlen($salt) != 8)
		{
			return $output;
		}
	
		/**
		* We&apos;re kind of forced to use MD5 here since it&apos;s the only
		* cryptographic primitive available in all versions of PHP
		* currently in use.  To implement our own low-level crypto
		* in PHP would result in much worse performance and
		* consequently in lower iteration counts and hashes that are
		* quicker to crack (by non-PHP code).
		*/
		if (PHP_VERSION &gt;= 5)
		{
			$hash = md5($salt . $password, true);
			do
			{
				$hash = md5($hash . $password, true);
			}
			while (--$count);
		}
		else
		{
			$hash = pack(&apos;H*&apos;, md5($salt . $password));
			do
			{
				$hash = pack(&apos;H*&apos;, md5($hash . $password));
			}
			while (--$count);
		}
	
		$output = substr($setting, 0, 12);
		$output .= $this-&gt;_hash_encode64($hash, 16, $itoa64);
	
		return $output;
	}
	
	/**
	* Encode hash
	*/
	function _hash_encode64($input, $count, &amp;$itoa64)
	{
		$output = &apos;&apos;;
		$i = 0;
	
		do
		{
			$value = ord($input[$i++]);
			$output .= $itoa64[$value &amp; 0x3f];
	
			if ($i &lt; $count)
			{
				$value |= ord($input[$i]) &lt;&lt; 8;
			}
	
			$output .= $itoa64[($value &gt;&gt; 6) &amp; 0x3f];
	
			if ($i++ &gt;= $count)
			{
				break;
			}
	
			if ($i &lt; $count)
			{
				$value |= ord($input[$i]) &lt;&lt; 16;
			}
	
			$output .= $itoa64[($value &gt;&gt; 12) &amp; 0x3f];
	
			if ($i++ &gt;= $count)
			{
				break;
			}
	
			$output .= $itoa64[($value &gt;&gt; 18) &amp; 0x3f];
		}
		while ($i &lt; $count);
	
		return $output;
	}

	

}
&lt;/code&gt;</content>
	<keywords>PHPBB, authentication, security, authentication modules</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=93">
	<page_name>Authenticating_Against_the_Joomla!_Users_Table</page_name>
	<page_id>93</page_id>
	<page_title></page_title>
	<content>Xataface is able to use the joomla users table to authenticate against so that, you can allow your users to log into your Xataface application using the same credentials as they use to access your joomla website. Achieving this level of integration requires 2 simple steps :
1 - Set up the [_auth] section of your conf.ini file to reference the joomla users table and the correct username and password columns.
2 - Create a delegate class for the joomla users table to be able to decrypt the password set in the table.
==Configure the conf.ini file==
Joomla users table is named jos_users. So you have to declare this table in the conf.ini file.
&lt;code&gt;[_auth]
users_table = jos_users
username_column = username
password_column = password&lt;/code&gt;
Note that username_column and password_column are very simple...
==Create a delegate class for your users table==
Now we have to create a delegate class for the users table to decrypt the passwords set in joomla.
Joomla uses a custom md5 encryption.
===Joomla encryption===
When a user is setting a password in joomla, the system does several things :
1 - generate a random key containing alphanumeric characters
example : 
&lt;code&gt;8NdiRqLRKLHaNwudJ3InJknsew9sc7pL&lt;/code&gt;
2 - concate the clear entered password with the random key
example : 
&lt;code&gt;password8NdiRqLRKLHaNwudJ3InJknsew9sc7pL&lt;/code&gt;
3 - doing a md5 encryption on the result string
example : 
&lt;code&gt;md5(password8NdiRqLRKLHaNwudJ3InJknsew9sc7pL = f2b1fb3996442db549c1ed1a1eebbfe1&lt;/code&gt;
4 - concate the md5 string with the random key separated by &quot;:&quot;
example :
&lt;code&gt;f2b1fb3996442db549c1ed1a1eebbfe1:8NdiRqLRKLHaNwudJ3InJknsew9sc7pL&lt;/code&gt;
So it&apos;s a great encryption but xataface doesn&apos;t know how to do that.
Here is the utility of the delegate class. We will define a function inside which could compare the entered password in xataface with the joomla stored password.
===Creating the delegate class===
1 - Add a jos_users directory in your directory table
2 - Create a jos_users.php file inside this new directory
===Creating the decrypt password function===
Before posting this code, I would like to thank fantomasdm who created this function.
So here is the code of the function to paste directly in the jos_users delegate class :
&lt;code&gt;&lt;?
class tables_jos_users {
	
function password__serialize($password){

   $app =&amp; Dataface_Application::getInstance(); 
   $query = &quot;SELECT id, gid, block, password, usertype FROM jos_users where username=&apos;&quot;.$_POST[&apos;UserName&apos;].&quot;&apos;&quot;;
   $result = mysql_query($query,$app-&gt;db()) or die(&quot;Query failed&quot; . mysql_error() );

   $line = mysql_fetch_array($result, MYSQL_ASSOC);
   mysql_free_result($result);

   $arraypass=explode(&quot;:&quot;, $linea[&apos;password&apos;]);
   $key=$arraypass[1];
   
   $ret = md5(trim($password).$key).&quot;:&quot;.$key;
   return $ret;
} 
}
?&gt;&lt;/code&gt;
Save your file and test the result.
Enjoy ! ;-)</content>
	<keywords>joomla authentication md5</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=94">
	<page_name>fieldname__validate</page_name>
	<page_id>94</page_id>
	<page_title>fieldname__validate Delegate Class Method</page_title>
	<content>Return to [[Delegate class methods]]

[[toc]]

===Synopsis===

Xataface allows you to add validation on any particular field in table by adding a fieldname__validate method to the table&apos;s delegate class of the form:
&lt;code&gt;
function myfield__validate(&amp;$record, $value, &amp;$params){
    if ( $value != &apos;Steve&apos; ){
        $params[&apos;message&apos;] = &apos;Sorry you must enter &quot;Steve&quot;&apos;;
        return false;
    }
    return true;
}
&lt;/code&gt;

===Parameters===

* &amp;$record : A [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object encapsulating the record we are validating.  Note that the values of this object correspond with the submitted values from the form, and not necessarily the actual values of the record in the database.
* $value : The value that is being inserted.
* &amp;$params : An output array that can be used to pass back a message if validation fails.  You would set this array&apos;s &apos;message&apos; parameter to be a message.

===Returns===

Returns a boolean value.  True if the value is ok and false if validation failed.

===See Also===

* [[validators]] - For simple validation rules you can use the [[validators|validator:VALIDATOR_NAME]] directive of the [[fields.ini file]].
* [http://xataface.com/documentation/tutorial/getting_started/validation Form Validation] - Section on form validation in the Getting Started tutorial.

</content>
	<keywords>validate, validation, delegate class validation, custom validator</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=95">
	<page_name>validators</page_name>
	<page_id>95</page_id>
	<page_title>validators:NAME fields.ini directive</page_title>
	<content>Return to [[fields.ini file]]

[[toc]]

===Synopsis===

In the fields.ini file you can specify validation rules to be applied to any field by adding the validators:NAME directive in that field&apos;s section of the [[fields.ini file]].

===Available Validators===

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Value
! Version
|-
| required
| Field is required
| 1
| All
|-
| maxlength
| Maximum number of characters allowed.
| $length
| All
|-
| minlength
| Minimum number of characters allowed.
| $length
| All
|-
| rangelength
| Range (min and max) characters allows
| $min,$max
| All
|-
| email
| Input must be syntactically correct email address.
| 1
| All
|-
| emailorblank
| Accepts an email address or a blank field.
| 1
| All
|-
| regex
| Input must match the provided regular expression.
| A regular expression
| All
|-
| lettersonly
| Input must contain only letters (i.e. [a-zA-Z]
| 1
| All
|-
| numeric
| The input must contain a valid positive or negative integer or decimal number.
| 1
| All
|-
| nopunctuation
| The input must not contain any of these characters: &lt;nowiki&gt;( ) . / * ^ ? # ! @ $ % + = , &quot; &apos; &amp;gt; &amp;lt; ~ [ ] { }.&lt;/nowiki&gt;
| 1
| All
|-
| nonzero
| The input must not begin with zero.
| 1
| All
|-
| uploadedfile
| The element must contain a successfully uploaded file.
| 1
| All
|-
| maxfilesize
| The uploaded file must be no more than $size bytes.
| $size
| All
|-
|filename
| The uploaded file must have a filename that matches the regular expression $file_rx.
| $file_rx
| All
|}


===Examples===

To make a the first_name field required we add the following to the [[fields.ini file]]:
&lt;code&gt;
[first_name]
    validators:required=1
&lt;/code&gt;

&apos;&apos;&apos;Note that fields that are declared NOT NULL in the database are required by default.&apos;&apos;&apos;.  If you wanted to remove the &apos;&apos;required&apos;&apos; validator from a field that is NOT NULL in the database you would add the following to the [[fields.ini file]]:
&lt;code&gt;
[first_name]
    validators:required=0
&lt;/code&gt;

===See Also===

* [[fieldname__validate]] - For more complex validation you can define the [[fieldname__validate]] method in the [[Delegate class methods|Table Delegate Class]].
* [http://www.devarticles.com/c/a/Web-Graphic-Design/Using-HTML-Quickform-for-Form-Processing/12/ HTML_QuickForm article] going over HTML_Quickform validation.  Dataface&apos;s forms are built on HTML_QuickForm.
* [http://xataface.com/documentation/tutorial/getting_started/validation Form Validation] - Section from getting started tutorial introducing form validation in a tutorial format.

</content>
	<keywords>validation, form validation, validators,validator:name</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=96">
	<page_name>validators:VALIDATOR_NAME:message</page_name>
	<page_id>96</page_id>
	<page_title>validators:VALIDATOR_NAME:message directive for the fields.ini file</page_title>
	<content>Return to [[fields.ini file]]

[[toc]]

===Synopsis===

If you want to customize the error message associated with a particular [[validator|validation rule]] you can use the validators:VALIDATOR_NAME:message directive in the fields.ini file.

===Format===

&lt;code&gt;
[myfield]
    validators:VALIDATOR_NAME:message = MESSAGE
&lt;/code&gt;

===Examples===

If you don&apos;t like the default error message that is displayed when you make the first_name field required, you can customize it with your own message.  E.g.
&lt;code&gt;
[first_name]
    validators:required=1
    validators:required:message = &quot;Please enter your first name&quot;
&lt;/code&gt;

===See Also===

* [[validators]] - The [[fields.ini file]] directive for adding a validation rule to a field.  This directive must be used in conjunction with [[validators]].
* [[fieldname__validate]] - For more complex validation rules you can define them in the table delegate class.
* [http://xataface.com/documentation/tutorial/getting_started/validation Form Validation] - Section in the Getting Started tutorial on form validation.</content>
	<keywords>validation messages,error messages,form validation rules</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=97">
	<page_name>_auth</page_name>
	<page_id>97</page_id>
	<page_title>_auth section of the conf.ini file</page_title>
	<content>[[conf.ini file|Return to conf.ini file]]

[[toc]]

===Synopsis===

The &apos;&apos;_auth&apos;&apos; section of the conf.ini file includes configuration directives to enable authentication in a Xataface application.  For more information about authentication and registration see [[authentication]].  This section may include the following directives:

===Directives===

{| class=&quot;listing listing2&quot;
|-
! Directive
! Description
! Required
! Default
! Version
|-
| users_table
| The name of the table that contains your user accounts.
| Yes
| None
| 0.6
|-
| username_column
| The name of the column that stores the username.
| Yes
| None
| 0.6
|-
| password_column
| The name of the column that stores the password.
| Required if using basic authentication.
| None
| 0.6
|-
| auth_type
| Specifies the authentication module that is being used.  E.g. basic, cas, ldap, http, facebook, etc...
| No
| basic
| 0.6
|-
| allow_register
| Flag to enable user registration.  If this is set to 1, then a &apos;&apos;register&apos;&apos; link will appear below the login form.
| No
| 0
| 0.8
|-
| session_timeout
| Number of seconds of inactivity after which the user will be logged out. Note: Arithmetic don&apos;t work in the conf.ini, use seconds.
| No
| 86400 (=&gt; 24*60*60 (24 hours))
| 1.3rc4
|}

===See Also===

* [[authentication]] - Overview of Xataface Authentication
* [[conf.ini file]] - Directives available in the conf.ini file.</content>
	<keywords>_auth,authentication,conf.ini file,allow_register</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=98">
	<page_name>registration_form</page_name>
	<page_id>98</page_id>
	<page_title>Setting up User Registration</page_title>
	<content>[[toc]]

===Synopsis===

Xataface optionally enables you to allow users to register for an account in your application.  If your &apos;&apos;users&apos;&apos; table includes a column for email, it will also perform email validation before the account is activated.  Before tackling user registration, it is good to have an understanding of Xataface&apos;s [[authentication]] and [http://xataface.com/documentation/tutorial/getting_started/permissions permissions] faculties.

===Enabling Registration===

To enable registration, simply add the following to the &apos;&apos;[[_auth]]&apos;&apos; section of the [[conf.ini file]]:

&lt;code&gt;
allow_register=1
&lt;/code&gt;

e.g. after adding this, your &apos;&apos;[[_auth]]&apos;&apos; section might look like:

&lt;code&gt;
[_auth]
     users_table=users
     username_column=username
     password_column=password
     allow_register=1
&lt;/code&gt;

After doing this, you&apos;ll notice a little &apos;&apos;Register&apos;&apos; link below the login form.  

[[Image:http://media.weblite.ca/files/photos/Picture%2036.png?max_width=640]]

Clicking on this link will produce a registration form for the user which is essentially a &quot;New Record&quot; form on your &apos;&apos;users&apos;&apos; table.

[[Image:http://media.weblite.ca/files/photos/Picture%2037.png?max_width=640]]

Some features of this registration form include:

* Checks to ensure that the username is unique
* If the users table contains an &apos;&apos;email&apos;&apos; field, it will use the user-entered address for email validation before activation is complete.

===Setting up Permissions to Support Registration===

&apos;&apos;&apos;Xataface &lt;= 1.2.4&apos;&apos;&apos;:   You must ensure that unlogged-in users have permission to add new records to the &apos;&apos;users&apos;&apos; table.  This means that your getPermissions() method on the users table should, at least, provide the &apos;&apos;new&apos;&apos; permission.  In addition these users must be granted the &apos;&apos;register&apos;&apos; permission in order to be able to register to begin with.

&apos;&apos;&apos;Xataface &gt;= 1.2.5&apos;&apos;&apos;:  You no longer need to provide the &apos;&apos;new&apos;&apos; permission to allow users to register.  You simply need to provide the &apos;&apos;register&apos;&apos; permission.

====Sample Permissions on Users Table====

In the tables/users/users.php file (assuming my &apos;&apos;users&apos;&apos; table is actually named &quot;users&quot;)

&lt;code&gt;
class tables_users {

    function getPermissions($record){
        if ( isAdmin() ) return null;
        $perms[&apos;register&apos;] = 1;
        return $perms;
     
    }
}
&lt;/code&gt;

&apos;&apos;&apos;Note that this example is only applicable for Xataface 1.2.5 or higher.  In Xataface 1.2.4 you needed to provide users with the &apos;&apos;new&apos;&apos; permission rather than the &apos;&apos;register&apos;&apos; permission, which opens up a small security hole since users could potentially just use the &quot;new&quot; action if they new the URL and by-pass the registration and activation email altogether&apos;&apos;&apos;.

Some notes on this example:

* The isAdmin() function is not part of Xataface.  It is used as a bit of *magic* here to reduce code.  It is supposed to simply return true if the currently logged in user is an admin.  Hence if the user is an admin, this method defers to the Application Delegate class&apos;s permissions (i.e. this method should not affect administrators).
* We are giving all users (logged in or not) the register permission which enables them to register for an account on the system.
* Generally you will want to restrict permissions on some of the fields in the users table.  E.g. users should not be able to set their role or access level when they register.  You can define more fine-grained permissions on these fields using the [[fieldname__permissions]] method of the users table delegate class (per the following example).

====Restricting Permissions on Particular Fields====

You probably don&apos;t want users to be able to set their access level when the register for an account, and your &quot;users&quot; table will quite often contain some field like &quot;role&quot; which stores this information.  So the previous example is not quite realistic.  You will also need to restrict permissions on the &quot;role&quot; field (and any other fields that you want to prevent users from setting themselves.

&lt;code&gt;
function role__permissions(&amp;$record){
    if ( isAdmin() ) return null;
    return Dataface_PermissionsTool::NO_ACCESS();
}
&lt;/code&gt;

This will cut off the user&apos;s ability to set their own role when they register.  You will likely want to set the default role value either in the mysql table definition or in the [[beforeInsert]] trigger.

===Email Validation===

As mentioned above, registration works by sending an activation email to the address specified in the user&apos;s registration.  This email contains a link back to the &apos;&apos;activate&apos;&apos; action of your Xataface application, which will create the user account and log the user in.  This implies that your &apos;&apos;users&apos;&apos; table must store an email address for your users.  If you add a field named &apos;&apos;email&apos;&apos; to the &apos;&apos;users&apos;&apos; table, Xataface will assume that you mean to use this field as the user&apos;s email address, and thus, for email validation.  However you can override this functionality and use *any* field as an email field by setting the &apos;&apos;email&apos;&apos; directive of the appropriate field in the [[fields.ini file]] for the &apos;&apos;users&apos;&apos; table.

&apos;&apos;&apos;Example: Assigning the my_addr field of the users table to be used for email validation&apos;&apos;&apos;:

In the tables/users/fields.ini file:
&lt;code&gt;
[my_addr]
    email=1
&lt;/code&gt;

====Disabling Email Validation====

99% of the time, email validation is the preferred way of ensuring that people who register are who they say they are.  You may, however, prefer to let users register directly without requiring the email activation step.  You can disable email validation by overriding the &apos;&apos;register&apos;&apos; action in the [[actions.ini file]] as follows:

In your application&apos;s [[actions.ini file]]:
&lt;code&gt;
[register &gt; register]
    email_validation=0
&lt;/code&gt;

After setting this, the user account will automatically be created, and the user logged in upon saving the registration form.

===Triggers: Overriding Registration Workflow===

Xataface provides a number of triggers in the [[Application Delegate Class]] to override and extend the behavior of the user registration and activation process.  For a list of available triggers see [[Application Delegate Class#registration]].


===Preventing Spam with CAPTCHA===

One problem with enabling automatic registration is that it invites SPAM in the form of bots that can learn how to automatically register for user accounts and then leave unwanted input into your application.  The Xataface [[reCAPTCHA module]] allows you to avoid these problems to some extent by forcing users who aren&apos;t logged in to fill a CAPTCHA field in order to successfully submit the form.  This is especially helpful for registration forms.

After installing the [[reCAPTCHA module]] the registration form will include a CAPTCHA field like the one depicted below:

[[Image:http://media.weblite.ca/files/photos/Picture%2038.png?max_width=640]]

For more information about the reCAPTCHA module [[reCAPTCHA module|click here]].
    </content>
	<keywords>registration form, _auth, authentication</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki></record>