page_name,page_id,page_title,content,keywords,language,original_page
Contribute_to_Xataface_Translation_Project,110,"How to Contribute Translations","[[toc]]

==Synopsis==

Xataface stores its translations in INI files in its lang directory, one for each language.  You can develop your own translation by first copying the en.ini file to xx.ini (where xx is the ISO language code for the language you are translating for), then modifying the translations into your target language. '''NOTE: THIS IS NOT THE PREFERRED WAY TO CONTRIBUTE TRANSLATIONS.  PLEASE SEE ""Adding Translations Using Google Spreadsheets"" BELOW'''.

==Anatomy of a Language .INI file==

The language .INI files (e.g. en.ini, es.ini, etc...) consist of key-value pairs, where the key is a unique identifier for a string in Xataface, and the value is the translation.  All language files should contain the same keys, however if you omit a key from your translation, Xataface will just fall back to the default value that is defined in the PHP source code.

===Example Snippet from en.ini file===

<code>
scripts.GLOBAL.FORMS.OPTION_PLEASE_SELECT = ""Please Select ...""
save_button_label = ""Save""
scripts.GLOBAL.MESSAGE.PERMISSION_DENIED = ""Permission Denied""
scripts.GLOBAL.NO_RECORDS_MATCHED_REQUEST = ""No records matched your request.""
</code>

In this small segment you can see 4 strings that are translated.  The values on the left of the equals sign are the keys.  Their corresponding values are on the right of the equals signs.  A corresponding segment of the fr.ini (French) language file looks like:

<code>
scripts.GLOBAL.FORMS.OPTION_PLEASE_SELECT = ""SVP sélectionnez ...""
save_button_label = ""Enregistrer""
scripts.GLOBAL.MESSAGE.PERMISSION_DENIED = ""Permission Refusée""
scripts.GLOBAL.NO_RECORDS_MATCHED_REQUEST = ""Aucun résultat ne correspond à votre requête.""
</code>

You can see that the keys (the values on the left) are identical to those in the en.ini snippet.  Only the values are changed (translated) into French.

'''NOTE: IT IS BETTER TO USE GOOGLE SPREADSHEETS TO EDIT TRANSLATIONS, THAN TO WORK WITH INI FILES DIRECTLY. PLEASE SEE ""Adding Translations Using Google Spreadsheets"" BELOW'''


==Gotchas: Things to watch out for==

When editing or adding translations in INI files, you need to be aware of a few gotchas related to how INI files work.  If you mess up a line by forgetting to add a quote, you could cause a parse error which would cause Xataface to ignore the language file altogether.  The following are a few common pitfalls:

===Use UTF-8 Encoding===

All ini files should use UTF-8 encoding, so make sure you are using a text editor that supports UTF-8 if you want to edit INI files.  (But it is better to just use Google Spreadsheets for the editing if possible, in which case you don't have to worry about this).

===Wrap Translations in Double Quotes===

All translations should be wrapped in double quotes.  E.g.
<code>
mykey=""My Value""
</code>

If you forget to close a quote, it will likely cause a parse error and Xataface will fail to load the file.  E.g.
<code>
mykey=""My Value
</code>
would be a problem.


===Can't Use Double Quotes as Part of the Translation===

Since INI files use double quotes to wrap strings, you can't use a double quote inside your translation.  E.g. you can't do this:
<code>
mylink=""<a href=""http://google.com"">Google</a>""
</code>
because of the inline double quotes.

One way around this is to try to use single quotes where possible.  E.g.
<code>
mylink=""<a href='http://google.com'>Google</a>""
</code>

Another way around this is to the ''""_Q""'' key sequence, which Xataface will
automatically convert to a double quote for you at runtime.  E.g. You could do:
<code>
mylink=""<a href=""_Q""http://google.com""_Q"">Google</a>""
</code>

'''NOTE: If you use Google Spreadsheets to edit your translations, you won't have this problem.  You can use double quotes inside your translations.  The [[csv2ini]] tool will automatically convert these to an appropriate form when the spreadsheet is converted to the INI files.'''


===Leave Variables Alone===

Some translated strings include variables that are meant to be replaced by Xataface at runtime.  These should be left intact across translations.  You can identify a variable by their resemblance to PHP variables (prefixed with a $).

E.g. In the en.ini file, the translation:
<code>
No action found = ""No action found named '$name'""
</code>
has the variable ''$name''.

So the French translation should maintain this variable.  E.g. in the fr.ini file:
<code>
No action found = ""Aucune action nommée '$name'""
</code>


==Adding Translations Using Google Spreadsheets==

In order to help keep translations more up to date, we have developed a set of tools to enable us to use Google Spreadsheets to edit and add translations, and convert these spreadsheets on demand into an appropriate set of language INI files.

The spreadsheet containing the Xataface translations is public to view and is located  [https://spreadsheets.google.com/ccc?key=0AqJNZUI7flxSdFVLWDlnVVpQZ3dMaGZhVjVHN2c3bEE&hl=en here].  If you would like to add your own translations or modify existing translations, please contact [mailto:steve@weblite.ca Steve Hannah] so that you can be given editor permission.  You will first need a google docs account, then we can give you permission to edit the spreadsheet.

This centralized spreadsheet is converted to INI files and merged into SVN before every release.  You can also export this spreadsheet as a CSV and convert it to Xataface's language INI files yourself using the [[csv2ini]] tool that is located in the tools directory of the Xataface distribution.


===Gotchas with Google Spreadsheets===

Editing translations with Google Spreadsheets is much safer than editing the INI files directly.  You don't have to worry about encoding issues, and you don't have to dance around double quotes like you do with INI files.  There is only one known thing to watch out for:

====Starting a translation with a Single Quote====

If you start a translation with a single quote, Google Spreadsheets will interpret this as a directive to indicate that the contents of that cell should be considered a string (and not a number for example).  E.g. If you enter the following into a Google Spreadsheets cell:
<code>
'Help!', I exclaimed
</code>
If you unfocus from that cell it will only say:
<code>
Help!', I exclaimed
</code>
If you go back into edit mode of the cell again, you'll see your opening single quote again... and when you tab out, it will disappear again.  

You can work around this issue by just using two single-quotes for the first quote.  E.g.:
<code>
''Help!', I exclaimed
</code>

This way Google will interpret the first quote as a directive, and it will use the second one as an actual single quote.


====Converting the Google Translation Spreadsheet into INI Files====

So you've contributed a number of translations to the [https://spreadsheets.google.com/ccc?key=0AqJNZUI7flxSdFVLWDlnVVpQZ3dMaGZhVjVHN2c3bEE&hl=en Xataface Translations Google Spreadsheet], and you want to be able to use them in your installation of Xataface before the next release.  Just follow the steps below:

# Download the spreadsheet as a CSV file, using the ''File'' > ''Download as'' > ''CSV (Current Sheet)'' menu item in Google Spreadsheets.
# Run the [[csv2ini]] PHP script located in the xataface/tools directory to convert the xataface-translations.csv file that you downloaded from Google Spreadsheets in the previous step into INI files.  The conversion command looks like:
<code>
$ php /path/to/xataface/tools/csv2ini.php /path/to/xataface-translations.csv /path/to/destination/dir/
</code>

This will convert the xataface-translations.csv file into a set of language INI files and place them the specified destination directory  (don't forget the trailing slash) on /destination/dir so that the script knows its a directory.  You can then copy these INI files into your xataface/lang directory to make them live.

'''Note: the [[csv2ini]] script has only been used in a unix/os x type environment.  Some small modifications would probably be necessary to make them work on Windows.'''




","Translations, Google Spreadsheets, en.ini, fr.ini",en,
Module_Developers_Guide,112,"Module Developers Guide","[[toc]]

==Why Write a Xataface Module?==

Xataface modules are components that can be used to extend Xataface's functionality in a generic way so that it can be used on multiple applications.  If you find yourself trying to add the same functionality in multiple applications, you might consider writing a Xataface module so that you can share the functionality more easily.

==What can you do with a Xataface Module==

* Create custom authentication handlers.
* Provide custom actions and templates.
* Implement blocks and slots for existing templates.
* Respond to certain application triggers.


==Where do I place a Xataface Module?==

Xataface modules can be placed in the xataface/modules directory (i.e. DATAFACE_PATH/modules).  As of Xataface 1.3 they can also be placed directly in your application's modules directory (i.e. DATAFACE_SITE_PATH/modules).

==Your first module==

For our first module, we're going to create a simple module that adds ""hello world"" at the beginning of every page.

===Step 1: Create the Module Class===

In your modules directory, create a directory called ""Hello"".  And in this directory, create a file named ""Hello.php"", with the following contents:
<code>
<?php
class modules_Hello  {
}
</code>
(So this file would be located at DATAFACE_PATH/modules/Hello/Hello.php)

===Step 2: Implement the block__before_body method===

We are going to add the phrase ""hello world"" before every page of our application.  The easy way to do this is to fill the [[before_body]] slot of the [[Dataface_Main_Template.html]] template.  We do this by implementing the ''block__before_body'' method in your module (just as we would if we were trying to fill this slot from the [[Application Delegate Class]].

<code>
<?php
class modules_Hello  {
    function block__before_body(){
        echo ""hello world"";
        return true;
    }
}
</code>

===Step 3: Activate the Module===

Xataface only loads the modules that have been enabled in the conf.ini.  We can enable our module by adding the following section to the [[conf.ini file]]:

<code>
[_modules]
modules_Hello=modules/Hello.php
</code>

All this does is tell Xataface that the module class modules_Hello can be loaded from the location modules/Hello.php.

Now if you start up your application, you should see the phrase ""hello world"" written at the top of each page.


==Example 2: Adding a Custom Action==

Our first module shows an example of filling blocks and slots using a module.  Let's now extends that to include a custom action that displays Hello World on its own page.

Complete the following steps:

# Add an ''actions'' directory inside our new module directory.  i.e. modules/Hello/actions
# Add a file named hello.php inside the ''actions'' directory with the following contents:<code>
<?php
class actions_hello {
    function handle($params){
        echo ""Hello World"";
    }
}
</code>
# Go to index.php?-action=hello To see the results of your action.  It should say ""Hello World"" on a blank page.

From here on you can improve this action just as you would if you defined the action inside the application's actions directory.  You can go on to restrict access to this action using permissions, or you could decide to use a template to display the action.

===Defining a Custom ""hello"" permission for our action===

Perhaps we want to create a special permission for our action so that regular users won't have access to this action unless they are specifically granted this permission.  Let's create a ""hello"" permission with which to limit access to our action.

# Create a file named ""permissions.ini"" inside your modules/Hello directory with the following contents:<code>
hello = Permission to access the hello action
</code>

Now if you try to access your action (and you haven't been assigned ALL() permissions) you should receive either a login prompt or a permission denied message.

If you want users to be able to access your action, you will need to explicitly add this permission to one of the user's assigned roles or return it as part of the list of authorized permissions in the getPermissions() method.

===Granting the ""hello"" permission to the ""READ ONLY"" role===

If we want the default READ ONLY role to have access to the ""hello"" permission we can actually modify the READ ONLY role inside the [[permissions.ini file]] that we created inside the Hello module:

<code>
hello = Permission to access hello action

[READ ONLY extends READ ONLY]
    hello=1
</code>


==Example 3: Using Module Templates==

Xataface, by default, stores its templates in the DATAFACE_SITE_PATH/templates and DATAFACE_PATH/templates directories.  However if you are writing a module you probably want to keep templates that are used by the module inside the module directory so that you don't break dependencies when you use the module in different applications.

You can use the [http://dataface.weblite.ca/df_register_skin df_register_skin] method to register additional directories for Xataface to look for templates in.  This will allow you to add a ''templates'' directory inside your module directory for use by your module's templates.

It is probably best to register this directory on demand (i.e. as part of individual actions) rather than register it globally.  

===Using a Template from the hello action===

Let's modify our hello action to use a template that we are going to store and distribute with our module.

# Create a directory named ""templates"" in the modules/Hello directory.
# Create a file named ""hello.html"" inside the templates directory with the following contents:<code>
{use_macro file=""Dataface_Main_Template.html""}
    {fill_slot name=""main_section""}
    	Hello World
    {/fill_slot}
{/use_macro}
</code>  Notice that we are extending the Dataface_Main_Template.html template (which is located in the main Xataface install) so that our hello action can now take on the look and feel of the rest of the application.
# Modify the modules/Hello/actions/hello.php file to look like this:<code><?php
class actions_hello {
    function handle($params){
        df_register_skin('hello theme', dirname(__FILE__).'../templates');
        df_display(array(), 'hello.html');
    }
}
</code>  Notice that we call the df_register_skin function to register the templates directory that we created in the previous step.  Then we call df_display() to display the template.



==See Also===

* [[modules]] - A list of existing Xataface modules that you can download and install.
* [[block__blockname]] - A list of some of the available blocks that can be filled in the default Xataface templates.
* [http://xataface.com/documentation/tutorial/customizing-the-dataface-look-and-feel Customizing Xataface's Look and Feel with Templates] - A tutorial on how to use Xataface's built-in smarty template engine.  It has some sections on using delegate classes to override blocks and slots.
* [http://xataface.com/documentation/tutorial/getting_started/changing-look-and-feel Changing Xataface's Look and Feel] - Part of the Getting Started tutorial that shows how to use slots and blocks to customize the Xataface look and feel.",modules,en,
field__pullValue,104,"field__pullValue delegate class method","[[toc]]

The field__pullValue() delegate class method can be used to transform database from the database for use in an edit/new record form.  Sometimes it is the case that we want users to be able to work with data differently than it is stored in the database.

This method should always be accompanied by a corresponding [[field__pushValue]] method which performs the inverse operation and is used to transform the value in an edit form into a format that can be stored in the database.

===Example===

Given a field ''start_ip'' that stores an IP address in the database as an unsigned INT, we want to be able to work with the data on the edit form in a friendlier format - the standard IP address dot notation, so we define pullValue and pushValue methods for the field in the table's delegate class.

<code>
class tables_ip_blocks {

	/**
	 * @param Dataface_Record $record The record we are pushing the value
	 *		into
	 * @param HTML_QuickForm_element $el The QuickForm widget that we are 
	 *      retrieving the value from.
	 */
	function start_ip__pushValue($record, $el){
		$val = ip2long($el->getValue());
		if ( $val !== false ){
			return sprintf('%u', $val );
		}
		return null;
	}
	
	function start_ip__pullValue($record, $el){
		$val = $record->val('start_ip');
		if ( $val )
			return long2ip($val);
		return $val;
	}
}
</code>

==References==

* [[Delegate class methods]]
* [[Application Delegate Class]]
* [[http://dataface.weblite.ca/Dataface_Record Dataface_Record API docs]
* [http://xataface.com/documentation/how-to/how-to-define-custom-serialization-for-fields How to define custom serialization for fields] - A how-to document.
","pushValue, pullValue",en,
field__pushValue,105,,"[[toc]]

The field__pushValue() delegate class method can be used to transform a field value as entered in the edit form into a format that can be stored in the database..  Sometimes it is the case that we want users to be able to work with data differently than it is stored in the database.

This method should always be accompanied by a corresponding [[field__pullValue]] method which performs the inverse operation and is used to transform the value in the database into a format that can be edited in the edit form.

===Example===

Given a field ''start_ip'' that stores an IP address in the database as an unsigned INT, we want to be able to work with the data on the edit form in a friendlier format - the standard IP address dot notation, so we define pullValue and pushValue methods for the field in the table's delegate class.

<code>
class tables_ip_blocks {

	/**
	 * @param Dataface_Record $record The record we are pushing the value
	 *		into
	 * @param HTML_QuickForm_element $el The QuickForm widget that we are 
	 *      retrieving the value from.
	 */
	function start_ip__pushValue($record, $el){
		$val = ip2long($el->getValue());
		if ( $val !== false ){
			return sprintf('%u', $val );
		}
		return null;
	}
	
	function start_ip__pullValue($record, $el){
		$val = $record->val('start_ip');
		if ( $val )
			return long2ip($val);
		return $val;
	}
}
</code>

==References==

* [[Delegate class methods]]
* [[Application Delegate Class]]
* [[http://dataface.weblite.ca/Dataface_Record Dataface_Record API docs]
* [http://xataface.com/documentation/how-to/how-to-define-custom-serialization-for-fields How to define custom serialization for fields] - A how-to document.
","pullValue, pushValue",en,
loginFailed,184,"loginFailed() Application Delegate Trigger","[[toc]]

The loginFailed() method of the Application Delegate class is executed after a failed login attempt.

'''Available since 2.0.1'''

==Example==

<code>
function loginFailed($username, $userIp, $time){
    error_log(""Failed login for username: $username at IP $userIp at time $time"");
}
</code>
","login permissions failed password",en,
XataJax,113,"Introduction to XataJax","[[toc]]

Xataface 1.3 comes with a new module [[XataJax]] which comes installed standard.  [[XataJax]] serves as a foundation for Javascript/AJAX powered Xataface applications and will hopefully usher in a new fresh generation of Xataface powered applications.

===Features===

Xataface provides pieces of infrastructure:

# [[XataJax Compiler|A Javascript/CSS Compiler & Linker]]
# A Javascript component library & API

====The Javascript/CSS Compiler & Linker====

Web 2.0 and HTML 5 is a great platform for application development, but it presents a challenge when it comes to developing large-scale, robust applications.  It can be difficult to manage applications that consist of dozens or even hundrends of javascript libraries, some of which depend on each other.

The XataJax compiler provides a solution to this problem by providing a just-in-time compilation of all of the javascripts that are necessary to service a particular request.  It doesn't actually compile your Javascript into machine code, it just aggregates and minifies all of the javascript code together into a single file at runtime so that you don't have to worry about figuring out exactly which libraries you need to import in each template.

This has 2 key benefits:

1. Load time.  By having all of the scripts grouped into a single file, it is much quicker for the client to load the your scripts.

2. Code organization.  Since the compiler will automatically resolve the script dependencies, you can keep your code nicely organized, which produces a far more maintainable source code base.


====The Javascript Component Library & API====

The 2nd part of the XataJax module is a new API that will help you develop rich Web 2.0 applications that interact with your database.  The will allow you to build forms more dyanmically with Javascript, or load, update, and delete records directly using a javascript API.  

The goal is to eventually expose all important Xataface functionality via the XataJax API.

Additional modules may build on top of this API to produce alternative dynamic interfaces for Xataface using existing web UI component libraries like JQueryUI or Sencha.","XataJax, Ajax, Web 2.0",en,
blob,55,blob,,,en,0
struct,56,struct,,,en,0
widget:type_textarea,60,widget:type_textarea,,,en,0
Internet_Media_Manager,8,"Internet Media Manager","'''Manage your videos and photos all in one place'''

[[toc]]

===Watch the Guided Tour (6 minutes)===
<nowiki>
<embed src=""http://media.weblite.ca/lib/flvplayer.swf"" width=""640"" height=""448"" bgcolor=""#FFFFFF"" type=""application/x-shockwave-flash"" pluginspage=""http://www.macromedia.com/go/getflashplayer"" flashvars=""file=http%3A%2F%2Fs3.amazonaws.com%2Fweblite_media%2Fintro_video.flv&image=http%3A%2F%2Fmedia.weblite.ca%2Ffiles%2Fphotos%2Fintro_video.flv.AbpY0Y.jpg&showdigits=true&autostart=false"" />
</nowiki>

===Introduction===

The Internet Media Manager is a web-based database application that allows webmasters to centrally store their images and videos to be served on their website(s).  It provides a Youtube-like interface whereby users can simply copy and paste code snippets to embed images and videos into their web pages.  It also provides a photo gallery component that allows users to easily embed a gallery of images into their web pages by simply copying and pasting a snippet of javascript code.

===Purpose===

I created this application because:

# I didn't want to have to resize images in Photoshop anymore before uploading them to the web.
# I wanted to be able to embed videos, images, and photo galleries into my web pages without having to muck around with HTML code.

IMM (Internet Media Manager) allows you to resize your photos to any size you want, and embed these resized images in your web pages by copying and pasting a snippet of HTML.  Similarly it makes embedding videos and photo galleries into your website a snap.

===Features===

* Add/Edit/Delete/Categorize images and videos in a searchable database.
* Import multiple images or videos at once by uploading a ZIP file.
* Large file imports via FTP/SSH.
* Embed video and images directly into other web pages by copying and pasting HTML snippets (like Youtube).
* Resize images and videos.
* FLV video support (like Youtube).
* Search media by content type, category, keyword, etc..
* Includes javascript photo gallery component that can be embedded into any web page.
* Amazon Simple Storage Service (S3) integration.

===Requirements===

* [http://www.php.net|PHP] 5.2+
* [http://www.mysql.com|MySQL] 4.1+
* [http://ca.php.net/gd|GD_Image_Processing_Library]
* [http://ffmpeg.mplayerhq.hu/|FFMPEG] (optional - if you want to automatically generate poster images for videos).

===Download===

* [https://sourceforge.net/projects/immgr/files/|Internet Media Manager 0.3]

===Installation===

# Download the latest version from Sourceforge.
# Extract the files and copy to your web server.
# Point your web browser to the install.php and follow the instructions. 

===Screenshots===

<nowiki>
<script language=""javascript"" type=""text/javascript"" src=""http://media.weblite.ca/index.php?-action=gallery&-table=files&categories=3&-cursor=0&-skip=0&-limit=30&-mode=list&-photo_max_width=500&--format=js""></script>
<div style=""clear:both""></div>
</nowiki>

===Screencasts===

How to import multiple images at once in a ZIP archive.

<nowiki><iframe title=""YouTube video player"" width=""640"" height=""510"" src=""http://www.youtube.com/embed/0gfRJ5HkRsI"" frameborder=""0"" allowfullscreen></iframe></nowiki>

===Support===

Visit the [http://xataface.com/forum/viewforum.php?f=12|Support_forum].
","Internet Media Manager,resize photos,image gallery,photo gallery,video gallery",en,0
How_to_build_a_PHP_MySQL_Application_with_4_lines_of_code,38,"How to build a PHP MySQL Application with 4 lines of code","'''The [http://xataface.com Xataface Application Framework] allows you to convert your existing MySQL database into a full-fledged with as little as 4 lines of code.  And it's Not a code generator.'''

[[toc]]

This article is intended to spark interest in the [http://xataface.com Xataface Application Framework] amongst PHP developers by showing how easy it is to set up a full-featured front-end for your MySQL database.  If you are a PHP developer, surly you can identify with the situation where you've built a snazzy website with PHP and MySQL but you need to create some way the website users to administer it.  I.e., you need to make an administrative back-end for your users.

You need to do this because PHP admin is too technical for your users, and it is an aweful lot of tedious work to create all of the necessary forms and lists for your users to edit the data themselves.

===Features for our Application===

* Create, edit and delete records using simple web forms.
* Browse through database and find records without any SQL.
* Lots of great widgets for editing records including html editors, select lists, grids, checkboxes, calendars and more.
* Sort records.
* Export result sets as CSV or XML.
* Fully configurable and extendable by you to implement more [[about|features]].

===Creating the Application===

Here are 6 steps to a full-featured front-end for your database:

# Create a directory for your application on your webserver.  Call it ''myapp''.
# Download the latest version of [http://xataface.com Xataface] and copy it into your application directory that we just created.  (i.e. ''myapp/xataface''.
# Create a configuration file named ''conf.ini'' inside your application directory (i.e. ''myapp/conf.ini'') to store your database connection info:<code>
[_database]
    host=localhost
    name=mydb
    user=username
    password=mypass

[_tables]
    ;; This section lists the tables to include in your application menu
    table1=Label for table 1
    table2=Label for table 2
</code>
# Create an .htaccess (i.e. ''myapp/.htaccess'') file to prevent Apache from serving your ''conf.ini'' file:<code>
<FilesMatch ""\.ini$"">
Deny from all
</FilesMatch>
</code>  '''Note:  If you are not using Apache as your web server you'll need to block access to the .ini files using a different mechanism.  E.g. On IIS you can create a Web.config file to block this access and place it inside your application's directory.'''  Download a sample Web.config file [http://weblite.ca/svn/dataface/core/trunk/site_skeleton/Web.config here].
# Create an index.php file (i.e. ''myapp/index.php'') to serve as an access point for your application:<code>
<?php
// Include the Xataface API
require_once 'xataface/dataface-public-api.php';

// Initialize Xataface framework
df_init(__FILE__, 'xataface')->display();
    // first parameter is always the same (path to the current script)
    // 2nd parameter is relative URL to xataface directory (used for CSS files and javascripts)
</code>
# Create a ''templates_c'' directory to store cached smarty templates or your application (i.e. ''myapp/templates_c'', and make sure that it is writable by the webserver:
 $ mkdir templates_c
 $ chmod 777 templates_c


That's all there is to it!  Point your web browser to the index.php file we just made, and check out your new app!

===Screenshots of Our App===

====Find Form====

[[Image:http://media.weblite.ca/files/photos/people-find.png?max_width=400]]

====New Record Form====

[[Image:http://media.weblite.ca/files/photos/people-new-record.png?max_width=400]]

====List View====

[[Image:http://media.weblite.ca/files/photos/people-list.png?max_width=400]]

===Where to go now===

# Sign up for the Xataface mailing list to receive exclusive development tips (see the left column for a signup form).
# Check out the [[about|About Xataface]] page for more information about features and requirements.
# Use the [http://xataface.com/documentation/getting_started Getting Started Tutorial] to get started making your own application.
# [http://xataface.com/videos Watch screencasts] showing Xataface in action.



","tutorial, getting started, installation, first app, 4 lines of code",en,0
_output_cache,45,"The Xataface Output Cache","<nowiki><div class=""portalMessage"">Note: There was a bug in the output cache affecting Xataface version 1.0 to 1.3rc1.  If you are using a version of Xataface older than 1.3rc2 then you should either disable the output cache, or replace the Dataface/OutputCache.php file with one from a newer version.</div></nowiki>

[[toc]]

Xataface does quite a bit of heavy lifting on each page request.  If your application is getting a lot of traffic that is slowing your server down, you may want to look at enabling the Xataface output cache.

===Features===

* Improve speed of application dramatically - especially for seldom updated sites.
* Supports multiple languages.
* Supports multiple users (each user has own cache).
* Provides GZIP compression for improved performance.

===How it works?===

When you receive a request, Xataface will return a cached version of the page if the page has been accessed before.  If the page doesn't yet exist in the cache it generates the page, saves it to the cache and outputs it to the user transparently.  The cache is completely transparent to your users.

===Where is the cache stored?===

Xataface creates a table called ''__output_cache'' that stores all of the cached content for your application.  This table stores both a GZIPed and regular version of each page.  If the user's browser supports GZIP compression, Xataface will automatically return the GZIP version.  This results in further performance improvements.

===What if I make changes to the database?===

Xataface records which tables were in use when a page is cached.  If any of those tables are modified after the page is cached, Xataface will mark that cached page as ''out of date'' and regenerate it the next time that it is requested.

===What if I make changes to my configuration files and templates?===

The output cache will have to be manually cleared if you make any changes to your source files (e.g. PHP, templates, and INI files).  Clearing the cache is as easy as deleting or emptying the ''__output_cache'' table.

===How do I enable the Cache?===

Add the following to your [[conf.ini file]]:

<code>
[_output_cache]
    enabled=1
</code>

===How do I disable the Cache?===

Simply comment out or remove the ''[_output_cache]'' section of your [[conf.ini file]].  E.g.
<code>
;[_output_cache]
;   enabled=1
</code>

===Configuration Options===

The following directives can be added to the ''[_output_cache]'' section of your [[conf.ini file]] to customize how your output cache works.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| lifeTime
| Number of seconds before cached page is considered ''out of date''.
| 0.7
|-
| tableName
| The name of the table to store the cached pages.  Default '__output_cache'.
| 0.7
|-
| ignoredTables
| A comma-delimited list of tables that don't affect the output cache (i.e. these tables can be changed without causing the output cache to be refreshed.
| 0.7
|-
| observedTables
| A comma-delimited list of tables that should affect the status of the output cache for every page (whether the table is explicitly used by the page or not).  This is a useful way to tell Xataface to refresh your cache.
| 0.7
|-
| exemptActions
| A comma-delimited list of actions that are exempt from the output cache (and thus should not be cached).
| 0.7
|}","output cache",en,0
block__blockname,11,block__blockname,"===Available Blocks===

This is a grep to show the blocks that are defined in Xataface templates:

* Dataface_ActionsMenu.html:actions_menu_head
* Dataface_ActionsMenu.html:actions_menu_tail
* Dataface_Add_Existing_Related_Record.html:before_add_existing_related_record_form
* Dataface_Add_Existing_Related_Record.html:before_add_existing_related_`$ENV.relationship`_form
* Dataface_Add_Existing_Related_Record.html:after_add_existing_related_`$ENV.relationship`_form
* Dataface_Add_Existing_Related_Record.html:after_add_existing_related_record_form
* Dataface_Add_New_Related_Record.html:before_add_new_related_record_form
* Dataface_Add_New_Related_Record.html:before_add_new_related_`$ENV.relationship`_form
* Dataface_Add_New_Related_Record.html:after_add_new_related_`$ENV.relationship`_form
* Dataface_Add_New_Related_Record.html:after_add_new_related_record_form
* Dataface_AjaxEventDetails.html:before_event_details
* Dataface_AjaxEventDetails.html:after_event_details
* Dataface_Delete_Record.html:before_delete_record_form
* Dataface_Delete_Record.html:after_delete_record_form
* Dataface_Edit_Record.html:before_edit_record_form
* Dataface_Edit_Record.html:after_edit_record_form
* Dataface_FindForm.html:findform_before_`$element.field.name`_row
* Dataface_FindForm.html:findform_before_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_row
* Dataface_FindForm.html:before_findform_table
* Dataface_FindForm.html:findform_before_`$element.field.name`_row
* Dataface_FindForm.html:findform_before_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_row
* Dataface_FindForm.html:after_findform_table
* Dataface_Find_View.html:before_find_form
* Dataface_Find_View.html:after_find_form
* Dataface_Form_Section_Template.html:before_quickform_table
* Dataface_Import_RelatedRecords.html:before_import_related_records_form
* Dataface_Import_RelatedRecords.html:before_import_related_`$ENV.relationship`_form
* Dataface_Import_RelatedRecords.html:after_import_related_`$ENV.relationship`_form
* Dataface_Import_RelatedRecords.html:after_import_related_records_form
* Dataface_List_View.html:before_result_list
* Dataface_List_View.html:after_result_list
* Dataface_Login_Prompt.html:before_login_form
* Dataface_Login_Prompt.html:after_login_form
* Dataface_Main_Template.html:custom_stylesheets2
* Dataface_Main_Template.html:head
* Dataface_Main_Template.html:body_atts
* Dataface_Main_Template.html:before_body
* Dataface_Main_Template.html:before_header
* Dataface_Main_Template.html:after_header
* Dataface_Main_Template.html:before_search
* Dataface_Main_Template.html:after_search_form_submit
* Dataface_Main_Template.html:after_search
* Dataface_Main_Template.html:before_nav_menu
* Dataface_Main_Template.html:after_nav_menu
* Dataface_Main_Template.html:before_language_selector
* Dataface_Main_Template.html:after_language_selector
* Dataface_Main_Template.html:before_user_status_logged_in
* Dataface_Main_Template.html:after_user_status_logged_in
* Dataface_Main_Template.html:before_user_status_not_logged_in
* Dataface_Main_Template.html:after_user_status_not_logged_in
* Dataface_Main_Template.html:before_personal_tools
* Dataface_Main_Template.html:after_personal_tools
* Dataface_Main_Template.html:before_bread_crumbs
* Dataface_Main_Template.html:after_bread_crumbs
* Dataface_Main_Template.html:before_main_table
* Dataface_Main_Template.html:before_left_column
* Dataface_Main_Template.html:before_record_tree
* Dataface_Main_Template.html:after_record_tree
* Dataface_Main_Template.html:before_nav_menu
* Dataface_Main_Template.html:after_nav_menu
* Dataface_Main_Template.html:before_application_menu
* Dataface_Main_Template.html:after_application_menu
* Dataface_Main_Template.html:after_left_column
* Dataface_Main_Template.html:before_main_column
* Dataface_Main_Template.html:before_message
* Dataface_Main_Template.html:message
* Dataface_Main_Template.html:after_message
* Dataface_Main_Template.html:before_errors
* Dataface_Main_Template.html:error
* Dataface_Main_Template.html:after_errors
* Dataface_Main_Template.html:before_table_tabs
* Dataface_Main_Template.html:before_menus
* Dataface_Main_Template.html:after_menus
* Dataface_Main_Template.html:before_main_section
* Dataface_Main_Template.html:before_recently_viewed
* Dataface_Main_Template.html:after_recently_viewed
* Dataface_Main_Template.html:before_record_content
* Dataface_Main_Template.html:after_record_content
* Dataface_Main_Template.html:after_main_section
* Dataface_Main_Template.html:before_fineprint
* Dataface_Main_Template.html:after_fineprint
* Dataface_Main_Template.html:before_global_footer
* Dataface_Main_Template.html:after_global_footer
* Dataface_Main_Template.html:before_main_section
* Dataface_Main_Template.html:before_recently_viewed
* Dataface_Main_Template.html:after_recently_viewed
* Dataface_Main_Template.html:before_record_content
* Dataface_Main_Template.html:after_record_content
* Dataface_Main_Template.html:after_main_section
* Dataface_NavMenu.html:tables_menu_head
* Dataface_NavMenu.html:tables_menu_tail
* Dataface_NavMenu.html:tables_menu_head
* Dataface_NavMenu.html:tables_menu_tail
* Dataface_New_Record.html:before_new_record_form
* Dataface_New_Record.html:after_new_record_form
* Dataface_Record_Template.html:before_details_controller
* Dataface_Record_Template.html:after_details_controller
* Dataface_Record_Template.html:before_record_heading
* Dataface_Record_Template.html:after_record_heading
* Dataface_Record_Template.html:before_record_tabs
* Dataface_Record_Template.html:before_record_content
* Dataface_Record_Template.html:after_record_content
* Dataface_Record_Template.html:before_record_footer
* Dataface_Record_Template.html:after_record_footer
* Dataface_Registration.html:before_registration_form
* Dataface_Registration.html:after_registration_form
* Dataface_Related_Records_List.html:before_related_`$ENV.relationship`_records_list
* Dataface_Related_Records_List.html:after_related_`$ENV.relationship`_records_list
* Dataface_Remove_Related_Record.html:before_remove_related_record_form
* Dataface_Remove_Related_Record.html:before_remove_related_`$ENV.relationship`_record_form
* Dataface_Remove_Related_Record.html:after_remove_related_`$ENV.relationship`_record_form
* Dataface_Remove_Related_Record.html:after_remove_related_record_form
* Dataface_View_Record.html:before_view_tab_content
* Dataface_View_Record.html:before_record_actions
* Dataface_View_Record.html:after_record_actions
* Dataface_View_Record.html:after_view_tab_content
* Dataface_related_records_checkboxes.html:before_related_`$ENV.relationship`_records_checkboxes
* Dataface_related_records_checkboxes.html:before_related_records_checkboxes
* Dataface_related_records_checkboxes.html:after_related_records_checkboxes
* Dataface_related_records_checkboxes.html:after_related_`$ENV.relationship`_records_checkboxes
* Dataface_set_translation_status.html:before_details_controller
* Dataface_set_translation_status.html:after_details_controller

===Available Slots===

* Dataface_ActionsMenu.html:actions_menu
* Dataface_Add_Existing_Related_Record.html:add_existing_related_`$ENV.relationship`_form
* Dataface_Add_Existing_Related_Record.html:add_existing_related_record_form
* Dataface_Add_New_Related_Record.html:add_new_related_`$ENV.relationship`_form
* Dataface_Add_New_Related_Record.html:add_new_related_record_form
* Dataface_AjaxEventDetails.html:event_details
* Dataface_Delete_Record.html:delete_record_form
* Dataface_Edit_Record.html:edit_record_form
* Dataface_FindForm.html:findform_`$element.field.name`_row
* Dataface_FindForm.html:findform_`$element.field.name`_widget
* Dataface_FindForm.html:findform_`$element.field.name`_row
* Dataface_FindForm.html:findform_`$element.field.name`_widget
* Dataface_Find_View.html:find_form
* Dataface_Import_RelatedRecords.html:import_related_`$ENV.relationship`_form
* Dataface_Import_RelatedRecords.html:import_related_records_form
* Dataface_List_View.html:result_list
* Dataface_List_View_summary.html:result_list
* Dataface_Login_Prompt.html:login_form
* Dataface_Main_Template.html:doctype_tag
* Dataface_Main_Template.html:html_tag
* Dataface_Main_Template.html:html_head
* Dataface_Main_Template.html:html_title
* Dataface_Main_Template.html:dataface_stylesheets
* Dataface_Main_Template.html:custom_stylesheets
* Dataface_Main_Template.html:dataface_javascripts
* Dataface_Main_Template.html:custom_javascripts
* Dataface_Main_Template.html:head_slot
* Dataface_Main_Template.html:html_body
* Dataface_Main_Template.html:global_header
* Dataface_Main_Template.html:search_form
* Dataface_Main_Template.html:language_selector
* Dataface_Main_Template.html:user_status_logged_in
* Dataface_Main_Template.html:user_status_not_logged_in
* Dataface_Main_Template.html:personal_tools
* Dataface_Main_Template.html:bread_crumbs
* Dataface_Main_Template.html:main_table
* Dataface_Main_Template.html:left_column
* Dataface_Main_Template.html:application_menu
* Dataface_Main_Template.html:main_column
* Dataface_Main_Template.html:table_tabs
* Dataface_Main_Template.html:menus
* Dataface_Main_Template.html:main_section
* Dataface_Main_Template.html:record_content
* Dataface_Main_Template.html:fineprint
* Dataface_Main_Template.html:global_footer
* Dataface_Main_Template.html:main_section
* Dataface_Main_Template.html:record_content
* Dataface_Main_Templateold.html:doctype_tag
* Dataface_Main_Templateold.html:html_tag
* Dataface_Main_Templateold.html:html_head
* Dataface_Main_Templateold.html:html_title
* Dataface_Main_Templateold.html:dataface_stylesheets
* Dataface_Main_Templateold.html:custom_stylesheets
* Dataface_Main_Templateold.html:dataface_javascripts
* Dataface_Main_Templateold.html:custom_javascripts
* Dataface_Main_Templateold.html:head_slot
* Dataface_Main_Templateold.html:html_body
* Dataface_Main_Templateold.html:global_header
* Dataface_Main_Templateold.html:search_form
* Dataface_Main_Templateold.html:language_selector
* Dataface_Main_Templateold.html:user_status_logged_in
* Dataface_Main_Templateold.html:user_status_not_logged_in
* Dataface_Main_Templateold.html:personal_tools
* Dataface_Main_Templateold.html:bread_crumbs
* Dataface_Main_Templateold.html:main_table
* Dataface_Main_Templateold.html:left_column
* Dataface_Main_Templateold.html:application_menu
* Dataface_Main_Templateold.html:main_column
* Dataface_Main_Templateold.html:table_tabs
* Dataface_Main_Templateold.html:menus
* Dataface_Main_Templateold.html:main_section
* Dataface_Main_Templateold.html:record_content
* Dataface_Main_Templateold.html:fineprint
* Dataface_Main_Templateold.html:global_footer
* Dataface_Main_Templateold.html:main_section
* Dataface_Main_Templateold.html:record_content
* Dataface_NavMenu.html:tables_menu_options
* Dataface_NavMenu.html:tables_menu_options
* Dataface_New_Record.html:new_record_form
* Dataface_Record_Template.html:record_heading
* Dataface_Record_Template.html:record_content
* Dataface_Record_Template.html:record_footer
* Dataface_Registration.html:registration_form
* Dataface_Related_Records_List.html:before_related_list
* Dataface_Related_Records_List.html:related_`$ENV.relationship`_records_list
* Dataface_Related_Records_List.html:related_records_list
* Dataface_Related_Records_List.html:after_related_list
* Dataface_Remove_Related_Record.html:remove_related_`$ENV.relationship`_record_form
* Dataface_Remove_Related_Record.html:remove_related_record_form
* Dataface_View_Record.html:view_tab_content
* Dataface_View_Record.html:record_actions
* Dataface_View_Record.html:record_search
* Dataface_View_Record.html:`$section.name`_section_content
* Dataface_View_Record.html:record_view_main_section
* Dataface_View_Record.html:`$section.name`_section_content
* Dataface_related_records_checkboxes.html:related_`$ENV.relationship`_records_checkbox_form
* Dataface_related_records_checkboxes.html:related_records_checkbox_form
* global_header.html:site_logo

",,en,0
about,36,about,"==About Xataface==

[[toc]]

Xataface is a flexible and shapable skin that sits on top of MySQL, making it accessible to every-day users. It automatically generates the appropriate forms, lists, and menus for a user to interact with the database without having to know any SQL. 

It is a full-featured Web application framework, and gives developers the flexibility to customize the features and behavior of their application via configuration files (using the simple INI-file syntax), templates, and plug-ins. A generic application with no customizations is completely functional, but the developer is free to customize things at his leisure.

===Who is Xataface for?===

Xataface is for web developers and database administrators who would like to build a front-end for their MySQL database.  However the resulting applications are targeted at non-technical users such as secretaries.

===Requirements===

====Xataface 1.1.x and below:====

* MySQL 3.23+
* PHP 4+

Some advanced features require MySQL version 4.1 or higher.

====Xataface 1.2 and higher====

* MySQL 3.23+
* PHP 5+

Some advanced features require MySQL version 5 or higher.

===At a Glance: Your first App===

# Create a directory for your app.
# Copy the ''xataface'' directory inside your application directory.
# Create a configuration file named ''conf.ini'' in your application directory with your database settings:<code>
[_database]
    host=localhost
    name=mydb
    user=me
    password=mypass

[_tables]
    ; A list of tables to include in your application's menu
    ; These tables must already exist in your database
    people=Profiles
    news=News Articles
</code>
# Create an .htaccess file in your application directory to prevent access to your ''conf.ini'' file:<code>
<FilesMatch ""\.ini$"">
Deny from all
</FilesMatch>
</code>
# Create a PHP script in your application directory as an access point for your app.  We'll call it ''index.php'':<code style=""php"">
<?php
// Include the Xataface API
require_once 'xataface/dataface-public-api.php';

// Initialize Xataface framework
df_init(__FILE__, 'xataface');
    // first parameter is always the same (path to the current script)
    // 2nd parameter is relative URL to xataface directory (used for CSS files and javascripts)

// Create a new application
$app =& Dataface_Application::getInstance();

// Display the application
$app->display()
</code>
# You're done.  Your app is ready to use!

This is just the beginning, though.  There is no limit to the customizations you can make on your application.

Read the [http://xataface.com/documentation/tutorial/getting_started Getting Started Tutorial] for more information on developing applications with Xataface.


===Product Comparison===

Xataface fits a niche that is not well covered by existing apps/frameworks.  Xataface is '''NOT''':

* A database administration system like PHPMyAdmin
* Simply a software library/Framework like PHPCake
* Simply a content management system like Drupal
* A code generator

Xataface is a framework, but it is not a typical framework.  Most frameworks require a substantial amount of development before you get a usable application.  Xataface, on the other hand, provides you with a fully-functional application with as little as 4 lines of PHP code.  It doesn't generate any code so it is easy to maintain your application and expand on it later.

As a development framework, Xataface most closely resembles Django, a python framework for building data-driven applications.  As an application, Xataface most closely resembles Filemaker, a popular relational database that makes it easy for the end user to create layouts and manage their data.

===Features===

====General====

* '''Out-of-the-box Database Front-end''' - With as little as 4 lines of PHP code, you can have a full-featured web application for your database.
* '''Simple, Intuitive User interface''' - Default application is consistent and simple to use.  There is a 'tables' menu, to select a table, and each table has ""details"", ""list"", and ""find"" tabs.  Very easy to navigate.
* '''Powerful configuration options''' - You can configure your application details (such as widget types) using simple configuration files.
* '''Extendible''' - You can modify your application as you see fit using configuration files and PHP delegate classes.
* '''Hooks''' - By observing simple conventions you can extend Xataface's functionality with hooks, triggers, and events.  E.g. add a function that is called after a record is inserted.
* '''Permissions''' - Powerful, pluggable permissions system.
* '''Authentication''' - Provides login/logout ability.  You just specify which table your users are stored in.
* '''Relationships''' - Tell Xataface how your tables are related to one another and it will provide you with more logical functionality for managing your data.
* '''Themeable''' - Xataface uses the Smarty template engine as a base, but extends it with some powerful new features such as extendable templates and theming support.
* '''Modular''' - There are several add-on modules available to extend the features of Xataface even further, and a simple API for writing your own modules.


====Editing====

* '''Automatic Form Generation''' - Automatically generates appropriate web forms to add new records and edit existing records.
* '''Widgets''' - Support for many different widget types including text fields, text areas, checkboxes, select lists, html editors, grids, file uploads, and more.
* '''Configurable''' - Customize forms using configuration files and delegate classes.
* '''Personalizable''' - Show different forms to different users depending on their permissions and preferences.
* '''Add Related Records''' - Insert records and automatically track their relationships to other tables.
* '''Editable Data Grid''' - Manage your data like a spreadsheet using the DataGrid module.
* '''Copy''' - Copy sets of records.
* '''Update Found Set''' - Update multiple records with one swipe.
* '''Fine-grained Permissions''' - Assign editing permission based on table, record, or field. 
* '''File uploads''' - Support for file uploads with storage either in a BLOB field or on the file system.
* '''Delete''' - Delete single record or delete the current found set.

====Searching====

* '''Automatic Find Form''' - The Xataface find form allows you to search a table on any field.
* '''Range Searches''' - Search for records matching values in a certain range (e.g. find all people between the ages of 20 and 30).
* '''Exact Matching''' - Search for exact matches.
* '''Partial Matching''' - Search for fields that contain a keyword phrase.
* '''Multi-field search''' - There is always a simple search field accessible which searches all fields in the current table.  E.g. a search for ""Tom"" would match any record in the current table that contained the phrase ""Tom"" in any of its columns.
* '''Related Record Searches''' - Find records that contain related records matching a search term.  (E.g. find all people who got an 'A' in a particular course).


====Browsing====

* '''Automatic Details View''' - Each record has user-friendly details page to browse the contents of the record.
* '''AJAX Record Tree''' - Provides optional AJAX record tree to browse the data in your database by relationships.
* '''Expand for More''' - Quickly expand a row in list view to see the full record details.
* '''Drag and Drop Reordering''' - The details view for a record can be broken up into related sections.  Users can reorder these sections via drag and drop.

====Exporting====

* '''RSS''' - Support for RSS 1.0, 2.0 and Atom feeds of any found set.
* '''XML''' - Export any found set as XML so that the data can be interchanged with other products (e.g. desktop publishing suites).
* '''CSV''' - Export any found set to CSV (comma-separated-value) to open in a spreadsheet application like Excel.
* '''JSON''' - Export any found set to JSON.  This feature makes Xataface a good choice for serving the next generation of Web 2.0 AJAX applications.

====Internationalization====

* '''String Internationalization''' - Xataface fully supports internationalizing your application.  It provides you with language files to provide translations of all of the strings and labels in your application.
* '''Dynamic Data Translation''' - Xataface even allows you to internationalize your existing database data without having to change your database structure.
* '''Templates''' - Includes a {translate} tag for Smarty templates to easily translate template text.
* '''In the background''' - You can use Xataface to internationalize any PHP/MySQL website without having to make any drastic changes to your existing code.  Just include Xataface as a library and use some of its useful internationalization functions to convert your application into multiple languages.
* '''Translation Form''' - If multiple languages are enabled, Xataface provides a simple translation form to translate content between languages.
* '''Translation Status Tracking''' - Track the status of translations to mark whether they need to be retranslated.

====Importing====

* '''Import Filter API''' - Using delegate classes, it is easy to define an import filter to import any type of data into the database.
* '''User Preview''' - User can preview imported data before confirming that he wants to import it.

====History====

* '''Optional History Support''' - If history is enabled, all changes made to any data are recorded.
* '''Undo/Redo Support''' - Easily revert to an earlier version of a record.
* '''View Snapshot''' - Browse previous versions of records.
* '''View Diffs''' - View differences/changes between versions of records, similar to a wiki.

====Caching====

* '''Output cache''' - Supports output cache that caches output of pages to improve performance dramatically for busy sites.  Cache is automatically refreshed whenever changes are made to tables that are used to generate the page.
* '''APC Support''' - If APC (Alternate PHP Cache) is installed, Xataface will automatically use it to cache table configuration information.  This tends to increase performance by about 20%.


====Security====

* '''Fine-grained permissions''' - Define permissions to the entire application, a single table, by the record, or by the field.  Each feature has an associated permission that can be allowed or disallowed on a per-user basis.
* '''Cascading Permissions''' - You can very restrictive permissions to the application as a whole and then apply more permission permissions to specific tables or fields that you want uses to be able to access.  Table permissions override application permissions.  Field permissions override field permissions.
* '''Role-based permissions''' - You can define """"""roles"""""" which are sets of permissions that can be assigned to users.
* '''Extendable Permissions Model''' - You can easily define your own permissions and roles, extending existing roles, custom for your application.
* '''Built-in Authentication''' - It is easy to set up login/logout features for your application.  Just tell Xataface which table you store your user records in, and Xataface will do the rest.
* '''Password Encryption''' - Xataface supports and is compatible with most of the standard password encryptions including MD5, SHA1, and MySQL Password.
* '''Pluggable Authentication''' - Easy to create your own authentication plugins in case you want to implement your own custom authentication.
* '''CAS''' - Module available for the Yale CAS (Central Authentication Service).
* '''LDAP''' - LDAP authentication module available.
* '''HTTP''' - Optional HTTP login support.  Standard login uses a web-based login form, but you can also use HTTP headers for authentication.

====Relationships====

* '''Powerful Relationship Model''' - It is easy to define relationships between your tables using simple configuration files.  Syntax is simple, but the results are powerful.
* '''Add New Related Record''' - Create a new record and add it to a parent record's relationship at the same time. (E.g. create a new ""course"" record and add it to a teacher's list of taught courses).
* '''Add Existing Related Record''' - Add an existing record to a parent record's relationship. (e.g. Add an existing course record to a teacher's list of taught courses).
* '''Remove related record''' - Remove a record from a relationship. (e.g. remove a course record from a teacher's list of taught courses).

====API====

Xataface includes a powerful API to allow you to more efficiently work with your database.

* '''Data Objects''' - Provides a simple API to work with database records.  Searching, loading, saving, editing, and deleting records supported.

====Templates====

* '''Smarty Template Engine''' - Xataface uses the Smarty template engine as a base, one of the fastest PHP template engines available.
* '''Template Inheritance''' - You can create templates that inherit from other templates, and replace the content in specified ""slots"" of the original template.  This drastically increases template reuse and development productivity.
* '''Cascading Support''' - All system templates are stored in the Dataface/templates directory.  Your application can have its own templates directory where you can place templates to override system templates.  All parts of the system can be overridden without modifying the original templates themselves.

====Themes====

Xataface includes a powerful themes API.  You can create multiple looks for your application and switch between them with a simple configuration setting.

====REST Support====

Xataface's intelligent URL protocols make it a powerful platform for REST web services.  You can specify a query directly in the URL to obtain the exact found-set that you want.  This is also very useful in standard web applications because you can easily create links to desired parts of your application.  Or you can use Xataface to provide missing functionality in your existing applications and link only to the parts of your Xataface app that you need.

===History===

Xataface (formerly Dataface) was originally created by Steve Hannah in 2005 to increase productivity created data-driven applications for Simon Fraser University.  He came from faculty that used Filemaker extensively for their databases.  As a PHP developer he preferred open technologies like MySQL as they provided fewer ""road blocks"", but it was hard to deny the benefits of filemaker when it came to providing users with an instant user interface for their databases.  It was difficult to justify spending 3 weeks building an administration console for a MySQL application when it could have been done in 3 hours had Filemaker been used.

Xataface was designed to:

# Increase developer productivity to the point where MySQL applications could be created as quickly as Filemaker applications without sacrificing usability and functionality.
# Add an abstraction over a database to make is accessible to non-technical users.  The secretary shouldn't need to know SQL in order to interact with a database.
# Test the limits of PHP and MySQL

As it was built with the intention of providing an alternative for Filemaker, many implementation details and concepts have been inspired by Filemaker.  For example, Xataface's implementation of relationships is very similar to Filemaker relationships; as are valuelists.  In addition the method of searching follows many Filemaker conventions.

The first application built with Xataface was a group content management system for the Faculty of Applied Sciences at Simon Fraser University.  This system was used by faculty to manage their research profiles and their research groups.  The database itself pre-existed the Xataface implementation.   Xataface was used to build a new administrative interface to the system.  Since then Xataface has been used to develop many systems for SFU including website content management systems, auctions, event registration systems, research databases, shopping carts, and more.

==Where to go from here==

* [http://xataface.com/documentation/tutorial/getting_started Getting Started Tutorial]
* [http://xataface.com/videos Watch Demonstration Videos of Xataface]
* Sign up for the Xataface Maillist to receive free updates and development tips.  (See sign-up form in upper left of the page).",,en,0
actions.ini_file,6,actions.ini_file,"==actions.ini file Reference==

[[toc]]

The actions.ini file stores information about the various [[action]]s that can be performed by your application.  An action may be manifested in two ways:

# As a web page
# As a menu item

And there is no reason why an action cannot serve in both capacities simultaneously.  All menu items and functions that Xataface performs are defined in the Xataface actions.ini file (in the root of the Xataface installation dirctory).  You can also create an actions.ini file in your application's root directory to override existing Xataface actions, or to create your own.  If you want to modify an existing action instead of overriding it, you can use this syntax.

<code>
[browse > browse]
	label = Browse
</code>

The &gt; symbol simply means to inherit from the existing browse action.  All the attributes are the same, and we just override the label to Browse (originally was Details)

Additionally, for actions that pertain only to a single table, an actions.ini file may be placed in any [[table configuration directory]].

===Syntax===

As with the [[fields.ini file]] and the [[valuelists.ini file]], the actions.ini file uses the simple [[INI file syntax]] to define its actions.  Each action is defined in its own section, and can have a number of directives to specify the action's behavior.

Here is a snippet from the Xataface actions.ini file to give you an idea:

<code>
;; Show the details of the current record
[browse]
	label = Details
	category = table_tabs
	url = ""{$this->url('-action=view')}""
	accessKey = ""b""
	mode = browse
	permission = view
	order=0

;; Show a list of the records in the current found set
[list]
	label = List
	category = table_tabs
	url = ""{$this->url('-action=list')}""
	accessKey = ""l""
	mode = list
	template = Dataface_List_View.html
	permission = list
	order=0.5

;; Show a ""Find Record Form""
[find]
	label = Find
	category = table_tabs
	url = ""{$this->url('-action=find')}""
	accessKey = ""f""
	mode = find
	permission = find
	template = Dataface_Find_View.html
	order=0.75
</code>

This snippet shows the definition of the browse, list, and find actions - three of the most central actions in a Xataface application.  Notice how each action has its own section (according to [[INI file syntax]]) with a number of directives which specify how the action behaves.  For instance, each action has a ""category"" value of ""table_tabs"", which tells Xataface to display the actions as part of the table tabs in the user interface.

===Directives===

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[action allow_override|allow_override]]
| An optional directive to indicate that this action can be overridden by more specific directives in another ini file.  Currently there is only support for a value of ""relationships.ini"" indicating that the settings can be overridden in the relationships.ini file.  In order for this to work, related=1 must also be set.
| 1.3rc4
|-
| [[action label|label]]
| The label to display if the action is used as a menu item.
| all
|-
| [[action category|category]]
| The name of the action's category which can be used to group this action together with other similar actions to be used in a menu in the user interface.
| all
|-
| [[action url|url]]
| If the action appears as a menu item, this is the URL that the menu item points to.  This may contain PHP expressions inside curly braces.
| all
|-
| [[action accessKey|accessKey]]
| The key code to automatically select this action if it is included as a menu item.  I.e. ALT+accessKey calls the action.
| all
|-
| [[action mode|mode]]
| This indicates which tab of the table tabs (find, details, list, etc...) that this action should appear to be part of when the action is viewed as a web page.  If this is left undefined, or it does not match any existing visible action in the table tabs, then no tab will appear to be selected.
| all
|-
| [[action permission|permission]]
| The name of a permission required to both see the action as part of a menu and to access the action as a web page.
| all
|-
| [[action visible|visible]]
| A boolean value indicating whether the action should be visible as a menu item.
| all
|-
| [[action condition|condition]]
| A boolean value or a PHP expression evaluating to a boolean value to indicate whether the action should be visible as a menu item.
| all
|-
| [[action url_condition|url_condition]]
| A PHP expression evaluating to a boolean value to indicate whether the URL directive should be evaluated.  This basically checks to make sure that its OK to evaluate the ""url"" expression, just in case the current state of affairs would cause it to throw a fatal error.
| all
|-
| [[action order|order]]
| A numeric value indicating the order in which the action should be displayed as part of a menu.  Low numbers result in higher placement in the menu.
| all
|-
| [[action icon|icon]]
| The path to an icon that should be used when the action appears as a menu item.
| all
|-
| [[action template|template]]
| The path to the template that should be used when the action is displayed as a web page.
| all
|-
| [[action description|description]]
| Mouseover text for the action (when displayed as a menu item).
| all
|}

===PHP Expression Context===

Notice that the [[action url|url]], [[action condition|condition]], and [[action url_condition|url_condition]] directives allow you to use a PHP expression for their values.  In order for this to be helpful, you should know a little bit about the context and environment in which these expressions will be executed.  All expressions are evaluated immediately prior to being rendered, so the same action can be displayed multiple times in the same page, but have very different resulting values for their [[action url|urls]] and [[action condition|conditions]].

These expressions are all executed within the context of the Dataface_Application::parseString() method, with the following variables loaded in the local symbol table (i.e. you can use the following variables in your expressions).

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[action context:site_url|$site_url]]
| The URL to the current application's directory (not including ""index.php"")
| all
|-
| $site_href
| The URL to the current application including ""index.php""
| all
|-
| $dataface_url
| The URL to the xataface installation directory.
| all
|-
| $table
| The name of the current table (i.e. the value of the ""-table"" request parameter""
| all
|-
| $query
| An associative array of the current query variables.
| all
|-
| $app
| A reference to the current Dataface_Application object.  Alias of ""$this""
| all
|-
| $resultSet
| A reference to the Dataface_QueryTool object for the current query.
| all
|-
| [[action context:record|$record]]
| A reference to the current Dataface_Record object.
| all
|-
| [[action context:context|$context]]
| An associative array of context variables that are passed to the action from the context in which the action is called.
| all
|}",,en,0
afterRegister,14,afterRegister,"==afterRegister() Trigger==

A trigger that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]], to be executed after the registration form is saved.  This can be used to perform some custom actions like emailing the administrator.

===Signature===

function afterRegister( Dataface_Record &$record ) : mixed

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| &$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {
    function afterRegister(&$record){
        // mail the admin to let him know that the registration is occurring.
        mail('admin@example.com', 'New registration', 'A new user '.$record->val('username').' has registered);
    }
}
</code>

===See Also===

* [[beforeRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
after_action_new,33,after_action_new,"==after_action_new trigger==

[[toc]]

This trigger is called after the '''new''' action is successfully completed.  This trigger can be defined in the table [[Delegate class methods|delegate class]] and is often used to redirect to a particular page after a new record is submitted.  This should not be confused with the [[afterInsert]] trigger, which is executed after a record is inserted into the database (this can occur multiple times per request).  The after_action_new trigger is only executed once after the 'new' action has been successfully completed.  i.e. a maximum of once per request.

===Signature===

<code>
function after_action_new($params=array()){ ... } : return void
</code>

====Parameters====

This method takes a single associative array as a parameter. This array includes the following keys:

* '''record''' - The [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object that was just inserted.


===Examples===

====Example 1: Redirect to the view tab for the inserted record====

<code>
function after_action_new($params=array()){
    $record =& $params['record'];
    header('Location: '.$record->getURL('-action=view').'&--msg='.urlencode('Record successfully inserted.'));
    exit;
}
</code>
",,en,0
beforeRegister,13,beforeRegister,"==beforeRegister() Trigger==

A trigger that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]], to be executed before the registration form is saved.  This can be used to perform some custom actions like emailing the administrator.

===Signature===

function beforeRegister( Dataface_Record &$record ) : mixed

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| &$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {
    function beforeRegister(&$record){
        // mail the admin to let him know that the registration is occurring.
        mail('admin@example.com', 'New registration', 'A new user '.$record->val('username').' has registered);
    }
}
</code>

===See Also===

* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
Calendar_Action,43,Calendar_Action,"==Calendar Action==

[[toc]]

Xataface 1.0 includes a built-in calendar action that is disabled by default.  If enabled, it allows you to view the records in any found set as a calendar of events, as follows:

<nowiki>
<div style=""text-align:center;border: 1px solid #ccc; padding: 10px"">
<img src=""http://media.weblite.ca/files/photos/Picture -4.png?max_width=500""
onmouseover=""this.src='http://media.weblite.ca/files/photos/Picture -4.png';""
onmouseout=""this.src='http://media.weblite.ca/files/photos/Picture -4.png?max_width=500';""/>
</div>
</nowiki>

===Features===

* Monthly display
* Hourly schedule for any day by clicking on it.
* Show record details instantly by clicking on it in the calendar.
* Recognizes dates, start and end times for records when interpreted as calendar events.
* Respects searches (i.e. you can filter the records and the calendar will only show those records in the found set).

===Requirements===

Your table records should contain at least dates in order for them to be interpreted as events that can be placed in a calendar.

===Setting up the Calendar===

Suppose I have a table called ''Lessons'' that stores information about scheduled music lessons.  If I want to add the calendar to this table, then I would add an ''[[actions.ini file]]'' to the ''tables/Lessons'' directory with the following contents:<code>
[calendar > calendar]
    condition=""true""
</code>
This overrides the calendar action which is disabled by default, and enables it for the ''Lessons'' table.

Next I need to inform Xataface which fields store the event dates and times so that the records can be laid out in the calendar appropriately.  (Note that if you skip this step, Xataface will make a best guess based on column types and names - but it is better to specify these explicitly).

In the ''Lessons'' table I have the following fields that are relevant here:

* ''lesson_date'' - A date field containing the date and start time of the event.
* ''start_time'' - A time field with the start time of the lesson.

We can tell Xataface to treat these fields accordingly by adding the following directives to the appropriate field sections of the [[fields.ini file]] for the ''Lessons'' table:

* ''event.date=1'' - Specifies that the field stores the date of the event.
* ''event.start=1'' - Specifies that the field stores the start time of the event.

So in our case we'll modify the [[fields.ini file]] as follows:

<code>
[lesson_date]
    event.date=1

[start_time]
    event.start=1
</code>

Now if we load up our application, we should now see a ''calendar'' tab along side ''list'', ''details'', and ''find'' for the ''Lessons'' table.  Click on this tab to see your records displayed in a calendar.

===Using a datetime field to store both date and start time===

You can also use a single field to store both the date and start time for an event.  In this case you just provide the ''event.date'' and ''event.start'' directives for the same field.  For example if the ''lesson_date'' was a datetime field that marked the date and time of the lesson, we would modify our [[fields.ini]] file as follows:

<code>
[lesson_date]
    event.date=1
    event.start=1
</code>

===Available Fields===

The Calendar action will look for the following pieces of information in your records:

{| class=""listing listing2""
! Name
! Description
! Version
|-
| event.date
| Indicates that the field contains the date of the event.
| 1.0
|-
| event.start
| Indicates that the field contains the start time of the event.
| 1.0
|-
| event.end
| Indicates that the field contains the end time of the event.
| 1.0
|-
| event.location
| Indicates that the field contains the location of the event.
| 1.0
|-
| event.category
| Indicates that the field contains the category of the event.
| 1.0
|}",,en,0
conf.ini_file,25,conf.ini_file,"==conf.ini File==

[[toc]]

The conf.ini file is where most of the application-level configuration information is stored for a Xataface application.  It contains information such as:

* database connection information
* which tables should appear in the tables menu.
* [[preferences|preference settings]]
* [[authentication]] settings
* which add-on [[modules]] are to be used
* output caching settings
* history/undo settings
* other misc settings.

Every conf.ini file must contain at least the following sections:


{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| _database
| Contains database connection info.
| all
|-
| _tables
| Contains a list of tables that are to be included in the navigation menu of the application.
| all
|}


The following optional sections may also be included:

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [http://xataface.com/documentation/how-to/disallow_tables _allowed_tables]
| Specifies tables that should be explicitly allowed to override disallowed tables listed or matched in the [http://xataface.com/documentation/how-to/disallow_tables _disallowed_tables] section.
| 0.7
|-
| [[_auth]]
| Contains information about [[authentication]].
| 0.6
|-
| [http://xataface.com/documentation/how-to/disallow_tables _disallowed_tables]
| A list of tables or patterns that match tables that should be blocked from being accessed directly through the application.  By default any table beginning with an underscore, 'dataface_', or ending in '__history' are blocked.  This prevents unintended access to some of the automatically created tables in Xataface.
| 0.7
|-
| _feed
| Configuration options for [[Introduction_to_RSS_Feeds_in_Xataface|RSS feeds]] that are generated by the application.
| 1.0
|-
| _history
| Settings pertaining to the [http://xataface.com/documentation/how-to/history-howto history feature] (e.g. whether it has been enabled).
| 0.7
|-
| _index
| Settings for the full site search indexing.
| 1.0
|-
| _modules
| A list of [[modules]] that are enabled for this application.
| 1.0
|-
| [[_output_cache]]
| Output cache settings.  Using output caching can dramatically improve performance for busier sites.
| 0.8
|-
| _themes
| A list of the themes that are to be applied to the application.
| 0.8
|}

===Stand-alone Attributes===

Stand-alone attributes for an INI file must appear at the beginning of the INI file (before any of the sections).  The conf.ini may contain the following stand-alone attributes.

{| class=""listing listing2""
|-
! Name
! Description
! Values
! Version
|-
| cache_queries
| Enables query caching.  Enabling this feature can yield drastic performance improvements especially on busy sites with large databases.
| boolean (0 or 1)
| 1.2

|-
| cache_queries_log
| Enables logging of query caching to the file /tmp/querylog.log so that you can tell whether your queries are being cached, and which ones are being cached.
| boolean (0 or 1)
| 1.2

|-
| default_action
| The default action to be performed if it is not explicitly specified in the query (e.g. 'list', 'find', 'edit').  Default is 'list'.
| string
| 0.6
|-
| debug
| If this is set to 1, then the application will run in debug mode which displays the available slots and blocks on the screen, along with some other debug information.
| 0 or 1 (default is 0)
| 0.6

|-
| default_browse_action
| The default action to perform in the details tab.  E.g. When you click on the ""details"" tab there are a number of sub-tabs including 'view', 'edit', etc... .   The default value for this directive is 'view'.  If you want to go directly to the edit form when clicking on a record in list view, you would set ''default_browse_action'' to 'edit'.
| string
| 0.6
|-
| default_language
| The default language to use.  This is the 2-digit ISO language code.  If this value is not specified it defaults to the first language listed in the ''[languages]'' section.
| string (2-digit ISO language code)
| 0.6
|-
| default_limit
| The default limit (i.e. the number of records to show per page) if none is explicitly specified in the query.  Default is 30.
| int
| 0.6
|-
| default_table
| The default table to show if none is specified by the query.  If you do not define this value, then the first table in the ''[_tables]'' section is used.
| string
|0.6
|-
| disable_session_ip_check
| Default behaviour automatically tracks the IP address of the user when they log in.  If a request is made for a session from a different IP then the session is automatically destroyed and the user is logged out.
| boolean
| 1.3rc4

|-
| title
| A title for the application (appears in the browser title bar).
| string
| 0.6
|-
| usage_mode
| The usage mode of the application.  If this value is set to ''edit'', then ajax inline editing is enabled (i.e. you can click on any value in the application to edit it inline.
| 'view' or 'edit'
| 0.6
|}

===Example 1: A simple conf.ini file===

<code>
[_database]
	host=""localhost""
	name=""mydb""
	user=""mydbuser""
	password=""foo""
	
[_tables]
webpage_sites=""Websites""
translations = ""Translations""
packages=""Packages""
users=Users
proof_jobs=""Jobs""
webpage_status=""Webpages Status""

</code>

===Example 2: A more complex conf.ini file===

<code>
;debug=1
;default_action=home
;google_translate_url=""http://weblite-dns2.com/proxy.php""
google_translate_url=""http://ec2-75-101-244-123.compute-1.amazonaws.com/proxy.php""
title=""Web Lite Translate""
default_price_per_word=0.15

;;Configuration settings for application
title=""translation_weblite_ca""
scriptUrl=""http://translation.weblite.ca/index.php""
multilingual_content=1


[_database]
	host=""localhost""
	name=""mydb""
	user=""mydbuser""
	password=""foo""
	
[_tables]
    webpage_sites=""Websites""
    translations = ""Translations""
    packages=""Packages""
    users=Users
    proof_jobs=""Jobs""
    webpage_status=""Webpages Status""


[_auth]
	users_table=users
	username_column=username
	password_column=password
	secret_code=""ljkasdfjkldsafliasdoiudsfoi""
	allow_register=1
	session_timeout=999999999
	
[_modules]
	modules_ShoppingCart=""modules/ShoppingCart/ShoppingCart.php""

[ShoppingCart_taxes]
	;; This section is necessary to declare that we have NO taxes.
	
[metatags]
	keywords = ""translation, translate""
	description = ""Good translation service""
	
;[_output_cache]
;	enabled=1

[_mail]
	func=mail2
	
</code>

",,en,0
Selected_Records_Actions,58,Selected_Records_Actions,"==Creating a Custom ''Selected Records'' Action==

[[toc]]

If you view the ''list'' tab in any of your Xataface applications, you'll notice that there is a checkbox next to each row of the list, and there are a number of actions listed at the bottom of the list that you can perform on the selected records.  Xataface comes pre-built with only a few of these actions:

# Delete selected
# Update selected
# Copy selected

However it is quite easy to add your own actions here that are performed on selected records.  This article describes exactly how to do this.

===What is a ''Selected Record'' action?===

A ''Selected Record'' action is no different than any other action in Xataface, except that it is meant to act on the records that have been selected in the list tab.

==Example Action:  Approve Records==

Consider a news site where news stories are automatically imported into the database en masse, but each news story has a field ''approved'' to indicate whether the store has been approved to appear on the site yet.   The usage pattern of this application involves a lot of looking through lists of news stories and approving them.  Therefore it would be convenient if the user could just select the rows that he wants to approve and click a button to approve them all.

Out of the box Xataface would allow the user to select the records, click ''update selected records'', then update them all via the ''update selected records'' form.  But avoiding this extra step will improve usability greatly.

===Step 1: Design the Action===

First we need to specifically decide how our action will work.  In this case, the flow goes as follows:

# User selects the news items they want to approve.
# User clicks the ''Approve Selected'' button. (to be created)
# Our action approves the selected records.
# User is automatically redirected back to the list tab with a message stating how many records were successfully approved, and whether there were any errors.

===Step 2: Gather Our Tools===

Before we actually create the action, let's look at a few tools that we'll be using from the Xataface framework to make this happen.

# In the [[actions.ini file]], the ''[[selected_result_actions]]'' category is reserved for actions that act on selected records of the list tab.  E.g.<code>
[delete_selected]
    ...
    category=selected_result_actions
    ...
</code>
# The [http://dataface.weblite.ca/df_get_selected_records df_get_selected_records()] function returns an array of [http://dataface.weblite.ca/Dataface_Record Dataface_Record] objects that represent the rows that were selected to initiate the action.  E.g.<code>
$app =& Dataface_Application::getInstance();
$query =& $app->getQuery();
$records = df_get_selected_records($query);
foreach ($records as $record){
    ...
}
</code>
# The [http://dataface.weblite.ca/checkPermission Dataface_Record::checkPermission()] method allows us to see if the current user has access to a specific permission on the given record.  We'll use this method to ensure that the user has permission to approve the news record. E.g.<code>
if ( !$record->checkPermission('edit', array('field'=>'approved')) ){
    return PEAR::raiseError(""You don't have permission to edit the approved field for this record."");
}
</code>
# The Xataface will pass the redirect URL where your action should send the user upon completion of the action as the ''--redirect'' attribute of the ''POST'' variables.  This value is base64_encoded so you'll need to decode it before redirecting.  E.g.:<code>
if ( @$_POST['--redirect'] ) 
    $url = base64_decode($_POST['--redirect']);
$url .= '&--msg='.urlencode($updated.' records were deleted.');
header('Location: '.$url);
exit;
</code>

===Step 3: Create the Action===

We will call our action ''approve_news'' so we'll place it in the ''actions/approve_news.php'' file of our application:
<code>
<?php
class actions_approve_news {
    function handle(&$params){
        // First get the selected records
        $app =& Dataface_Application::getInstance();
        $query =& $app->getQuery();
        $records =& df_get_selected_records($query);

        $updated = 0;  // Count the number of records we update
        $errs = array();   // Log the errors we encounter

        foreach ($records as $rec){
            if ( !$rec->checkPermission('edit'), array('field'=>'approved')) ){
                $errs[] = Dataface_Error::permissionDenied(
                    ""You do not have permission to approve '"".
                    $rec->getTitle().
                    ""' because you do not have the 'edit' permission."");
                continue;
            }
            $rec->setValue('approved', 1);
 
            $res = $rec->save(true /*secure*/);
            if ( PEAR::isError($res) ) $errs[] = $res->getMessage();
            else $updated++;
            
        }
        
        if ( $errs ){
            // Errors occurred.  Let's let the user know.
            // The $_SESSION['--msg'] content will be displayed to the user as a message
            // in the next page request.
            $_SESSION['--msg'] = 'Errors Occurred:<br/> '.implode('<br/> ', $errs);
        } else {
            $_SESSION['--msg'] = ""No errors occurred"";
        }
        

        $url = $app->url('-action=list');   // A default URL in case no redirect was supplied
        if ( @$_POST['--redirect'] ) $url = base64_decode($_POST['--redirect']);
        $url .= '&--msg='.urlencode($updated.' records were deleted.');

        // Redirect back to the previous page
        header('Location: '.$url);
        exit;
    }
}
</code>

===Step 4: Add the action to your actions.ini file===

The actions.ini file allows us to specify how and where this action is used, and by whom.  We can specify permissions that are required to perform the action, conditions that are required to display the action, confirmation messages that are to be displayed to the user when they are about to perform the action, and more.  Our [[actions.ini file]] entry looks like:

<code>
[approve_news]
    label=""Approve""
    description=""Approve selected records""
    permission = edit
    category=selected_result_actions
    confirm=""Are you sure you want to approve the selected records?""
    icon=""${dataface_site_url}/images/approve.gif""
    condition=""$query['-table'] == 'news'""
</code>

This should be fairly straight forward.  The only special items here are the ''category'' and ''confirm'' directives.  The ''condition'' directive tells Xataface that this action should only be shown for the ''news'' table. 

The ''confirm'' directive defines a confirmation message that should be displayed to the user when they attempt to approve records.

The ''icon'' directive allows you to specify the path to an icon to display for the action.  In our case we have an icon located in the images directory of our application.

===Step 5: Trying it out===

Now when we go to the ''list'' tab of the ''news'' table there is an ''Approve'' button along the bottom where it says ""With Selected"".  You we can click on this button to approve any of the selected rows.


	",,en,0
Creating_a_Dashboard,57,Creating_a_Dashboard,"==Creating a Dashboard for your Users==

[[toc]]

Xataface allows you to build powerful data-driven applications quickly, but these applications may be daunting to your users if they don't know what they can do with the application.  Most applications provide some sort of dashboard or control panel with some introductory instructions and links to commonly used actions in the application.  This makes the application more intuitive for users so that they can start using it right away, even without instruction from the developer.

===Characteristics of a Dashboard===

# Should be the default page when someone visits the application.
# Should be customized to show menus and content that are relevant to the current user.  (i.e. different users may see different links and content on their dashboard).
# Should contain at least some basic instructions so that the user understands what the application does when he visits the dashboard for the first time.
# Should contain links to frequently used actions.

===Strategies: 8 ways to skin the cat===

There are many viable strategies for adding a dashboard to your Xataface application.  This article presents only one.  It has been chosen because it satisfies all of the desired characteristics of a dashboard listed above, and it is easy to implement.

This strategy involves the following components:

# Create a dummy ''dashboard'' table.
# Create a dashboard action and associated template.
# Make sure our dashboard action is the default action for our application (more complex than just using the [[default_action]] directive in the [[conf.ini file]].

==Our Sample Application==

Consider our sample application, a publications management system for professors and research groups at a university.  It allows users to manage their publications using either BibTex format or a web-based form, and embed those publications into their webpage in a slick sortable format.  Currently, when the user accesses the application for the first time, they are shown the ''list'' tab of the ''bibliographies'' table.  This isn't all that informative and it may not be obvious to the user that their first step should be to create a new bibliography via the ''new record'' button.  Ideally we would like the user to go directly to a dashboard page with options to:

# Add New Bibliography
# Edit an Existing Bibliography
# Embed a Bibliography into their Webpage

And we want some basic instructions so that the user knows what to do when they first access the page.

==The Steps==

To create this dashboard we will follow the steps listed below (and mentioned above in the ''strategies'' section.

===Step 1: Create a dummy ''dashboard'' table===

This may seem unorthodox but it just happens to make our lives easier in the long run.  By creating a dummy table we are able to cause that table to be listed first in the ''_tables'' section of the [[conf.ini file]] and thus be the default table when users visit our application.

<code>
CREATE TABLE dashboard (
    dashboard_id int(11) not null auto_increment primary key
);
INSERT INTO dashboard values (1);
</code>

===Step 2: Make ''dashboard'' table default===

We now modify the conf.ini file to list the ''dashboard'' table first:
<code>
[_tables]
    dashboard=Dashboard
    bibliographies=Bibliographies
</code>

===Step 3: Create a Dashboard action and associated template===

This is the step where we actually create our dashboard action.  There are three parts to this story:

====Creating Action PHP Class====

The actual action will be located in the ''actions/dashboard.php'' file of our application, and looks like:

<code>
<?php
class actions_dashboard {
    function handle(&$params){
        $bibs = df_get_records_array('bibliographies', array());
        df_display(array('bibliographies'=>$bibs), 'dashboard.html');
    }
}
</code>

All this does is loads the ''bibliographies'' records owned by the current user. Elsewhere we are using security filters so that the user can only see ''his'' bibliographies, which is why we don't need to specify any query here in the ''df_get_records_array'' function.

It then passes those bibliographies to the ''dashboard.html'' template that we create next.

====Creating the Action's Template====

The template for our action is located in the ''templates/dashboard.html'' file:
<code>
{use_macro file=""Dataface_Main_Template.html""}
    {fill_slot name=""main_column""}
        <h1>Welcome to the BibTeX Publication Management System (BPMS)</h1>
        
        <p>This system allows you to manage your publications and publish
        them on the web.  Some common actions you may perform with this system
        include:
            <ul>
                <li><img src=""{$ENV.DATAFACE_URL}/images/add_icon.gif""/>
                    <a href=""{$ENV.DATAFACE_SITE_HREF}?-table=bibliographies&-action=new"">
                        Create New Bibliography</a>
                </li>
                <li><img src=""{$ENV.DATAFACE_URL}/images/edit.gif""/> 
                   Edit existing bibliography: 
                   <select onchange=""window.location.href=this.options[this.selectedIndex].value"">
                    <option value="""">Select ...</option>
                    {foreach from=$bibliographies item=bibliography}
                        <option value=""{$bibliography->getURL('-action=edit')}"">
                            {$bibliography->getTitle()}
                        </option>
                    
                    {/foreach}
                </select>
                </li>
                <li><img src=""{$ENV.DATAFACE_URL}/images/file.gif""/> 
                    Embed your bibliography in a webpage:
                    <select onchange=""window.location.href=this.options[this.selectedIndex].value"">
                    <option value="""">Select ...</option>
                    {foreach from=$bibliographies item=bibliography}
                        <option value=""{$bibliography->getURL('-action=view')}#embed"">
                            {$bibliography->getTitle()}
                        </option>
                    
                {/foreach}
                </select>
                </li>
                
            </ul>
    {/fill_slot}
{/use_macro}
</code>

A few key things to notice in this template:

# It extends the ''Dataface_Main_Template.html'' template placing its content in the ''main_column'' slot.  This allows our action to still display within the header and footer of our application.
# It makes use of the {$ENV.DATAFACE_SITE_URL} and {$ENV.DATAFACE_SITE_HREF} variables to refer to the site's base url and create links to the desired common actions.
# It provides a direct link to the ''new bibliography record'' form.
# It uses some slick javascript combined with select lists to allow the user to select any of his current bibliogaphies and edit them, or embed them into a webpage.

====Adding entry to the actions.ini file====

Currently our dashboard action has no permissions attached to it so users can see it whether they are logged in or not.  In this particular application we want to require users to log in, and we have set permissions for all logged in users to NO_ACCESS().  Unfortunately this permission setting is only helpful if our action requires a particular permission to access it.  We'll require the 'view' permission for this action, by adding the following to the actions.ini file:

<code>
[dashboard]
    permission=view
</code>


===Step 4: Specify permissions===

We still want to specify permissions for our ''dashboard'' table to ensure that only logged in users can access the dashboard.  So we create a delegate class for the ''dashboard'' table at ''tables/dashboard/dashboard.php'' with the following contents:

<code>
<?php
class tables_dashboard {
    function getPermissions(&$record){
        if ( getUser() ){
            return Dataface_PermissionsTool::ALL();
        }
        return null;
    }
}
</code>

'''Note that we have defined the getUser() function elsewhere as a means of obtaining the current user and checking if a user is indeed logged in.'''

Notice that this [[getPermissions]] method returns all permissions only if the user is logged in.  Otherwise it returns null, which means that it should use the same permissions as the rest of the application as defined in the [[Application Delegate Class]].

===Step 6: Make ''dashboard'' the default action for the ''dashboard'' table===

Now we just have one more detail that needs to be taken care of.  We want the ''dashboard'' action to be the default action for the ''dashboard'' table only.  By default we would see the ''list'' action which isn't helpful at all, so we will want to add a rule in our application delegate class to ensure that the user only sees our custom ''dashboard'' action if they access the ''dashboard'' table.  We define a beforeHandleRequest() method in our conf/ApplicationDelegate.php (the application delegate class) file for this purpose:

<code>
<?php
class conf_ApplicationDelegate {
    
...
    function beforeHandleRequest(){
        ...
        $app =& Dataface_Application::getInstance();
	$query =& $app->getQuery();
	if ( $query['-table'] == 'dashboard' and ($query['-action'] == 'browse' or $query['-action'] == 'list') ){
	    $query['-action'] = 'dashboard';
	}
        
        
    }
    
    ...
}
</code>

This simply checks to see if the table is ''dashboard'' and changes the current action to ''dashboard'' if so.

===Step 7: Try it out===

At this point, we are ready to try out our new dashboard to see how it works.  When we load our application it should now go to the dashboard action that we created.  We should also see ''Dashboard'' listed as the first table in the tables menu.

This dashboard presents a major improvement to our application as it is now much more user friendly.

<nowiki>
<img src=""http://media.weblite.ca/files/photos/pub-dashboard.png?max_width=640""/>
</nowiki>",dashboard,en,0
Delegate_class_methods,7,Delegate_class_methods,"==Delegate Class Reference==

[[toc]]

A delegate class is a PHP class that complements a particular table with custom bahaviors.  Basic table metadata can be supplied using the [[fields.ini file]], however some things are better customized using PHP.

===Delegate Class Location===

The delegate class should be located in a file named TABLENAME.php (where TABLENAME is the name of the table with which the delegate class is associated) inside the table's [[table configuration directory|configuration directory]].  E.g. given a table named ""people"", you would place the delegate class in the file ""tables/people/people.php""

===Basic Delegate Class===

<code>
<?php
class tables_people {}
?>
</code>

===Available Methods===

====Table Settings====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[sql delegate method|__sql__]]
| Defines the SQL query that can be used to fetch records of this table.  This is identical to the [[fields.ini file]] [[__sql__]] directive, except that by defining it in the delegate class you have more flexibility.
| 1.0
|}

====Permissions====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getPermissions]]
| Returns the permissions available for a given record.
| 0.6
|-
| getRoles
| Returns the roles allowed for a given record.
| 1.0
|-
| [[__field__permissions]]
| Returns the default permissions for a field of a given record.
| 1.0
|-
| __field__roles
| Returns the default roles for a field of a given record.
| 1.0
|-
| [[fieldname__permissions]]
| Returns the permissions that are allowed for the field ""fieldname"" on a given record.
| 0.7
|-
| fieldname__roles
| Returns the roles that are allowed for the field ""fieldname"" on a given record.
| 1.0
|-
| rel_relationshipname__permissions
| Returns the permissions pertaining to the relationship ''relationshipname'' on a given record.
| 1.0
|-
| rel_relationshipname__roles
| Returns the role or roles pertaining to the relationship ''relationshipname'' on a given record.
| 1.0
|}

====Triggers====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[after_action_edit]]
| Trigger called after the edit action is succesfully completed.
| 0.7
|-
| [[after_action_new]]
| Trigger called after the new action is successfully completed.
| 0.7
|-
| [[after_action_delete]]
| Trigger called after the delete action is successfully completed.
| 0.7
|-
| [[afterAddExistingRelatedRecord]]
| Trigger called after an existing related record is added.
| 0.5
|-
| [[aftereAddNewRelatedRecord]]
| Trigger called after a new related record is added.
| 0.5
|-
| [[afterCopy]]
| Trigger called after a record is copied.
| 1.3
|-
| [[afterDelete]]
| Trigger called after a record is deleted.
|0.5
|-
| [[afterAddRelatedRecord]]
| Trigger called after a related record of this table is added (either an existing record or a new record).
| 0.5
|-
| [[afterRemoveRelatedRecord]]
| Trigger called after a related record is removed from a relationship.
| 1.1.6
|-
| [[afterInsert]]
| Trigger called after a given record is inserted.
| 0.5
|-
| [[afterSave]]
| Trigger called after a given record is saved (insert or update).
| 0.5
|-
| [[afterUpdate]]
| Trigger called after a given record is updated.
| 0.5
|-
| [[beforeAddExistingRelatedRecord]]
| Trigger called before an existing related record is added.
| 0.5
|-
| [[beforeAddNewRelatedRecord]]
| Trigger called before a new related record is added.
| 0.5
|-
| [[beforeAddRelatedRecord]]
| Trigger called before a related record of this table is added (either an existing record or a new record).
| 0.5
|-
| [[beforeCopy]]
| Trigger called before a record is copied.
| 1.3
|-
| [[beforeDelete]]
| Trigger called before a record is deleted.
| 0.5
|-
| [[beforeRemoveRelatedRecord]]
| Trigger called before a related record is removed.
| 1.1.6
|-
| [[beforeSave]]
| Trigger called before a given record is saved (insert or update).
| 0.5
|-
| [[beforeInsert]]
| Trigger called before a given record is inserted.
| 0.5
|-
| [[beforeUpdate]]
| Trigger called before a given record is updated.
| 0.5
|-
| [[init]]
| This method is called the first time the table is loaded.  It allows you to specify initialization details.
| 0.8
|}


====Field Filters====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| fieldname__htmlValue
| Returns the value of the field ""fieldname"" for a given record as HTML.
| 0.5
|-
| fieldname__display
| Returns the value of the field ""fieldname"" appropriate for displaying.
| 0.5
|-
| [[fieldname__default]]
| Returns the default value for the field ''fieldname''.  New record forms will be prepopulated with this value.
| 0.7
|-
| [[fieldname__validate]]
| Validates the input for the field ''fieldname''.
| 0.6
|-
| fieldname__parse
| Parses the input value for the field ''fieldname''.  This is called by Xataface inside the setValue() method or each record to normalize input values before they are stored in the object (not the database).
| 0.5
|-
| fieldname__toString
| Converts the value of the field ''fieldname'' to a string.  This string representation is used as the basis for most higher level data retrieval methods (such as serialize and display).  This could be treated as an inverse to the [[fieldname__parse]] method.
| 0.5
|-
| fieldname__serialize
| Converts a value of the field ''fieldname'' to be saved in the database.  This should return a string representation of the value that is suitable for database storage.
| 0.5
|-
| fieldname__link
| A link that appears beside the field ''fieldname'' on the edit form.
| 0.6
|-
| [[field__pushValue]]
| Converts form input for field ''fieldname'' to be ready to store in a Dataface_Record.
| 0.6
|-
| [[field__pullValue]]
| Converts a value for field ''fieldname'' in a Dataface_Record object to be ready to be inserted as a value on an HTML form.
| 0.6
|-
| [[field__fieldname]]
| Effectively creates a calculated field named ""fieldname"" available on the given record.
| 0.6
|-
| [[no_access_text]]
| Replace the default NO ACCESS permission text with another text.
| 1.1.6
|-
| [[no_access_link]]
| Replace the default link of the NO ACCESS permission link with another link.
| 1.1.6
|}

====Template Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[block__blockname]]
| Outputs content that is meant to override a slot or a block named ""blockname"".
| 0.6
|}

====List Tab Customization====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| css__tableHeaderCellClass
| Returns a custom CSS class for a table header cell (th tag) in the list view.  Takes the name of a table column as a parameter.
| 2.0alpha2
|-
| css__tableRowClass
| Returns a custom CSS class for a table row (tr tag) in list view.  Takes a Dataface record as a parameter.
| 1.2
|-
| fieldname__renderCell
| Overrides the table cell content for the ""fieldname"" field in list view with custom HTML.
| 1.0
|-
| renderRow
| Overrides the the html used for a row in list view for the given record.
| 0.7
|-
| renderRowHeader
| Overrides the header for the table in list view.
| 0.7
|-
| renderRelatedRow
| Overrides the html used for a row in a related record list for a given related record.
| 1.0 beta 4
|-
| renderRelatedRowHeader
| Overrides the html used for the header in a related list.
| 1.0 beta 4
|}

====Record Metadata====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getBreadCrumbs]]
| Returns the bread crumbs (i.e. you are here) for a given record as an associative array of path parts.
| 0.6
|-
| [[getChildren]]
| Returns a list of Dataface_Record objects that are to be considered children of the given record.
| 0.8
|-
| [[getCreated]]
| Returns a unix timestamp marking the date that a record was created. 
| 0.9
|-
| getDescription
| Returns a string description summary of this record.  This is used for indexing, RSS feeds, and anywhere that a brief summary of a record is appropriate.
| 0.7
|-
| getPublicLink
| Returns the public URL of this record (in case it is different than the standard URL).
| 0.8
|-
| getTitle
| Returns the title for a given record.  The title is used in various parts of the application to represent the record.
| 0.5
|-
| [[getURL]]
| Overrides the getURL() method for a record.  Returns the URL that should be used to display the given record.
| 0.6
|-
| titleColumn
| Returns a string SQL select expression that is used to describe the title of records.
| 0.5
|}

====View Tab Customization====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[How_to_Add_Custom_Sections_to_View_Tab|section__sectionname]]
| Defines a section to be displayed in the view tab for the given record.
| 0.7
|}


====Search Setup====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| getSearchableText
| If [[_index|Indexing]] is turned on, then this returns the text that should be stored in the index for this record for searchability.
| 1.0
|}

====RSS Feed Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getFeedItem]]
| For RSS Feeds, overrides the defaults and returns an associative array with feed elements for a particular record
| 1.0
|-
| [[getFeed]]
| For RSS feeds, overrides the default feed for a query, returning an array of feed items.
| 1.0
|-
| getFeedSource
| Overrides the default feed source parameter for an RSS feed.
| 1.0
|-
| [[getRelatedFeed]]
| For RSS feeds, overrides the default feed for a related feed.
| 1.0
|-
| getRSSDescription
| Overrides the default generated RSS description for a record.
| 1.0
|}

===XML Output Customization===
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[toXML]]
| Overrides the default XML produced for a record in the [[export xml]] action.  Returns an XML string.
| 1.2.7
|-
| [[getXMLHead]]
| Returns a string to be included at the beginning of XML output for a particular record. (just inside the opening tag).
| 1.2.7
|-
| [[xmlTail]]
| Returns a string to be included at the end of XML output for a particular record. (just inside the closing tag).
| 1.2.7
|}

====Valuelist Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[valuelist__valuelistname]]
| Defines a valuelist named ''valuelistname''.
| 0.7
|}


====Importing Records====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[__import__filtername]]
| Defines an import filter to named ''filtername'' which is used to import records into the table.
| 0.7
|}
","RSS,Feeds,delegate classes, triggers",en,0
index_page,1,index_page,"==Documentation==

[[toc]]

===Introductory===

* [[about|About Xataface]]
* [http://xataface.com/documentation/tutorial/getting_started Getting Started Tutorial]
* [[How to build a PHP MySQL Application with 4 lines of code]]
* [[Troubleshooting]]

===Reference===

* [http://dataface.weblite.ca API Docs]
* [[conf.ini file]] directives
* [[fields.ini file]] directives
* [[valuelists.ini file]] directives
* [[relationships.ini file]] directives
* [[Delegate class methods]]
* [[Application Delegate Class]]
* [[permissions.ini file]] directives
* [[actions.ini file]] directives
* [[preferences|User Preferences]] - options for customizing the application further via the getPreferences() method.
* [[xataface templates|templates]]
* '''[[URL Conventions]]''' - Learn how to use Xataface's URL conventions to form URLs that return exactly the result set that you want.
* '''[[Roadmap]]''' - What is planned for the next releases of Xataface

===Cook Book===

* [[Customizing Theme Based on IP Address]] - An article on storing IP addresses in the database and showing users a different theme depending on which range of IP addresses they are connecting from.

===By Topic===

====Installation====

* '''[http://xataface.com/documentation/tutorial/getting_started/installation Xataface Installation Instructions]''' - This document explains how to install Xataface on your system.  It does not describe how to create an application with Xataface.
* '''[http://xataface.com/documentation/tutorial/getting_started/first_application Creating your first App]''' - How to create an application using Xataface (from the Getting Started Tutorial)
* '''[[about|About Xataface]]''' - Quick overview of Xataface.  Includes a 6 step example of creating an application with Xataface.

====Configuration====

* '''[http://xataface.com/documentation/tutorial/getting_started/customizing Customizing field labels, descriptions, and widgets]''' - This document explains how to customize some basic aspects of your application's edit forms. (From the Getting Started tutorial).
* '''[http://xataface.com/documentation/tutorial/getting_started/valuelists Using Valuelists]''' - How to use valuelists to set up options for your select lists and checkbox groups.
* '''[http://xataface.com/documentation/how-to/list_tab Configuring and customizing the list tab]''' -     This document explains how to customize the display of the list tab using INI files, templates, and delegate classes.


====Internationalization====

* '''[[Contribute to Xataface Translation Project]]''' - We need translators to help us keep the Xataface translations up to date.  This page shows how you can help.
* '''[http://xataface.com/documentation/tutorial/internationalization-with-dataface-0.6 Internationalization with Xataface]''' (tutorial)
* '''[http://xataface.com/documentation/how-to/how-to-internationalize-your-application How to internationalize your application]''' (how to) - Xataface 0.6 contains a LanguageTool class that allows your applications to be presented in multiple languages
* '''[http://xataface.com/documentation/how-to/use-translations How to use other translations]''' - Xataface 0.7 includes German and French translations. This document explains how to allow your application to use these and other translations, rather than the default English translation.
* '''[http://xataface.com/documentation/how-to/unicode How to enable unicode support]''' -     As of Xataface 0.6, unicode is fully supported so that your dataface application will work with any and multiple languages simultaneously.
* '''[http://weblite.ca/svn/dataface/core/trunk/lang Download latest language files out of SVN]''' - If you want to make sure that you have the latest translations, you can download them from SVN and place them into your xataface lang directory.


====User Interface Customization====

* '''[[preferences|User Preferences]]''' - You can hide, show, enable, and disable features of the application selectively.
* '''[http://xataface.com/documentation/tutorial/getting_started/changing-look-and-feel Changing the Look and Feel]''' - Change the way your application looks by adding custom headers, footers, and sections, and by overriding the default templates with your own custom templates.  (From the Getting Started tutorial).
* [[xataface templates|templates]]
* '''[http://xataface.com/documentation/tutorial/customizing-the-dataface-look-and-feel Customizing the Xataface look and feel]''' tutorial
* '''[[Customizing the look and feel of a row or a cell| Customizing the look and feel of an element in the list view]]''' - Personnalize the aspect of each part of your list according to its content.
* '''[http://xataface.com/documentation/how-to/custom_javascripts How to include custom javascripts and stylesheets]''' - Use the custom_javascripts and custom_stylesheets blocks to include your own custom javascript and CSS files in your application.
* '''[http://xataface.com/documentation/how-to/hide_search How to hide the search box]''' -     The full-text search box that appears in the upper right can easily be removed.
* '''[http://xataface.com/documentation/how-to/list_tab Configuring and customizing the list tab]''' -     This document explains how to customize the display of the list tab using INI files, templates, and delegate classes.
* '''[[How to Add Custom Sections to View Tab]]''' - The ''View'' tab in a Xataface application can be configured in many ways.  This tutorial shows you how to add your own custom sections to the view tab.
* '''[[Creating a Dashboard]]''' - Create a dashboard action for your users to so that they have a logical starting point in your application.
* '''[[Grafted fields]]''' - Add a grafted field to your table for user convenience. You can use it also to be able to sort columns with relative tables content.
* '''[[Clean the html for the export]]''' - Clean the HTML tags and entities for the export in CSV or XML.

====Using the API====

* '''[[Introduction to the Xataface API]]''' - A short introduction to the classes, methods, and functions available in the Xataface API.
* '''[http://xataface.com/documentation/how-to/how-to-define-custom-serialization-for-fields How to define custom serialization for fields]'''

====Security====

* '''[[authentication]]''' - Overview of Xataface Authentication
* '''[[registration form]]''' - Enabling User Registration in Xataface
* '''[[permissions.ini file]]''' - Reference of the permissions.ini file directives.
* '''[http://xataface.com/documentation/tutorial/getting_started/permissions Permissions]''' - Use sessions and delegate classes to define permissions at the record and field level. (From the Getting Started tutorial).
* '''[[Cached permissions]]''' - Use cached perms for complex queries inside getPermissions()
* '''[[Delegate_class_methods#toc5|Delegate class methods]]''' - Permissions-related functions
* '''[[Relationship Permissions]]''' - Guide to permissions on related records.
* '''[http://xataface.com/documentation/how-to/disallow_tables How to disallow access to tables]'''
* '''[[site_with_backoffice]]''' - A site with a backoffice without obligation to log in
* '''[http://xataface.com/documentation/how-to/security_filters Security Filters]''' - Use security filters to block users from seeing certain records.
* '''[[How to granulate permissions on each field]]''' - Decide for each field who can edit, read...
** '''[[no_access_text]]''' - Replace the default NO ACCESS permission text with another text.
* '''[[LDAP or Active Directory]]''' - How to authenticate users with LDAP or Active Directory...

====Performance====

* '''[http://xataface.blogspot.com/2009/06/using-query-caching-in-xataface.html Using Query Caching]''' - Query caching can drastically improve performance of busy applications with large databases.  This article explains how to enable this caching in your Xataface application.
* '''[[_output_cache]]''' - Xataface does quite a bit of heavy lifting on each page request. If your application is getting a lot of traffic that is slowing your server down, you may want to look at enabling the Xataface output cache.

====Modules====

* [[modules]] - Available Xataface Modules.  This includes such things as CAPTCHA validation, editable javascript grids, and more.
* [[Module Developers Guide]] - A guide / Tutorial on how to develop your own Xataface modules.

====Preferences====

====Relationships====

* '''[http://xataface.com/documentation/tutorial/getting_started/relationships Relationships]''' - Xataface allows you to define relationships between tables using the relationships.ini file. (From the Getting Started Tutorial)
* '''[http://xataface.com/documentation/how-to/how-to-assign-order-to-related-records How to assign order to related records]''' -     Sometimes it is desirable for the records in a relationship to take on a particular default order. Dataface 0.6 makes this easy if you follow a few conventions.
* '''[[Drag and Drop Reordering of Relationships]]''' - A more in-depth tutorial about adding ordering to relationships.
* '''[[relationships.ini file]] reference
* '''[[Relationship Permissions]]


====Forms====

* '''[http://xataface.com/documentation/how-to/DisableEnterKeyInFields How to disable the enter key in forms]'''
* '''[http://xataface.com/documentation/tutorial/getting_started/customizing Customizing field labels, descriptions, and widgets]''' - This document explains how to customize some basic aspects of your application's edit forms. (From the Getting Started tutorial).
* '''[http://xataface.com/documentation/tutorial/getting_started/valuelists Using Valuelists]''' - How to use valuelists to set up options for your select lists and checkbox groups. (From the Getting Started tutorial)
* '''[http://xataface.com/documentation/tutorial/getting_started/validation Form Validation]''' - Xataface allows you to add validation rules to fields using the fields.ini file.  (From the Getting Started tutorial).
* '''[http://xataface.com/documentation/how-to/how-to-handle-file-uploads How to handle file uploads]''' -     Xataface allows you to store file uploads in BLOB fields or on the file system.
* '''[http://xataface.com/documentation/how-to/custom_validation How to add custom validation with delegate classes]''' - If the standard validators (e.g., required, email, regex, etc..) don't quite cut it for your validation rules, Xataface allows you to define custom validation methods in the delegate class.
* '''[http://xataface.com/documentation/how-to/regex_validation Validating with regular expressions]''' - How to validate input into a field using regular expressions.
* '''[[Dynamic select boxes]]''' -     How to create two dynamic javascript select boxes from the valuelists.

====Importing====

* '''[http://xataface.com/documentation/how-to/import_filters Import Filters]''' - It is common to need to import records en masse into a database. This is what import filters are for. (Since 0.7).

====Actions====

* '''[http://xataface.com/documentation/tutorial/getting_started/dataface_actions Actions I: The Basics]''' - Web Lite's actions framework allows you to customize existing actions (e.g. new, edit, find) and create your own new actions. (From the Getting Started Tutorial).
* '''[http://xataface.com/documentation/how-to/after_action_triggers Adding triggers to actions]''' -     Xataface 0.6.1 adds some triggers to actions so that the developer can define custom functionality to be performed after an action has successfullly taken place.
* '''[[Calendar Action]]''' - Using the built-in calendar action to add a full-fledged event calendar to your application.
* '''[[Creating a Dashboard]]''' - Create a dashboard action for your users to so that they have a logical starting point in your application.
* '''[[Selected Records Actions]]''' - Create custom actions that are performed on records that have been selected in the list tab.
* '''[[Creating Printable Reports]]''' - Create a custom printable report using a custom action.
* '''[[Using RecordGrid]]''' - Using Dataface_RecordGrid to print data in tabular form.

====History====

* '''[http://xataface.com/documentation/how-to/history-howto How to activate history logging]''' -     Xataface 0.6.9 comes with support for managing the history of your records. This how-to shows you how to enable and use this feature.

====RSS Feeds====

* '''[[Introduction to RSS Feeds in Xataface]]''' - Xataface provides RSS feeds to any found set in your application.  This tutorial shows how it works and how you can configure these feeds to get your desired results.

====Event Calendar====

* '''[[Calendar Action]]''' - Introduction to the Xataface calendar action which can be used to convert your application into a full-fledged event calendar.
",,en,0
Drag_and_Drop_Reordering_of_Relationships,39,Drag_and_Drop_Reordering_of_Relationships,"==Drag and Drop Reordering of Related Records in Xataface==

One powerful aspect of Xataface is its abstraction of relationships between tables.  Once you define a relationship users can browse related records, add new and existing related records, and delete related records to or from the relationship.  For example, suppose you have a ''people'' table and a ''publications'', you could define a relationship from ''people'' to ''publications'' to identify publications that belong to a particular person.  The table's might look something like:

===people table===

{| class=""listing listing2""
! person_id
! person_name
|-
| 1
| John Smith
|-
| 2
| Ben Stein
|-
| 3
| Harley Davidson
|-
| 4
| Trevor Linden
|}


===publications table===

{| class=""listing listing2""
! publication_id
! owner_id
! pub_title
|-
| 1
| 2
| Introduction to widgetry
|-
| 2
| 2
| Intermediate Widgetry
|-
| 3
| 2
| Advanced Widgetry
|-
| 4
| 3
| How to play the violin
|}


See http://xataface.com/documentation/tutorial/getting_started/relationships for an introduction to relationships in Xataface, and how to define them.

Our relationship definition in the  ''people'' table's [[relationships.ini file]] might look something like:

<code>
[my_pubications]
    publications.owner_id=""$person_id""
</code>

This indicates that any publication whose ''owner_id'' column matches the current ''people'' record's ''person_id'' field is considered part of the relationship.  Using our example data above, this would mean that Ben Stein's ''my_publications'' relationship would contain 3 records: ""Introduction to Widgetry"", ""Intermediate Widgetry"", and ""Advanced Widgetry"".  In our Xataface application this means that in the ""Details"" tab for the ""Ben Stein"" record, we would see a sub-tab ''My Publications'' which would contain a list of Ben Stein's publications.

===Adding Publication Order===

Now that we have our relationship, what if Ben Stein wants his publications to appear in a particular order whenever they are displayed to the user.  Xataface allows us to specify an ""order"" column for our relationship, which will cause the related records to be orderable by drag and drop (if the user has appropriate permissions).

# Add a field to the ''publications'' table named ""pub_order""
# Change the relationship definition in the people table's [[relationships.ini file]] to tell Xataface to use the pub_order field for sorting:<code>
[my_pubications]
    publications.owner_id=""$person_id""
    metafields:order=""pub_order""
</code>

Now load up your application and navigate to the ""My Publications"" tab for the ""Ben Stein"" record. Now you're able to drag and drop rows in your application to reorder them.

===Permission to Reorder Records===

Only users who have been assigned the ''reorder_related_records'' permission for a record's relationship are allowed to reorder records of that relationship.  By default the ''EDIT'' role contains this permission, as does any role that permits the user to edit the parent record of the relationship.  The ''READ ONLY'' role does not contain this permission.  If you want to explicitly deny this permission for all relationships in a record, you can simply set this permission to 0 in the associated role within your application's [[permissions.ini file]]:

<code>
[MY ROLE]
     reorder_related_records=0
</code>

For more information about permssions see:

* [[permissions.ini file|The Permissions.ini file reference]]
* [http://xataface.com/documentation/tutorial/getting_started/permissions Introduction to Permissions]

===Loading Related Records using the Xataface API===

The ordering that is set via this drag and drop method is also honoured by the Xataface API when fetching related records.  You can load related records using the [http://dataface.weblite.ca/getRelatedRecordObjects getRelatedRecordObjects] method of the [http://dataface.weblite.ca/Dataface_Record Dataface_Record] class. E.g.

<code>
$benStein = df_get_record('people', array('person_id'=>2));
$pubs = $benStein->getRelatedRecordObjects('my_publications');
foreach ($pubs as $pub){
    echo $pub->val('pub_title').'<br/>';
}
</code>
This will list up to the first 30 publications of Ben stein in the order prescribed by our drag and drop ordering scheme.
",,en,0
encryption,29,encryption,"==encryption [[fields.ini file]] directive==

The '''encryption''' directive is meant to be used on password fields only.  It specifies that a certain type of encryption is to be used in the storing of values in this field.  For example, many PHP/MySQL applications use MD5 encryption to store their passwords.  If you want your Xataface application to be able to use the same users tables, then you'll need to specify the '''encryption''' directive for the password field.

===Possible Values===

{| class=""listing listing2""
|-
! Value
! Meaning
! Version
|-
| md5
| MD5 encryption
| 0.6
|-
| sha1
| SHA1 encryption
| 1.0
|-
| encrypt
| MySQL encrypt function
| 1.0
|-
| password
| MySQL password encryption
| 1.0
|}


===E.g. in the users table [[fields.ini file]]===

<code>
[password]
   encryption=md5
</code>
    ",,en,0
visibility:fieldName,47,visibility:fieldName,"==Example==

<code>visibility:ConferenceID = hidden</code>

This will make the ConferenceID in the relationship list view disappear.",,en,0
fieldname__permissions,53,fieldname__permissions,"==fieldname__permissions() method==

[[toc]]

The fieldname__permissions() methods will allow you to define custom permissions on a particular field in the [[delegate class]].  For example to specify permissions on a field named ''foo'' you would define the ''foo__permissions()'' method, and to define permissions on a field named ''role'' you would define the ''role__permissions()'' method.


==Example #1==

(Note this example needs to be refined to be more clear)

<code>
function approval_level__permissions(&$record){
	return array('edit'=>0); //this is will merge with what the permissions for the normal record
}
</code>

Here we are targeting the ''approval_level'' field of the [[delegate class]].  The permissions method takes a return value an array of permissions.  So for example:

<code>
$permissions['new'] = 0;
$permissions['edit'] = 0;
</code>

Would be an example of an array of permissions which the key being the permission name and the value being a boolean to specify whether they have (1) or don't (0) have permissions to that field.  We don't have to specify a complete array of permissions (ie. permission of edit, new, readonly, etc, etc), but rather only the ones we want specifically.  The reason being that the permissions array in the return value gets merged with the permissions that this record normally gets from the record permissions.

So if the record normally gives the permissions new=0, edit=1.  Then the return value from approval_level will merge with the original permissions to produce an array like this:

<code>
$permissions['new'] = 0;
$permissions['edit'] = 1;
</code>

=== Also See: ===

* [[How_to_granulate_permissions_on_each_field]]
* [[__field__permissions]]",,en,0
fields.ini_file,3,fields.ini_file,"==fields.ini File Reference==

[[toc]]

===Overview===

The fields.ini file is a configuration file which is associated with a single table of a database application.  It provides metadata about the table's fields to help Xataface dictate how they should be included in the application.  This includes metadata such as

* [[widget:type|Widget type]] - To specify the type of widget that should be used to edit content in the field (e.g. text, select, checkbox).
* [[widget:label|Label]] - The labels that can be used in column headers and on forms.
* [[widget:description|Help text]] - for forms to inform the user how data should be entered.
* [[group|Field Groupings]]
* [[widget:atts|widget:atts]] - To use javascripts in event handlers
* and more

Although a table doesn't need to have an associated fields.ini file in order for the application to work, each table can have one; and it is always located in the [[table configuration directory]].  For example, the fields.ini file for the [[people]] table would be located at [[Site Root]]/tables/people/fields.ini file.

===Syntax===

The fields.ini file uses [[standard INI syntax]] (just like the php.ini file), where each section corresponds to a column in the table. 

For example, consider a table ""people"" with columns ""first_name"", ""last_name"", and ""age"".  The fields.ini file for the people table could then contain sections for each of its columns as follows:

<code>
[first_name]

[last_name]

[age]
</code>

In this example the sections are empty (i.e. they have no directives, but we could easily add some directives:

<code>
[first_name]
    widget:description=""Please enter your first name""
    widget:label=""Given Name""

...etc...
</code>

Here we have told Xataface that the first name field should include some help text (using the [[widget:description]] directive) on its edit form.

===Example fields.ini file===
<code>

;; Global directives applied to every field (requires Xataface 1.2.6)
[__global__]
	visibility:list=hidden

[isbn]
widget:label = ISBN
visibility:list=visible


[copyright_year]
widget:label = ""Year""
widget:atts:size=4
visibility:list=visible

[categories]
widget:type=checkbox
vocabulary = book_categories

[media]
widget:type=checkbox
vocabulary = book_media

[borrower_id]
widget:type=select
vocabulary=users

[due_date]
widget:description = ""The date that the book is due to be returned to the library""
visibility:list=visible


[cover_art_url_small]
visibility:browse=hidden


[cover_art_url_medium]
;visibility:browse=hidden


[cover_art_url_large]
visibility:browse=hidden
visibility:find=hidden

[amazon_description]
widget:label = Description


[amazon_reviews]


[amazon_url]

[amazon_refresh_timestamp]
widget:type=static

[date_created]
timestamp=insert
widget:type = static


[date_modified]
timestamp=update
widget:type=static


[created_by]
widget:type=static


[modified_by]
widget:type=static

[notes]

</code>

This is an example from the [http://apps.weblite.ca/index.php?-action=view&-table=packages&package_id=%3D2 Library DB] application for the books table. 


===Field Directives===

The following directives may be added to a field's section of the fields.ini file to customize the field's behavior.  Some directives are not applicable to all fields.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[column:label]]
| Specifies a custom label to use in list view for the column.  If this is not specified, then the value of [[widget:label]] will be used.
| 1.3
|-
| [[column:legend]]
| Adds a small amount of help text to the column header for this field in list view.  Default is blank.  E.g. <nowiki><br/><img src=""http://media.weblite.ca/files/photos/Screen%20shot%202011-02-08%20at%205.05.55%20PM.png?max_width=640""/><br/></nowiki>In this photo it shows the text ""*Paper Uploaded"" set as the [[column:legend]] for ""field 1"".
| 1.3
|-
| [[date_format]]
| Specifies how the field should be formatted when displayed.  Takes same parameters as PHP [http://php.net/strftime strftime] function.
| 2.0
|-
| [[display]]
| Specifies the layout of the field on the edit form.  Most fields have an implicit value of ""inline"" meaning the widget and its label appear on the same line.  Textareas and htmlareas have an implicit value of ""block"" meaning that the label and widget appear in separate rows (label above the widget).  You can set this value explicitly also to override the layout of a field.
| 0.8
|-
| [[display_format]]
| A pattern that can be used to define the display format of the field.  This takes the same parameters as the PHP [http://php.net/sprintf sprintf] function.
| 2.0
|-
| [[encryption]]
| Primarily used with password fields, indicates the type of encryption that should be used to save the field.  Supports ""md5"", ""sha1"", ""encrypt"", and ""password"".
| 0.6
|-
| event.date
| For use by the [[Calendar Action]].  Indicates that the field stores the date of the record when interpreted as an event.  Possible values ""0"" or ""1"".
| 1.0
|-
| event.start
| For use by the [[Calendar Action]].  Indicates that the field stores the start time of the record when interpreted as an event.  Possible values ""0"" or ""1"".
| 1.0
|-
| event.end
| For use by the [[Calendar Action]]. Indicates that the field stores the end time of the record when interpreted as an event.  Possible values ""0"" or ""1"".
| 1.0
|-
| event.location
| For use by the [[Calendar Action]].  Indicates that the field stores the location of a record when interpreted as an event.  Possible values ""0"" or ""1"".
| 1.0
|-
| [[filter]]
| Boolean value (0 or 1) indicating whether this field should be [[filterable]] in [[list view]].
| 0.8
|-
| [[frozen_description]]
| The field description shown when the widget is frozen (i.e. uneditable).  If this is not specified, no field description is shown in this case.
| 1.2
|-
| [[group]]
| The name of the field group that this field belongs to.  Fields with the same ""group"" value will be rendered in the same field group on the form.
| 0.5
|-
| [[Key]]
| If you are using a View for the table you need to explicitly mark the fields that comprise the primary key.  E.g. Key=PRI
| 0.6

|-
| [[label_link]]
| An optional URL for the field label to link to.  This would usually be some ""help"" page that explains what the field is for.  The link will be a link in both the view and edit tabs.
| 1.1.3
|-
| [[ignore]]
| Boolean value (0 or 1) indicating whether this field should be ignored on the edit form.  This is handy if the field is going to be constantly updated in the background (via a cron job perhaps) and you don't want the edit form to interfere.
| 1.0
|-
| [[logo]]
| Boolean value (0 or 1) to indicate if this field should be treated as a logo field.  Logo fields are displayed in the upper left of the [[view tab]] for a record, and are assumed to contain an image.  If no logo field is explicitly specified, Xataface will make a best guess as to which field should be used.
| 0.7
|-
| [[money_format]]
| For fields containing monetary amounts, this specifies the format.  Takes same parameters as PHP [http://php.net/money_format money_format] function.
| 2.0
|-
| [[noLinkFromListView]]
| Boolean value (0 or 1) to indicate if this field should be linked when in list view (or in a related list).  Default value is 0 to indicate that the field IS linked.  It is common to use this directive when using a custom xxx__renderCell() method that contains its own links.
| 1.1
|-
| [[not_findable]]
| A flag to indicate that this field can not be used as part of a query. This is helpful if you want a field to remain completely confidential to prevent people from finding records based on the value of this field.  This flag is even necessary if the permissions for the field don't permit viewing the value of the field.
| 1.1
|-
| [[number_format]]
| For numeric fields, this indicates the number of decimal places to display when displaying this field.  E.g. 2
| 2.0
|-
| [[order]]
| The order of the field when laid out on forms and lists.  Can contain any floating point number or integer (e.g. 0, 10, -10, 235.4)
| 0.6
|-
| [[relationship]]
| Used only with complex fields that involve editing related records (e.g. [[grid]]).  This is the name of the relationship that the field should be edited.
| 0.8
|-
| [[repeat]]
| Boolean value (0 or 1) used in conjunction with a select widget to indicate whether to enable a multi-select.
| ?
|-
| [[section]]
| The name of the section that this field should belong to in the [[view tab]].
| 0.7
|-
| [[secure]]
| A boolean flag for use with [[container fields]] to indicate that it should use secure URLs for the file downloads (i.e. it will obey the application permissions).  Without this directives, uploaded files are served directly by apache and don't obey the Xataface permissions defined per record.
| 1.3
|-
| [[struct]]
| A boolean (0 or 1) value indicating whether this field is considered a structure.  A value of 1 indicates that this field is a structure and should not be truncated under any circumstances.  Normally fields are truncated at 255 chars in list view.  This is useful if the field contains XML or other structured data so that attempts to truncate it would destroy integrity.
| 1.1.2
|-
| [[tab]]
| If tabbed forms are enabled, then this specifies the name of the tab that this field belongs to on the edit form.
| 0.8
|-
| [[timestamp]]
| Indicates when a timestamp should be set in the field (only applicable for date and time fields).  Possible values are ""insert"" and ""update""
| 0.7
|}

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[title]]
| Boolean value (0 or 1) indicating whether this field should be treated as a title field.
| 0.7
|-
| [[transient]]
| Boolean value (0 or 1) indicating whether this field is a transient field or not.  A transient field is a field that is defined in the fields.ini file but not in the database.  Hence the values that are input into this field on the edit form are not saved to the database.
| 0.8
|-
| [[Type]]
| The data type of the field (note the capital ""T"" as Xataface is case sensitive).  This value is only overridden for [[container]] fields, however its value can be accessed programmatically for any field.
| 0.5
|-
| [[validators|validators:VALIDATOR_NAME]]
| A prefix for a validation type on the current field. (Replace ""VALIDATOR_NAME"" with the name of the validator to be used. e.g. required). There are many validators available to be used.
| 0.5
|-
| [[validators:VALIDATOR_NAME:message]]
| The message the should be displayed if the form fails to validator due to the ""VALIDATION_NAME"" validation rule.
| 0.5
|-
| [[viewgroup]]
| The name of the field grouping that this field will belong to in the view tab.  If this is not present, then it will be grouped according to the [[group]] directive.
| 1.0
|-
| [[visibility:browse]]
| Indicates whether the field should be visible in browse mode (i.e. in the ""view"" tab).  Possible values are ""visible"" and ""hidden"".
| 0.6
|-
| [[visibility:csv]]
| Indicates whether the field should be included in CSV exports.  Possible values are ""visible"" and ""hidden"". (1.0 beta 4)
| 1.0b4
|-
| [[visibility:find]]
| Indicates whether the field should be visible in find mode.  Possible values are ""visible"" and ""hidden""
| 1.0
|-
| [[visibility:list]]
| Indicates whether the field should be visible in list view.  Possible values are ""visible"" and ""hidden"".
| 0.6
|-
| [[visibility:update]]
| Indicates whether the field should be included in update and copy/replace forms.  Possible values are ""visible"" and ""hidden"".
| 1.3
|-
| [[vocabulary]]
| The [[valuelist]] that should be used as the options to select.  This is only applicable for fields that have options to select like a select list or a checkbox group.
| 0.5
|-
| [[widget:atts]]
| A namespace for attributes that should be added to the HTML widget.  This allows you to specify things like javascript events, styles, widget size, etc..
| 0.5
|-
| [[widget:columns]]
| For checkbox groups, this specifies the number of columns to use for laying out the checkboxes.
| 1.0
|-
| [[widget:description]]
| Help text to give the user a hint about how to edit the field's content.
| 0.1
|-
| [[widget:editor]]
| The type of HTML editor that should be used.  This is used only when [[widget:type]] is set to [[widget:type htmlarea|htmlarea]]

Acceptable values include:

* [http://www.fckeditor.net/ fckeditor] (default)
* [http://tinymce.moxiecode.com/ tinymce]  (version 0.6 or higher)
* [http://www.nicedit.com/ nicedit] (version 1.0 or higher)
| all
|-
| [[widget:editvalues]]
| Used with select lists to allow users to add values to the select list.  E.g. widget:editvalues=1
| 0.8
|-
| widget:focus
| Sets default focus. 0 or 1. (Javascript focus in a form)
| 0.6
|-
| [[widget:label]]
| The label that should be used for the current field on edit forms, column headings, and other relevant locations.
| 0.1
|-
| [[widget:question]]
| Text displayed just before the widget.  This is almost the same as [[widget:description]] except that this text is guaranteed to be displayed before the widget, whereas [[widget:description]] may be displayed below or beside the widget.
| 0.1
|-
| [[widget:type]]
| The type of widget that should be used (e.g. checkbox, select, text, etc..)
| 0.1
|-
| [[xml]]
| A flag for use with calculated fields (i.e. fields defined in the [[delegate class]] via the [[field__fieldname]] method) that will include the field in XML output produced by the [[export xml action]].  Default is 0, but setting this value to 1 wil cause the field to be included.
| 1.2.7
|}

===Applying Directives to All fields (__global__)===

Xataface 1.2.6 includes support for a [[__global__]] section that allows you to specify directives that should be applied to all fields.  These directives can be overridden on a field by field basis.  The [[__global__]] section can take all the same directives that a normal field section takes.


===widget:atts:class Values===

The widget:atts:class directive allows you to assign a CSS class to a field's widget.  There
are certain CSS classes that have meaning to Xataface and will cause additional functionality
to automatically be added to the field.  These built-in classes are listed below:

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[passwordTwice]]
| Applicable only to password fields.  If you set widget:atts:class=passwordTwice, then this will convert the password field into two fields whereby both fields need to match in order for submission to continue on the edit form. This operates as a password verification field.""
| 1.3rc2
|}



===Global Directives===

The following directives can be added to the beginning of the fields.ini file (before any field sections) to customize field groups and the table as a whole.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[__dependencies__]]
| A comma-delimited list of tables that this table is dependent upon for caching purposes.  E.g. if any table in this list is modified, then the query cache is cleared for queries on this table.  See this [http://xataface.blogspot.com/2009/06/using-query-caching-in-xataface.html blog article] for more information about query caching.
| 1.2
|-
| [[__isa__]]
| The name of the parent table of the current table.  This directive allows you to have a heirarchical structure amongst the tables in your application.
| 0.8
|-
| [[__source_tables__]]
| A comma-delimited list of tables that this table/view is derived from.  This is used with the query caching feature and is necessary to use this directive if the table is actually a view.  If this directive is not set, then any queries involving this view will not use the query cache because Xataface would have no way to discern the update time of the view.  See this [http://xataface.blogspot.com/2009/06/using-query-caching-in-xataface.html blog article] for more information about query caching.
| 1.2
|-
| [[__sql__]]
| Defines a custom select query to override the default select query for the current table.  (The default select query is generally ""select * from tablename"").
| 0.7
|-
| [[__prefs__]]
| Sets preferences for this table and its records.
| 1.0b4
|}


===Field Groups===

The [[group]] directive allows you to group multiple fields together so that they will be rendered in the same field group on forms.  
You can also configure these groups as a whole by defining a section named ""[fieldgroup:GROUPNAME]"" (where GROUPNAME is the name of the field group, corresponding to the [[group]] directive values for the fields)
in the fields.ini file.  This section provides a few basic directives to customize some aspects of the field group:

* label
* order
* description
* template
* more...

The most common use of these sections is to customize the label or order of groups, especially when there are multiple field groups in the table.
For example, suppose we have a table ""people"" with fields ""first_name"", ""last_name"", ""phone"", ""fax"", ""email"", ""address"", ""city"", and ""country"". 
Suppose these fields are grouped as follows:

* ""first_name"" and ""last_name""
* ""phone"", ""fax"", and ""email""
* ""address"", ""city"", and ""country""

so that the fields.ini file looks like:

<code>
[first_name]
    group=name
    
[last_name]
    group=last_name
    
[phone]
    group=contact
    
[fax]
    group=contact
[email]
    group=contact
    
[address]
    group=address
    
[city]
    group=address
    
[country]
    group=address

</code>

By default, the ""name"" group will appear first in the form, followed by ""contact"" and ""address"".  If we want to place ""address"" first we could add the following section to our fields.ini file:

<code>
[fieldgroup:address]
    order=-1
</code>

Since the default order value is 0 on other groups, setting the ""order"" parameter to -1 will place the ""address"" group before all others.

====Field Group Directives====

The following directives are applicable in a fieldgroup section:

{| class=""listing listing2""
|-
! name
! description
! version
|-
| [[fieldgroup order|order]]
| Specifies the order of the group with respect to other groups on the form.  Accepts any numerical value (e.g. 0, 1, -1, 25.43), with lower values appearing first.  Default value is 0.
| 0.6
|-
| [[fieldgroup label|label]]
| Specifies the label that should be used for the field group.
| 0.6
|-
| [[label_link]]
| Specifies a URL that the field group label should link to.
| 1.1.3
|- 
| [[fieldgroup template|template]]
| The path to a custom template that should be used to render the fields of the field group.
| 1.0
|-
| [[fieldgroup collapsed|collapsed]]
| Boolean value (0 or 1) indicating whether the field group should be collapsed by default (user can expand it).  
| 1.0
|}
","fields.ini directives ",en,0
getFeed,42,getFeed,"==getFeed() Delegate Class Method==

[[toc]]

===Synopsis:===

The getFeed() method of a table [[Delegate class methods|delegate class]] or [[Application Delegate Class|application delegate class]] returns an associative array of parameters to configure the [[Introduction_to_RSS_Feeds_in_Xataface|RSS feed]] for a particular table .  An RSS feed consists of the following components:

# '''title''' - The title of the RSS feed as it should appear in the subscribers' feed list.
# '''description''' - Describes the RSS feed.
# '''link''' - A link to the RSS feed
# '''syndicationURL''' - The URL to this RSS feed's site.

===Parameters===

# '''array''' $query - The HTTP query.  Contains information like the current table, current action, and search parameters.  This allows you to customize your RSS feed depending on the user's query parameters.

===Return Value===

The getFeed() method returns an associative array with the components of the RSS feed.  This array does not need to contain all possible keys, or even any keys.  Any keys that are omitted will simply use default values in the RSS feed.  The array may contain the following keys:

{| class=""listing listing2""
! Name
! Description
! Version
|-
| title
| The title for the RSS feed.  If this omitted, it will try to use the ''title'' directive of the ''[_feed]'' section of the [[conf.ini file]].  Failing that, it will try to generate an appropriate title for the feed depending on the current query.
| 1.0
|-
| description
| A Description for this RSS feed.  If this is omitted, it will try to use the ''description'' directive of the ''[_feed]'' section of the [[conf.ini file]].
| 1.0
|-
| link
| A link to the source page of the RSS feed.  If this is omitted, it will try to use the ''link'' directive of the ''[_feed]'' section of the [[conf.ini file]].
| 1.0
|-
| syndicationURL
| A link to the source page of the RSS feed.  If this is omitted, it will try to use the ''syndicationURL'' directive of the ''[_feed]'' section of the [[conf.ini file]].
| 1.0
|}

===Example===

<code>
function getFeed(&$query){
    return array(
        'title' => ""RSS feed for the "".$query['-table']."" table."",
        'description' => ""News and updates for automobiles"",
        'link' => df_absolute_url(DATAFACE_SITE_HREF),
        'syndicationURL' => df_absolute_url(DATAFACE_SITE_HREF)
    );
}

</code>

'''Note that RSS feeds will work perfectly well without defining this method.  This just allows you to customize one or more parameters of the RSS feed'''.

===See Also:===

* '''[[getFeedItem]]''' - A delegate class method available to both the [[Delegate class methods|table delegate classes]] to configure parameters for the particular items of the RSS feed.
* '''[[getRelatedFeed]]''' - A [[Delegate class methods|delegate class method]] available to both the [[Application Delegate Class|application delegate class]] and the [[Delegate class methods|table delegate classes]] to configure the [[Introduction to RSS Feeds in Xataface|RSS feed]] for a related records list.
* '''[[getRSSDescription]]''' - A delegate class method to override the description that appears for a particular record in an RSS feed.  (The same as the ''description'' parameter of the [[getFeedItem]] method.
* '''[[Introduction to RSS Feeds in Xataface]]''' - An overview of Xataface's RSS feed support.",,en,0
getFeedItem,41,getFeedItem,"==getFeedItem() Delegate Class Method==

[[toc]]

===Synopsis:===

The getFeedItem() method of a table [[Delegate class methods|delegate class]] returns an associative array of parameters for a record as it should appear as part of an [[Introduction_to_RSS_Feeds_in_Xataface|RSS feed]].  An RSS feed item consists of the following components:

# '''title''' - The title of the record as it appears in the RSS feed.
# '''description''' - The description of the record for the RSS feed.  This is really the body of the RSS feed item.
# '''link''' - The linkback URL if users want to know more about the record.
# '''date''' - The date that the record was posted/modified.
# '''author''' - The name of the person who posted this record.
# '''source''' - URL to the site where record originated from.

===Parameters===

# '''Dataface_Record''' &$record - The record that is being represented in an RSS feed.

===Return Value===

The getFeedItem() method returns an associative array with the components of the RSS feed.  This array does not need to contain all possible keys, or even any keys.  Any keys that are omitted will simply use default values in the RSS feed.  The array may contain the following keys:

{| class=""listing listing2""
! Name
! Description
! Version
|-
| title
| The record title as it appears in RSS feeds.  If this is omitted, the RSS feed will simply use the output of [http://dataface.weblite.ca/Dataface_Record Dataface_Record's] [http://dataface.weblite.ca/getTitle getTitle()] method.
| 1.0
|-
| description
| The record description.  This is used in the main body of the RSS feed.   If this is omitted, the RSS feed will use an HTML table that shows all of the field data in the record.  This value can also be overridden using the [[getRSSDescription]] method of the delegate class.
| 1.0
|-
| link
| The URL to this record.  If this is omitted it just points to the ''view'' tab for this record.  However you can direct it anywhere you like.  When the user clicks on the ""More Info"" link in his RSS reader it will direct him to this link.
| 1.0
|-
| date
| The date that this record was posted or last modified.  This is the date that an RSS reader will use to decide if it has already loaded the record yet.  If this is omitted it will try the [http://dataface.weblite.ca/Dataface_Record Dataface_Record's] [http://dataface.weblite.ca/getLastModified getLastModified()] method to obtain the last modified date of the record.  Failing that, it will use [http://dataface.weblite.ca/Dataface_Record Dataface_Record's] [http://dataface.weblite.ca/getCreated getCreated()] method to try to obtain the creation date of the record.  This date should be a unix timestamp.
| 1.0
|-
| author
| The name of the user who posted this record.  If this is omitted, then it will try to use [http://dataface.weblite.ca/Dataface_Record Dataface_Record's] [http://dataface.weblite.ca/getCreator getCreator()] method.  Failing that, it will use the value of the ''default_author'' parameter in the ''[_feed]'' section of the [[conf.ini file]].  If that is not defined, then it simply uses the string ""Site Administrator"".
| 1.0
|-
| source
| The source URL where the feed is to have originated.  If none is specified, then it will use the value of the ''source'' parameter in the ''[_feed]'' section of the [[conf.ini file]].  Failing that, it will simply use the URL to the application.

Note that you can alternatively define this value using the [[getFeedSource]] method.
| 1.0
|}

===Example===

<code>
function getFeedItem(&$record){
    return array(
        'title' => ""News Item: "".$record->getTitle(),
        'description' => $record->display('News Body'),
        'link' => $record->getPublicLink(),
        'date' => strtotime($record->val('last_modified')),
        'author' => $record->val('posted_by'),
        'source' => 'http://www.example.com'
    );
}

</code>

'''Note that RSS feeds will work perfectly well without defining this method.  This just allows you to customize one or more parameters of the RSS feed'''.

===See Also:===

* '''[[getFeed]]''' - A delegate class method available to both the [[Application Delegate Class]] and the [[Delegate class methods|table delegate classes]] to configure the RSS feed as a whole (not just for an individual item in the RSS feed.
* '''[[getRelatedFeed]]''' - A [[Delegate class methods|delegate class method]] available to both the [[Application Delegate Class|application delegate class]] and the [[Delegate class methods|table delegate classes]] to configure the [[Introduction to RSS Feeds in Xataface|RSS feed]] for a related records list.
* '''[[getRSSDescription]]''' - A delegate class method to override the description that appears for a particular record in an RSS feed.  (The same as the ''description'' parameter of the [[getFeedItem]] method.
* '''[[Introduction to RSS Feeds in Xataface]]''' - An overview of Xataface's RSS feed support.",,en,0
getRegistrationActivationEmailInfo,17,getRegistrationActivationEmailInfo,"==getRegistrationActivationEmailInfo() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the default information that is used to send the registration activation email (the email that the user receives when they register).

This should return an associative array with the keys:

* subject - The subject of the activation email.
* message - The message body of the activation email.
* parameters - The parameters to be used in the mail() function for the activation email.
* headers - The headers to use in the mail() function for the activation email.


===Signature===

function getRegistrationActivationEmailInfo( Dataface_Record &$record, string $activationURL ) : array

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| &$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&$record, $activationURL){
        return array(
            'subject' => 'Welcome to the site.. Activation required',
            'message' => 'Thanks for registering.  Visit '.$activationURL.' to activate your account',
            'headers' => 'From: webmaster@example.com' . ""\r\n"" .
                          'Reply-To: webmaster@example.com' . ""\r\n"" .
                          'X-Mailer: PHP/' . phpversion()
             );
            
        
       
    }
}
</code>

===Example 2: Only override the subject===

<code>
<?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&$record, $activationURL){
        return array(
            'subject' => 'Welcome to the site.. Activation required'
             );
            
        
       
    }
}
</code>


===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
getRegistrationActivationEmailMessage,19,getRegistrationActivationEmailMessage,"==getRegistrationActivationEmailSubject() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the default registration activation email message body (the email that the user receives when they register).


===Signature===

function getRegistrationActivationEmailSubject( Dataface_Record &$record, string $activationURL ) : string

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| &$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&$record, $activationURL){
        return 'Thanks for registering.  Please visit '.$activationURL.' to activate.';   
    }
}
</code>


===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
getRegistrationActivationEmailSubject,18,getRegistrationActivationEmailSubject,"==getRegistrationActivationEmailSubject() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the default registration activation email subject line (the email that the user receives when they register).


===Signature===

function getRegistrationActivationEmailSubject( Dataface_Record &$record, string $activationURL ) : string

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| &$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&$record, $activationURL){
        reeturn 'Welcome to the site.. Activation required';   
    }
}
</code>


===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
group,28,group,"==group directive in [[fields.ini file]]==

The group directive allows you to declare that certain fields of your table should be grouped together on the edit form and the view tab (and other logical places).  For example, fields like address, city, state, country, postal_code would likely be grouped together as address_info.  Grouping the fields together will make the fields appear in a section of their own in the view tab and the edit form.

E.g.  In your fields.ini file:

<code>
[address]
   group=address_info

[city]
    group=address_info

[state]
    group=address_info

[country]
    group=address_info

[postal_code]
    group=address_info

</code>


===Configuring the Group as a Whole===

You can also configure your group in the fields.ini file by adding a '''fieldgroup:NAME''' section, where '''NAME''' is the name of the group.  E.g.
<code>
[fieldgroup:address_info]
    label=""Address Information""
    description = ""Please enter your address information below""
</code>

====See also:====

* [[fields.ini file]] - Scroll down to the '''Field Groups''' section.",,en,0
How_to_Add_Custom_Sections_to_View_Tab,52,How_to_Add_Custom_Sections_to_View_Tab,"==How to Add Custom Sections to the View tab==

[[toc]]

The ''View'' tab is intended to give the user a detailed view of the contents of a record.  By default it shows the values of each non-empty field grouped into their appropriate field groups.  It also shows the most recent 5 related records from each relationship in the record.  You can also add your own sections by implementing the [[section__xxx]] method of the delegate class.

==Example 1: A ""Hello World"" Section==

We'll start by adding a simple section that simply displays ""Hello World"" to the user.  In the delegate class for your table, add the following method:
<code>
function section__hello(&$record){
    return array(
        'content' => 'Hello World!!!',
        'class' => 'main'
    );
}
</code>

Now if you reload our application and click on the ""View"" tab for any of the records in the database, you'll notice a section labelled ''hello'' with the text ''Hello World!!!'' in it.

Let's dissect the above code so that we can better understand what is going on here.

# The function ''section__hello()'' defines a section named ''hello''.  If you wanted to define a section named ''foo'' you would call the function ''section__foo()''
# This function returns an array with the keys ''content'', and ''class''.
# The ''content'' key points to the actual HTML content of the section.  In this case it is simply the text ''Hello World!!!''.
# The ''class'' key defines where the section should be displayed.  It accepts values of ''left'' and ''main'' only.  If it is set to ''left'', then the section will be displayed in the left column.  A value of ''main'' indicates that it should be displayed in the main column.

===Customizing the Section Label===

''hello'' is a boring label, so let's add our own custom label by adding the ''label'' key to the array returned by our method:
<code>
function section__hello(&$record){
    return array(
        'content' => 'Hello World!!!',
        'class' => 'main',
        'label' => 'Message of the Day'
    );
}
</code>

Now if you load the view tab of your application, you'll notice that the section has a heading ""Message of the Day"".

===Customizing the Section Order===

A section can also specify an ''order'' attribute to define the order in which this section should appear.  It defaults to 0 which may cause the section to appear at the top of the view tab.  You can push it to the bottom of the view tab by assiging a higher number to the ''order'' attribute:
<code>
<code>
function section__hello(&$record){
    return array(
        'content' => 'Hello World!!!',
        'class' => 'main',
        'label' => 'Message of the Day',
        'order' => 10
    );
}
</code>

Now if you reload the view tab you'll notice that the section has moved to the bottom of the page.",,en,0
How_to_authenticate_users_with_LDAP_or_Active_Directory,64,How_to_authenticate_users_with_LDAP_or_Active_Directory,"==How to authenticate users with LDAP or Active Directory==

",,en,0
Customizing_the_look_and_feel_of_a_row_or_a_cell,62,Customizing_the_look_and_feel_of_a_row_or_a_cell,"==How to customize the look and feel of elements in the list view==

===Create a method in a delegate class===

In the delegate class, the method ''css__tableRowClass'' is implemented, like in this example :

<code>class tables_journal_interventions {
function css__tableRowClass(&$record){
    if ( !$record->val('fermeture')){
        return 'intervention_close';
    }
    else return '';
} 
}
</code>

Here the function tests a condition : is there a value in the field ''fermeture'' ?

===Add the class in a CSS stylesheet===

Now the class is created in a CSS stylesheet.

<code>td.intervention_close {
        background-color: #FFE6E6 !important;
    } </code>

This is a class for each cell, the <td> tag. The ''!important''  attribute is added to be sure that this information has precedence over all the others. It is better to add this class in a [http://xataface.com/documentation/how-to/custom_javascripts custom CSS stylesheet].

===Remarks===

Beware that some versions of IE don't respect the background-color property on the <tr> tag, so it is probably better to write:

<code>

    tr.intervention_close td {
        background-color: #FFE6E6;
    }</code>

i.e. to apply the background color to the individual cells. ",,en,0
How_to_granulate_permissions_on_each_field,63,How_to_granulate_permissions_on_each_field,"==How to granulate permissions on each field==

To reach this aim, there is the method fieldname__permissions to place into the delegate class of the table. 

===Getting the role===

First it is necessary to know the user's role. For this, the method getUser() is added in the class :
<code>function getUser(&$record){
  $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
return $user;
}</code>


===Setting up the permissions for each field===

Next, the permissions are built for each column or field where they are needed, like in this example where the method name is formed with the field name, followed by 2 underscores then by ''permissions'' :

<code>function fieldname__permissions(&$record){

$the_user =$this->getUser($record);
$user=$the_user->val('identifiant');
if ( !$user) return Dataface_PermissionsTool::NO_ACCESS();

    if ( $user=='demande' ){
        return Dataface_PermissionsTool::ALL();
    } elseif ($user=='admin'){
 return Dataface_PermissionsTool::ALL();
}
else {
        return Dataface_PermissionsTool::READ_ONLY();
    }
}</code>


=== Also See ===

* [[viewable_editable_fields]] - How to make a field editable for some users and only viewable for some other users  
* [[no_access_text]] - Replace the default NO ACCESS permission text with another text.
* [[__field__permissions]] - Returns the default permissions for a field of a given record.
* [[Delegate_class_methods#toc5|Permissions]] - other Delegate class methods",,en,0
Introduction_to_RSS_Feeds_in_Xataface,40,Introduction_to_RSS_Feeds_in_Xataface,"==Introduction to RSS Feeds in Xataface==

[[toc]]

A default Xataface application provides RSS feeds to any found set in your application.  This article explains a little bit about RSS and how you can configure Xataface to give you the desired results for your RSS feed.

===What is RSS?===

From [http://en.wikipedia.org/wiki/RSS_(file_format) Wikipedia's RSS article]:

""RSS is a family of Web feed formats used to publish frequently updated works such as blog entries, news headlines, audio, and videoin a standardized format.[2] An RSS document (which is called a ""feed"", ""web feed"",[3] or ""channel"") includes full or summarized text, plus metadata such as publishing dates and authorship. Web feeds benefit publishers by letting them syndicate content automatically. They benefit readers who want to subscribe to timely updates from favored websites or to aggregate feeds from many sites into one place. RSS feeds can be read using software called an ""RSS reader"", ""feed reader"", or ""aggregator"", which can be web-based or desktop-based. A standardized XML file format allows the information to be published once and viewed by many different programs. The user subscribes to a feed by entering the feed's URI (often referred to informally as a ""URL"", although technically, those two terms are not exactly synonymous) into the reader or by clicking an RSS icon in a browser that initiates the subscription process. The RSS reader checks the user's subscribed feeds regularly for new work, downloads any updates that it finds, and provides a user interface to monitor and read the feeds.""

In a way RSS replaces email subscriptions so that you can subscribe to receive updates when content is added or changed on websites that you monitory.  This way you can monitory these changes in your RSS reader so that your email box doesn't get clogged up.

===Using RSS in Xataface===

Xataface allows you to subscribe to:

# Entire tables
# Any found set
# Changes to a particular record
# Related record lists

====Example 1: Subscribing to receive news updates====

A user wants to be alerted whenever a new item is inserted into the ''news'' table, so he navigates to the ''list'' tab of the ''news'' table, and clicks the RSS Feed icon in the upper right.  If he has an RSS reader application set up, this is all he has to do to subscribe to the RSS feed for the ''news'' table.  When new records are inserted, he'll receive alerts in his RSS reader.

====Example 2: Subscribing to receive found set updates====

A user wants to be alerted whenever a new item is inserted into the ''news'' table that contains the phrase ""Buffalo Bills"", because he is a Buffalo Bills fan.  So he navigates to the ''news'' table, and does a search for the phrase ""Buffalo Bills"".  Then he clicks on the ""RSS Feed"" icon in the upper right of the result set list.  If he has an RSS reader application set up, this is all he has to do to subscribe to the RSS feed for ''news'' items containing the phrase ""Buffalo Bills"".  Whenever a new item is posted with this phrase, he will be notified via RSS of the new record.

====Example 3: Subscribing to a related list====

Suppose you want to receive updates whenever a particular author adds a book to his list of published works.  Further suppose this is represented by a relationship between the ''authors'' table and the ''books'' table named ''publications''.  You can subscribe to the RSS feed for his publications by navigating to the ''publications'' tab for that author, then clicking on the ""RSS Feed"" icon in the upper right.  Now whenever this author adds a new book to his publications list, you'll be notified via RSS.



===Example usage in Xataface===

# A user wants to be alerted whenever a new item is inserted into the ''news'' table, so he navigates to the ''list'' tab of the ''news'' table, and clicks the RSS Feed icon in the upper right.  If he has an RSS reader application set up, this is all he has to do to subscribe to the RSS feed for the ''news'' table.  When new records are inserted, he'll receive alerts in his RSS reader.
# A user wants to be alerted whenever a new record about ""Wayne Gretzky"" is inserted in to the ''news'' table.  He navigates to the ''news'' table, then performs a search for ""Wayne Gretzky"" using the top right search box.  Then, he clicks on the ""RSS Feed"" icon in the upper right of the result list.  Now, whenever a new item is inserted with the phrase ""Wayne Gretzky"", the user will be notified via RSS.

===Configuring RSS Feeds===

As with everything else in Xataface, you can configure your RSS feeds to appear just as you want them to.  The following delegate class methods are available to be defined in the table delegate class for your feed:

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getFeedItem]]
| For RSS Feeds, overrides the defaults and returns an associative array with feed elements for a particular record
| 1.0
|-
| [[getFeed]]
| For RSS feeds, overrides the default feed for a query, returning an array of feed items.
| 1.0
|-
| getFeedSource
| Overrides the default feed source parameter for an RSS feed.
| 1.0
|-
| getRSSDescription
| Overrides the default generated RSS description for a record.
| 1.0
|-
| [[getSingleRecordSearchFeed]]
| Overrides the default feed for a subsearch within a record.  This works identically to the [[getFeed]] method except that it takes 2 parameters: one for the current record, and a second parameter for the query.
| 1.2.3
|}

==Example Configuration==

There are 2 parts to configuring your RSS feeds.

# Configuring the feed as a whole
# Configuring the feed items (that is each record that will appear in your RSS feed).

===Configuring the Feed as a whole===

For configuring the feed as a whole, we have 2 options.  We can specify the title, description, and link for the feed in the ''[_feed]'' section of your [[conf.ini file]].  This is sort of a ""one size fits all"" approach where all feeds generated from your application will share the same title.

E.g.

<code>
[_feed]
    title=""My Site News""
    description=""News updates from my site""
    link=""http://www.example.com""
</code>

However, if we want our feed's information to depend on the user's query (e.g. what the user was searching for, or which table the feed is generated on, we have more flexibility if we define the [[getFeed]] method in either the [[Application Delegate Class|application delegate class]] or the [[Delegate class methods|table delegate class]].  E.g.

<code>
function getFeed($query=array()){
    $params = array();
    if ( @$query['-search'] ) $params['title'] = '""'.$query['-search'].'"" results';
    else $params['title'] = 'All records from my table';
    return $params;
}
</code>

Notice that I don't need to define all possible parameters.  Any parameters that I don't define will be provided automatically by Xataface, or it will simply use the values specified in your ''[_feed]'' section of the [[conf.ini file]].

===Configuring Feed Items===

Configuring the feed items is quite important for ensuring that subscribers are seeing what you want them to see in the RSS feed.  Xataface tries to guess appropriate content for your feed items if you don't specify it explicitly, but you'll likely want to tweak it a little bit to make the feed look more polished for your purposes.

Use the [[getFeedItem]] [[Delegate class methods|delegate class method]] to specify how a feed item behaves (e.g. the title, content, date, author, link).

E.g.

<code>
function getFeedItem(&$record)){
    return array(
        'description' => $record->val('body')
    );
}
</code>

Once again, notice that we don't need to specify all available options.  Only those options that we want to override.  In this case we want the description of the feed item to simply display the body of our news item.  The description of an RSS feed item is effectively the body text that the user sees why they click on an item in their news reader, so this is quite important.


","RSS Feeds",en,0
relationships.ini_file,20,relationships.ini_file,"==relationships.ini File Reference==

[[toc]]

===Overview===

The relationship.ini file is a configuration file which is associated with a single table of a database application.  It provides metadata about the table's relationships to other tables to help Xataface dictate how they should be included in the application.  

===Field Directives===

The following directives may be added to a field's section of the relationship.ini file to customize the field's behavior.  Some directives are not applicable to all fields.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| __sql__
| The SQL query that defines this relationship. 
| all
|-
| [[action:visible]]
| A boolean value (0 or 1) that indicates whether this relationship should be visible in the record tabs.
| all
|-
| [[action:condition]]
| An expression that evaluates to a boolean that determines at runtime whether the relationship's tab should appear in the record tabs.
| all
|-
| [[action:delegate]]
| The name of an alternative action that can be used instead of the standard related records list.  One possible value for this would be ""related_records_checkboxes"" which would provide the user with a checkbox group to select the records that should be part of the relationship rather than the usual related record list.
| 1.0
|-
| [[section:limit]]
| Integer.  The number of records to show in the related record sections (in the view tab).  Default is 5.
| 1.0
|-
| [[section:visible]]
| Boolean value (0 or 1) indicating whether the relationship information should appear as a section on the left side of the table.
| all
|-
| [[actions:addexisting]]
| Boolean value (0 or 1) indicating whether the action to add existing records should exist in this relationship.
| all
|-
| [[actions:addnew]]
| Boolean value (0 or 1) indicating whether the action to add news records should exist in this relationship.
| all
|-
| [[action:label]]
| The label that appears in the relationship tab for this relationship. 
| all
|-
| [[list:type]]
| Optional type of list to use for the related record list.  Possible value: ""treetable""
| 0.8
|-
| [[meta:class]]
| An optional special class to assign to the relationship.  E.g. ""parent"" or ""children"".
| 0.8
|-
| [[metafields:order]]
| If the relationship should have a default order this specifies the field that should be used for this sort. 
| all
|-
| [[visibility:fieldName]]
| If given the value hidden will make that particular fieldName disappear in the relationship.  This will only be applied for that particular relationship.  
| all
|-
| [[visibility:find]]
| If given the value hidden this will cause the related fields to not appear on the find form.  Normally each relationship is provided a section of the find form to enable users to find records that contain at least one match in the related records.  
| 1.3rc4
|-
| [[vocabulary:existing]]
| Specifies a valuelist that can be used to provide the set of records that can be added to this relationship.  If target table has a single column primary key then the valuelist should use the primary key for the value.  If it has a multi-column primary key, then the value should be in the form key1=value1&key2=value2 etc...  See also [[relationshipname__getAddableValues]] delegate class method for a programatic solution.
| 1.0
|}

==Relationship Permissions==

See [[Relationship Permissions]]

==See Also==

* [http://xataface.com/documentation/tutorial/getting_started/relationships Getting started with relationships]","relationships.ini file, relationships",en,0
sendRegistrationActivationEmail,16,sendRegistrationActivationEmail,"==sendRegistrationActivationEmail() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the sending of an activation email to the user.

===Signature===

function sendRegistrationActivationEmail( Dataface_Record &$record, string $activationURL ) : mixed

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| &$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {

    function sendRegistrationActivationEmail(&$record, $activationURL){
        // mail the admin to let him know that the registration is occurring.
        $username = $record->val('username');
        $email = $record->val('email');
        
        mail($email, 'Welcome to the team', 
            'Welcome '.$record->val('username').
            '.  You have been successfully registered.  
             Please visit '.$activationURL.' to activate your account'
        );
    }
}
</code>

===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
tab,48,tab,"==tab directive of the fields.ini file==

[[toc]]

The ''tab'' directive of the [[fields.ini file]] specifies which tab of the record edit form a field should be displayed on.  Xataface supports multiple tabs on the edit form by way of this ''tab'' directive.  If no fields contain the ''tab'' directive then all fields are displayed in a single tab (named ''__main__'').

==Example 1: Placing address info on separate tab==

Consider the following ''people'' table: 
<code>
CREATE TABLE `people` (
    person_id int(11) not null auto_increment primary key,
    first_name varchar(32) not null,
    last_name varchar(32) not null,
    address varchar(100),
    city varchar(100),
    province varchar(100),
    country varchar(100),
    postal_code varchar(20)
)
</code>

We want to split the fields into two tabs:
* Personal Info
* Address Info

===Splitting form into tabs===
We'll do this in two steps.  We use the ''tab'' directive to assign all address-related fields to the ''address_info'' tab.  In the tables/people/fields.ini file:
<code>
[address]
    tab=address_info

[city]
    tab=address_info

[province]
    tab=address_info

[country]
    tab=address_info

[postal_code]
    tab=address_info
</code>

Now, when we load the edit form of the ''people'' table, we see two tabs:

* __main__
* address_info

<nowiki>
<img src=""http://media.weblite.ca/files/photos/Picture 9.png?max_width=640""/>
<img src=""http://media.weblite.ca/files/photos/Picture 10.png?max_width=640""/>
</nowiki>

''__main__'' is the name assigned to the default tab (for all fields that don't have a tab defined explicitly.


===Customizing the tab labels===

Next we will customize the tab labels by adding the following to the beginning of the [[fields.ini file]]:
<code>
[tab:__main__]
    label=""Personal Information""

[tab:address_info]
    label=""Address Information""
</code>

<nowiki>
<img src=""http://media.weblite.ca/files/photos/Picture 11.png?max_width=640""/>
<img src=""http://media.weblite.ca/files/photos/Picture 12.png?max_width=640""/>
</nowiki>


===Reordering the tabs===

If we want to reorder the tabs so that the ''address_info'' tab comes first, we would just reorder the definitions of the tabs:
<code>
[tab:address_info]
    label=""Address Information""

[tab:__main__]
    label=""Personal Information""
</code>

<nowiki>
<img src=""http://media.weblite.ca/files/photos/Picture 13.png?max_width=640""/>
</nowiki>

===Try This Example App===

You can try this tiny sample application out [http://dev.weblite.ca/tab_test here].",,en,0
checkbox,69,checkbox,"==The checkbox widget==

In the [[fields.ini file]] you can specify a field to be edited using a checkbox widget by setting [[widget:type]] to [[checkbox]].  A checkbox widget can function in 2 different ways depending on the parameters that you assign to the field.

[[toc]]

===Example 1: A TinyInt (boolean) field===

Suppose our table has a tinyint field named ""Active"" which specifies whether the record is currently in use.  This field will store a value of either 0 or 1.  So we configure this field in our [[fields.ini]] file to use a checkbox widget as follows:

<code>
[Active]
  widget:type=checkbox
</code>

Results:

[[Image:http://media.weblite.ca/files/photos/Picture%2024.png?max_width=640]]

===Example 2: A repeating field (multiple checkboxes for one field===

Checkboxes can store multiple values in a single field by setting the [[vocabulary]] directive and applying it to a varchar or text field.  In this case there will be one value saved per line.  

In this example, suppose we have a varchar field named '''categories''' which uses the '''categories''' [[valuelist]] to specify the different categories that can be checked at any given time.  Our [[valuelists.ini file]] might look like:
<code>
[categories]
    __sql__ = ""select id,name from categories""
</code>

And our [[fields.ini file]] looks like:
<code>
[categories]
    widget:type=checkbox
    vocabulary=categories
</code>
* Note that you don't need to name the field the same as the valuelist.  It just worked out this way.

Now if we save a record with categories 1, 3, and 5 checked, then the categories column of our row in the database will store something like:
<code>
1
3
5
</code>
i.e. one category id per line.  Note that using this method, your database will not be normalized because you are storing multiple values in a single field.  However in many applications this is sufficient.

Results:

[[Image:http://media.weblite.ca/files/photos/Picture%2025.png?max_width=640]]

===Example 3: Using a ""Categories"" relationship===

""""""(Note: This example requires Xataface version 1.2 or higher)""""""

Example 2 above shows how we can easily add and remove a record from multiple categories using checkboxes.  However it required multiple pieces of information to be stored in a single database field which may or may not be advantageous for your database design.  If you're looking for a more normalized database schema you would probably design your database as follows for this case:

# Books table - Stores all of the books.
# Categories table - Stores all of the categories
# Book_Categories table - Stores mapping of books to categories.

With out table structure we will first want to define a relationship from Books to Categories to reflect the connection between books and categories.  The [[relationships.ini file]] for this might look like:

<code>
[categories]
    Books.Book_ID=""$Book_ID""
    Book_Categories.Category_ID=Categories.Category_ID
</code>

And our [[fields.ini file]] for the Books table might look like:
<code>
[categories]
    widget:type=checkbox
    transient=1
    relationship=categories
</code>
* Note that there is no need for our field to be named the same as our relationship.  It just turned out this way.  Also note that we used the transient=1 flag here because the Books table no longer has a categories field in the database.  This field is defined purely for the benefit of the edit form so that we will get a checkbox group to select the book's categories.

Results:
[[Image:http://media.weblite.ca/files/photos/Picture%2025.png?max_width=640]]

==Related Parameters==

# [[vocabulary]] - Assigns a valuelist to be used as the options for this checkbox group.
# [[repeat]] - A boolean value indicating whether this field should be treated as a 'repeating field'.  A repeating field is one with multiple checkboxes.  By default the checkbox widget operates as a single checkbox that controls a boolean value.
# [[relationship]] - (Only applicable to [[transient]] fields).  If the [[relationship]] directive is set then this field can be used to add/remove records from a relationship.",,en,0
filter,27,filter,"==The filter attribute of the [[fields.ini file]]==

The filter attribute with a value of 1 specifies that a field should be used as a filter field in list view.  In list view, any filter fields will provide a select list with all of the possible values in that field.  Selecting one of the items in this list will filter the results to only show records of that value.

===Example 1: Year, Make, Model===

The Fuel Economy Database has three fields with filter=1 : Year, Make, and Model.  I.e., in their fields.ini file we have something like:

<code>
[Year]
    filter=1

[Make]
    filter=1

[Model]
    filter=1
</code>

This causes 3 select lists to appear in list view.  See the application [http://fueleconomydb.com/index.php?-action=list here] and notice the select lists for Year, Make, and Model just above the list of results.

If you are filtering on a field where an ID is stored in the DB but you are using a vocabulary to associate it with a value, then it will still be sorted on the ID.

If you want to sort on value then you should add a [[Grafted fields|grafted field]] with the value using the __sql__ directive of the fields.ini file, then use that grafted field as your filter field, like the following:

<code>
__sql__ = ""select a.*, b.foo_name from a left join b on a.foo_id=b.foo_id""

[foo_name]
filter=1
</code>
",,en,0
permissions.ini_file,26,permissions.ini_file,"==The permissions.ini File==

[[toc]]

The permissions.ini file stores custom permissions and roles that can be used by an application.  It is an optional file that should be placed in the application root directory (i.e. the same directory where your conf.ini, and index.php files are located).

The permissions.ini file allows you to define two things:

# Permissions
# Roles (i.e. sets of permissions).

Permissions and roles are used throughout Xataface to limit access to actions, records, fields, and relationships.  For example, each action in your application can specify a permission that is necessary to perform the action.  Your delegate classes may include getPermissions() methods to define what permissions a user gets when interacting with different records.  This file (permissions.ini) simply defines the permissions that can be used by your application.  It doesn't actually assign those permissions.  Assigning permissions is the job of the getPermissions() (or getRoles()) method.

===Defining Permissions===

Permissions are defined by standalone properties in the beginning of the permissions.ini file.  For example, if you were desiging a proof-reading application, you might need permissions for ""submit_for_proof"", or ""approve_text"" to correspond with the submitting a document to be proof-read, and approving a document's proof.  In this case we would have the following at the beginning of our permissions.ini file:

<code>
submit_for_proof = Submit a document to be proofread
approve_text = ""Approve this document's proof""
</code>

The left side of the equals sign is the name of the permission.  The right side contains a human readable description of the permission and what it is for.

===Limiting Access to Actions based on Permissions===

At this point these permissions don't do anything.  In order to be useful we need reference these permissions from an action or a section.  For example, let's create an action called ""submit_for_proof"" which displays a form for a user to submit a document record to be proofread.

Our actions.ini file entry might look something like:

<code>
[submit_for_proof]
    url=""{$this->url('-action=submit_for_proof')}""
    label=""Submit document for proof""
    category=record_actions
    permission=submit_for_proof
    template=submit_for_proof.html
</code>

And for completeness, since this make-believe action specifies th ""submit_for_proof.html"" template, we'll create the ""submit_for_proof.html"" template in the templates directory:

<code>
<html><body>You have permission to perform this action.</body></html>
</code>

===Defining Who Get's Which Permissions===

Finally, in order to benefit from permissions, your application has to decide that it is going to use permissions (unless you define a getPermissions() method, users are granted ALL permissions by default.  Hence if you try to access our submit_for_proof action, we'll see it without any problem.  Regardless of who we are.  So let's create a simple, but restrictive getPermissions() method in our application delegate class:

<code>
<?php
class conf_ApplicationDelegate {
    function getPermissions(&$record){
        return Dataface_PermissionsTool::READ_ONLY();
    }
}
</code>

Now if we try to access our submit_for_proof action it will give us a ""Permission Denied"" message, because we are only granted READ ONLY permissions (which is a role that includes the view permission and some others - but not our custom ""submit_for_proof"" permission.

Now we'll make a small modification to our getPermissions() method to provide us with our submit_for_proof permission:

<code>
<?php
class conf_ApplicationDelegate {
    function getPermissions(&$record){
        $perms =  Dataface_PermissionsTool::READ_ONLY();
        $perms['submit_for_proof'] = 1;
        return $perms;
    }
}
</code>

Now if we try to access our submit_for_proof action, it will show us our template with no error messages (hopefully).


===Roles===

Roles are sets of permissions.  They are defined in the permissions.ini file as sections with lists of included permissions.  It might be handy to create roles such as EDITOR or MANAGER which contain sets of permissions that are meant to be assigned to users of those types.  For example an EDITOR may have the view and edit permissions, but not the delete permission.  A MANAGER might have the view, edit, and delete permissions.  You can define these two roles in the permissions.ini file as follows:

<code>
[EDITOR]
    view=1
    edit=1

[MANAGER]
    view=1
    edit=1
    delete=1
</code>

Then we could assign these roles to users using the Dataface_PermissionsTool::getRolePermissions() method:

<code>
function getPermissions(&$record){
    $user =& Dataface_AuthenticationTool::getInstance()->getLoggedInUser();
    if ( $user and $user->val('role') == 'EDITOR' ){
        return Dataface_PermissionsTool::getRolePermissions('EDITOR');
    } else if ( $user and $user->val('role') == 'MANAGER' ){
        return Dataface_PermissionsTool::getRolePermissions('MANAGER');
    }
    return Dataface_PermissionsTool::READ_ONLY();
}
 </code>

Or equivalently we could use the getRoles() method of our delegate class instead of getPermissions():

<code>
function getRoles(&$record){
    $user =& Dataface_AuthenticationTool::getInstance()->getLoggedInUser();
    if ( $user and $user->val('role') == 'EDITOR' ){
        return 'EDITOR';
    } else if ( $user and $user->val('role') == 'MANAGER' ){
        return 'MANAGER'
    }
    return 'READ ONLY';
}
</code>

===Xataface Core Permissions & Roles===

Xataface is distributed with its own permissions.ini file that defines some core permissions and roles.  You can look at this permissions.ini file (located in the Xataface directory) to see what the format should look like.  Any settings you place in your application's permissions.ini file will augment or override settings in Xataface's file.

Some core permissions include:


{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| view
| Permission to view a record or field.  This permission is required to access the view tab, and several other details tabs.
| 0.6
|-
| list
| Permission to access the list tab.
| 0.6
|-
| calendar
| Permission to access the calendar tab.
| 0.6
|-
| edit
| Permission to edit a record or field.  This also gives access to the edit tab.
| 0.6
|-
| new
| Permission to edit a record or field for the purpose of creating a new record.  This permission is required to access the new record form.
| 0.6
|-
| select_rows
| Permission to select rows in list view to perform actions on them.
| 0.6
|-
| post
| Permission to post a record using HTTP POST
| 0.6
|-
| copy
| Permission to copy a record.
| 0.6
|-
| update_set
| Permission to perform an update on a result set (i.e. access the update set action).
| 0.8
|-
| add new related record
| Permission to add a new record to a relationship.  See [[Relationship Permissions]]
| 0.6
|-
| add existing related record
| Permission to add an existing record to a relationship.  See [[Relationship Permissions]]
| 0.6
|-
| view related records
| Permission to view the records in a relationship. See [[Relationship Permissions]]
| 1.0
|-
| delete
| Permission to delete a record.
| 0.6
|-
| delete found
| Permission to access the delete found set action (to delete multiple records at a time).
| 0.6
|-
| show all
| Permission to access show all records action.
| 0.6
|-
| remove related record
| Permission to remove a record from a relationship.  See [[Relationship Permissions]]
| 0.6
|-
| delete related record
| Permission to delete a record in a relationship.  This is stronger than the remove related record permission in that it allows the user to delete the record from the database.  See [[Relationship permissions]]
| 0.6
|-
| find
| Permission to perform the find action.
| 0.6
|-
| import
| Permission to perform the import action (to import records into the database).
| 0.6
|-
| export_csv
| Permission to perform the Export CSV action (to export the result set in comma-separated-value format).
| 0.6
|-
| export_xml
| Permission to perform the Export XML action (to export the result set as XML).
| 0.8
|-
| translate
| Permission to translate a record into another language.  This permission provides access to the ""translate"" tab.
| 0.8
|-
| history
| Permission to view history information for a record (e.g. the history tab).  This requires that history be enabled.
| 0.8
|-
| edit_history
| Permission to edit history information such as undo/redo support for a record.
| 0.8
|-
| navigate
| Permission to navigate through records of a table.
| 0.6
|-
| reorder_related_records
| Permission to reorder the records of a relationship (this is different than just sorting).  It sets a default order for the records.  Requires the metafields:order directive to be set for the relationship.
| 0.6
|-
| ajax_save
| Permission to save a record through AJAX.
| 0.8
|-
| ajax_load
| Permission to load a record through AJAX.
| 0.8
|-
| ajax_form
| Permission to access the inline editing ajax form for a record.
| 0.8
|-
| find_list
| Permission to search current table.
| 0.6
|-
| find_multi_table
| Permission to perform a site-wide search.
| 0.8
|-
| register
| Permission to register for an account.
| 0.8
|-
| xml_view
| Permission to view a result set as xml.
| 0.8
|-
| view_xml
| View the XML for an individual record.
| 0.8
|-
| manage_output_cache
| Management permission to clear the output cache.
| 0.8
|-
| manage_migrate
| Permission to access the migration tool to migrate between versions.
| 0.8
|-
| manage
| Permission to access the management control panel.
| 0.8
|-
| manage_build_index
| Permission to rebuild the search index.
| 0.8
|-
| expandable
| Whether the record can be expanded in the left nav menu
| N/A
|}

Some core roles include:

{| class=""listing listing2""
|-
! Name
! Permissions Included
! Version
|-
| READ ONLY
| view, list, calendar, view xml, show all, find, navigate, ajax_load, find_list, find_multi_table, rss, export_csv, export_xml, and export_json
| 0.6
|-
| EDIT
| All permissions in READ ONLY, and edit, add new related record, add existing related record, add new record, remove related record, reorder_related_records, import, translate, new, ajax_save, ajax_form, history, edit_history, copy, update_set, and select_rows
| 0.6
|-
| DELETE
| All permissions in EDIT, and delete and delete found.
| 0.6
|-
| OWNER
| All permissions in DELETE except navigate, new, and delete found.
| 0.6
|-
| REVIEWER
| All permissions in READ ONLY, and edit and translate.
| 0.6
|-
| USER
| All permissions in READ ONLY, and add new related record.
| 0.6
|-
| ADMIN
| All permissions in DELETE and xml_view
| 0.6
|-
| MANAGER
| All permissions in ADMIN and manage, manage_output_cache, manage_migrate, manage_build_index, and install.
| 0.6
|}

===Extending and Overriding Roles===

The cleanest and easiest way to define a new role is to extend an existing role.  Xataface allows you to extend roles via the '''extends''' keyword.  For example, if you wanted to create a role '''TEST ROLE''' that contained all of the same permissions as the READ ONLY role, you could define it as follows in your application's permissions.ini file:

<code>
[TEST ROLE extends READ ONLY]
</code>

If we wanted it to contain the same permissions as READ ONLY but to also allow the edit permission we would define it as:
<code>
[TEST ROLE extends READ ONLY]
    edit=1
</code>

If we wanted to disallow the list permission, we would do something like:

<code>
[TEST ROLE extends READ ONLY]
    edit=1
    list=0
</code>

===Overriding Existing Roles===

You can also redefine existing roles:

<code>
[READ ONLY extends READ ONLY]
    my_permission=1
</code>

This is handy if you have added your own custom permissions that you feel should be included in a core role.

Note that there are some caveats regarding the order of how these roles are defined. Please refer to this forum post for more details: 
[http://www.xataface.com/forum/viewtopic.php?t=6187 Overriding Roles / Permissions]

==See Also==

* [[Relationship Permissions]]
* [[getPermissions]] - The getPermissionsMethod
* [[Delegate class methods]] - Delegate class methods.
* [http://xataface.com/documentation/tutorial/getting_started/permissions Getting started with Xataface permissions]","permissions.ini, getPermissions, permissions",en,0
templates:tags:use_macro,24,templates:tags:use_macro,"==use_macro Template Tag==

===Synopsis===

The use_macro tag includes another template into the current template with the option to override certain sections.

===Parameters===

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| file
| The path the template to include (within the templates directory).
| 0.6
|}

===Example===

In this example we will create a template for a user profile, but this template will include a slot that can be overridden by other templates to customize the user bio.

====user-profile.html====

<code>
<html>
<head>
    <title>User profile</title>
</head>
<body>
   <h1>User bio</h1>
   <div id=""bio"">
   {define_slot name=""bio""}
        This text will be overridden by other templates to place the correct
        bio information.
   {/define_slot}
</body>
</html>
</code>

====steve-profile.html====

<code>
{use_macro file=""user-profile.html""}
    {fill_slot name=""bio""}
        This is Steve's bio.  It will override the text in the bio slot.
    {/fill_slot}
{/use_macro}
</code>

===See also:===

* [[xataface templates|Xataface templates]]
* [[templates:tags:define_slot|The define_slot tag]]
* [[templates:tags:fill_slot|The fill_slot tag]]
* [http://www.xataface.com/documentation/tutorial/getting_started/changing-look-and-feel Changing the Look & Feel of Xataface] (From the Getting Started Tutorial)
* [http://www.xataface.com/documentation/tutorial/customizing-the-dataface-look-and-feel Cusomizing the Xataface Look & Feel] Tutorial
",,en,0
fieldgroup_template,51,fieldgroup_template,"==Using a custom template for a field group on the edit form==

[[toc]]

Xataface allows you to partition your fields into ''groups'' so that similar fields are grouped together on the edit form.  The default layout of the fields remains simply vertical, but you can customize this layout (on a per-group basis) by creating a custom template and then assigning this template to the field group with the ''template'' directive.


===Example===

For example, in your [[fields.ini file]] if you wanted to group your address fields together you might have:
<code>
[fieldgroup:address]
    label=""Address Information""
    template=""AddressInformationGroup.html""

[address_1]
    group=address

[city]
    group=address

[state]
    group=address
</code>

Then you would add the a template named ''AddressInformationGroup.html'' to your application's ''templates'' directory to display how the fields are laid out:
<code>
<table width=""100%"">
    <tr><th>Address 1:</th>
    <td>{$elements.address_1.html}</td>

    <th>City:</th>
    <td>{$elements.city.html}</td>

    <th>State:</th>
    <td>{$elements.state.html}</td>
    </tr>
</table>
</code>
This would display all of the fields in this group in a single row (horizontally) instead of vertically.

Note that this is an over-simplified example that doesn't take account for display error messages, required notices, grouped fields, and other information that you can obtain from the {$elements} array.",,en,0
validateRegistrationForm,15,validateRegistrationForm,"==validateRegistrationForm() hook==

A hook that validates the input into the user registration form to make sure that the input is valid.

===Signature===

function validateRegistrationForm( array $values ) : mixed

====Parameters====

{| class=""listing listing2""
! Name
! Description
|-
| $values
| An associative array of the input values of the registration form.
|-
| returns
| Mixed. If this method returns a PEAR_Error object then the validation will fail - and the user will be asked to correct his input.
|}

===Example===

<code>
<?php
class conf_ApplicationDelegate {
    function validateRegistrationForm($values){
        if ( $values['age'] < 18 ){
            return PEAR::raiseError(""Sorry you must be at least 18 years old to join this site."");
        }
        return true;
    }
}
</code>

===Validation via the Users table Delegate class===

Note that since the registration form is just a ""new record form"" for the users table, it is also possible (and preferred) to do validation through the users [[table delegate class]].

===See Also===

* [[afterRegister]]
* [[beforeRegister]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]",,en,0
valuelists.ini_file,5,valuelists.ini_file,"==valuelists.ini file Reference==

[[toc]]

The valuelists.ini file stores value lists that can be used as [[vocabulary|vocabularies]] for select lists, checkbox groups, and other widgets the provide the user with options to choose from.

Each table can have an associated valuelists.ini file located in its [[table configuration directory]]. E.g. for a table named ""people"" its valuelists.ini file will be stored in ""tables/people/valuelists.ini"".

In addition you can define an application-wide valuelists.ini file in the root of your application's directory, whose valuelists can be used by any table.

===Syntax===

The valuelists.ini file uses [[INI file syntax]], where a valuelist is defined by a single section of the INI file.  E.g.

<code>
[colors]
    r=Red
    b=Blue
    g=Green
</code>

This example would define a single valuelist named ""colors"" with 3 values: r,g, and b (with corresponding labels ""Red"", ""Green"", and ""Blue).  The values (the left of the equals sign) are stored in the database, while the labels are rendered on screen for the user's convenience.

===Dynamic Valuelists===

It is often advantageous to load valuelists from the database rather than store them directly in the valuelists.ini file.  The __sql__ directive allows you to specify an SQL query which selects up to 2 columns (the first is the id and the second, the label).

E.g.

<code>
[colors]
    __sql__ = ""select colorCode, colorName from colors""
</code>


===Defining Valuelists in a Delegate Class===

If you require more flexibility with the definition of your valuelists than can be gained from the valuelists.ini file, you can define your valuelist using PHP inside a delegate class.  Essentially you just create a method that returns an associative array, where the keys are the IDs that are stored in the database, and the values are the values that are visible in the select list.

e.g.  In either the application delegate class or a table delegate class:

<code>
function valuelist__colors(){
    return array(
        'r'=>'Red',
        'g'=>'Green',
        'b'=>'Blue'
    );
}
</code>

This method is called each time the valuelist is about to be used, so if your method performs any sort of intensive processing, it is a good idea to use a caching scheme so that it only runs the critical code once per request.  For example, you could use a static variable as follows:

<code>
function valuelist__colors(){
    static $colors = -1;
    if ( !is_array($colors) ){
        $colors = array();
        $res = mysql_query(""select colorCode, colorName from colors"", df_db());
        if ( !$res ) throw new Exception(mysql_error(df_db()));
        while ($row = mysql_fetch_row($res) ) $colors[$row[0]] = $row[1];
    }
    return $colors;
}
</code>

In this example the database query is only executed once per request to load the $colors variable.  The rest of the time it simply loads the cached value from $colors.","valuelists, dynamic valuelists, programmatically defined valuelists",en,0
widget:atts,46,widget:atts,"==widget:atts Directive Reference==

The widget:atts directive in the fields.ini file allows any arbitrary HTML attributes to be added to any of the fields.  It may also be used to specify javascript event handler functions that the widget should call upon the specified event.  In particular, here are some examples of possible widget:atts directives:

===Available Widget Event Handlers===

{| class=""listing listing2""
|-
! name
! description
! version
|-
| [[field_size|widget:atts:size]]
| This directive sets the length of the input area a text box field, but it does not limit the number of characters that can be entered.  For example: <nowiki><br/>widget:atts:size = 50</nowiki>
| ?
|-
| [[field_maxlength|widget:atts:maxlength]]
| This directive limits the maximum number of characters that can be entered into a text box field.  For example: <nowiki><br/>widget:atts:maxlength = 25</nowiki>
| ?
|-
| [[field_style|widget:atts:style]]
| This directive specifies the style (font-size, font-family, etc.) for the field.  For example: <nowiki><br/>widget:atts:style = ""font-size: 24pt; font-family: Apple Chancery""</nowiki>
| ?
|-
| [[field_rows|widget:atts:rows]]
| This directive specifies the number of rows for a text area field to display.  For example: <nowiki><br/>widget:atts:rows = 10</nowiki>
| ?
|-
| [[field_cols|widget:atts:cols]]
| This directive specifies the number of columns for a text area input field (1 character = 1 column).  For example: <nowiki><br/>widget:atts:cols = 10</nowiki>
| ?
|-
| [[field_javascript_onchange|widget:atts:onchange]]
| This directive will cause the specified javascript function to be called with the value of the field whenever its value is changed (i.e. when you change the field and tab out of it).  For example: <nowiki><br/>widget:atts:onchange = ""doJsFunction();""</nowiki>
| ?
|-
| [[field_javascript_onclick|widget:atts:onclick]]
| This directive will cause the specified javascript function to be called with the value of the field whenever it is clicked.  For example: <nowiki><br/>widget:atts:onclick = ""doJsFunction();""</nowiki>
| ?
|}

===Helpful tutorials===

See the bottom of this page in the Getting Started tutorial for more details on the basic directives above:

[http://xataface.com/documentation/tutorial/getting_started/customizing Customizing Field labels, descriptions, and widgets]

This tutorial talks about how to use the javascript directives:

[http://xataface.com/documentation/how-to/custom_javascripts]",,en,0
widget:editor,35,widget:editor,"==widget:editor fields.ini directive==

Return to [[fields.ini file]]

[[toc]]

The widget:editor directive is applicable in the [[fields.ini file]].  It specifies the type of HTML editor that should be used.  This directive is only used when [[widget:type]] is set to [[widget:type htmlarea|htmlarea]].  Xataface currently supports FCKEditor, TinyMCE, and NicEdit.

===Allowed Values===

{| class=""listing listing2""
|-
! Value
! Description
! Version
|-
| fckeditor
| Use [http://www.fckeditor.net/ FCKEditor].  This is the default value.
| all
|-
| tinymce 
| Use [http://tinymce.moxiecode.com/ TinyMCE editor].
| 0.6
|-
| nicedit
| Use [http://www.nicedit.com/ NicEdit].
| 1.0.5
|}

===Examples===

====Example 1: Using FCKEditor====

Given a field 'content' that you wish to be able to edit with FCKEditor, you would have the following section in your [[fields.ini file]]:

<code>
[content]
    widget:type=htmlarea
    widget:editor=fckeditor
</code>

Note that since FCKEditor is the default editor, the above would give the same result as:

<code>
[content]
    widget:type=htmlarea
</code>

====Example 2: Using TinyMCE====

Further from example 1, if we wanted to use TinyMCE editor, we would change our directive to:

<code>
[content]
    widget:type=htmlarea
    widget:editor=tinymce
</code>

====Example 3: Using NicEdit====

Further from example 1:

<code>
[content]
    widget:type=htmlarea
    widget:editor=nicedit
</code>

==Enabling Image Uploads==

By default image uploads are disabled in these WYSIWYG editors.

===Enabling Image Uploads in FCKEditor===

# Create a directory named ''uploads'' inside your application directory. e.g.<code>
cd /path/to/myapp/uploads
</code>
# Make the ''uploads'' directory writable by the webserver. e.g. <code>
chmod 777 /path/to/myapp/uploads
</code>
# Edit the ''lib/FCKeditor/editor/filemanager/connectors/php/config.php'' file inside your ''xataface'' directory so that:<code>
$Config['Enabled'] = true ;
$Config['UserFilesPath'] = '/url/to/myapp/uploads/' ;
    // The path portion of the URL to your uploads directory.
    // e.g. if your uploads directory is accessible at
    // http://example.com/myapp/uploads, then this value should
    // be /myapp/uploads/
$Config['UserFilesAbsolutePath'] = '/path/to/myapp/uploads/' ;
    // The absolute file system path to your uploads directory.
    // e.g. if your uploads directory is located at
    // /home/myhome/www/myapp/uploads, then this value should be
    // /home/myhome/www/myapp/uploads
</code>
# Now when you click on the ""Add Image"" link in your HTML editor, it will allow you to upload images and browse existing uploaded images.

",,en,0
grid,67,grid,"==widget:type = grid==

Suppose we have two tables, tbl_organisation and tbl_individuals, in the edit view for a record in the organisations table (tbl_organisations) we also want to be able to view and edit the individuals within this organisation we can use widget:type=grid

In the /tables/tbl_organisation/fields.ini we create a transient field by adding:

<code>
[Individuals]
widget:label = ""Individuals""
transient=1
relationship=individuals
widget:type=grid
widget:columns=""ind_firstname,ind_lastname,ind_tel""
</code>

The above assumes we have a relationship entry in our /tables/tbl_organisation/relationships.ini that looks like this:

<code>
[individuals]
__sql__ = ""SELECT * FROM tbl_individual WHERE org_id='$org_id'""
</code>

The fields.ini will show the three columns shown in widget:columns from the table tbl_individual

Correct permissions need to be set to enable editing and deletion etc of these records.",,en,0
widget:type,4,widget:type,"==widget:type Directive Reference==

The widget:type directive in the [[fields.ini file]] specifies the type of widget that should be used to edit a particular field in HTML forms.  Xataface uses [http://pear.php.net/package/HTML_QuickForm/ HTML_QuickForm] for its form generation so theoretically any widget supported by HTML_QuickForm should work with Xataface.

===Available Widget Types===

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[advmultiselect]]
| Two select lists with add/remove buttons.  Selected items appear in the right select list.  Options may be selected from the left select list.
| 1.0
|-
| [[autocomplete]]
| An autocomplete. text field.  This is not to be confused with the [[yui_autocomplete]] widget.  The main difference is that this widget does not provide a drop-down list of possibilities, it just tries to complete what the user is typing inside the text field based on a valuelist.
| all
|-
| [[calendar]]
| A DHTML pop-up calendar to select the date.  [[Image:http://media.weblite.ca/files/photos/calendar_widget.png?max_width=400]]
| 0.5.3
|-
| [[checkbox]]
| A checkbox or checkbox group. 

Example 1: Checkbox as boolean on Tinyint field.

[[Image:http://media.weblite.ca/files/photos/checkbox_widget.png?max_width=400]]

Example 2: Checkbox group to allow multiple selections.

[[Image:http://media.weblite.ca/files/photos/checkbox-group_widget.png?max_width=500]]
| all
|-
| [[date]]
| Select lists for month, year, day, hour, etc...
| all
|-
| [[file]]
| A file widget (default type for [[container]] fields and [[blob]] fields.  [[Image:http://media.weblite.ca/files/photos/file_widget.png?max_width=400]]

| all
|-
| [[grid]]
| A grid widget for editing multiple rows of related records inside the edit form.  Supports adding/removing/reordering. As of version 1.2.5, file uploads are not supported in the grid widget.

[[Image: http://media.weblite.ca/files/photos/grid_widget.png?max_width=500]]
| 1.0
|-
| [[group]]
| A compound widget for editing multiple fields but storing the data in a single XML field.
[[Image:http://media.weblite.ca/files/photos/group_widget.png?max_width=400]]
| all
|-
| [[hidden]]
| A hidden field 
| all
|-
| [[htmlarea]]
| A WYSIWYG (What you see is what you get) HTML editor.  This defaults to [http://www.fckeditor.net/ FCKeditor], but [http://tinymce.moxiecode.com/ TinyMCE] is also supported.  [[Image:http://media.weblite.ca/files/photos/htmlarea_widget.png?max_width=400]]
| all
|-
| [[lookup]]
| A field that allows users to look-up a record from another table.  THis is a good alternative to a select list.  It doesn't use a vocabulary, so this is appropriate when vocabularies would be unpractical (for large vocabularies).  You do, however need to specify the widget:table directive for the field so that the lookup knows from which table to load the records.
[[Image:http://media.weblite.ca/files/photos/Picture%2023.png?max_width=640]]

| 1.2
|-
| [[password]]
| A password field.

[[Image:http://media.weblite.ca/files/photos/password_widget.png?max_width=400]]
| all
|-
| [[select]]
| A select list.

Example 1: A single select.

[[Image:http://media.weblite.ca/files/photos/select_widget.png?max_width=400]]

Example 2: A multi-select.  To use a multi-select, add repeat=1 to your fields.ini.

[[Image:http://media.weblite.ca/files/photos/multi-select_widget.png?max_width=500]]
| all
|-
| [[table]]
| A compound widget for editing tabular data.  This widget dictates the storage format as XML.

[[Image:http://media.weblite.ca/files/photos/table_widget.png?max_width=400]]
| all
|-
| [[text]]
| A text field

[[Image:http://media.weblite.ca/files/photos/text_widget.png?max_width=400]]
| all
|-
| [[textarea]]
| A text area (multi-line text field)

[[Image:http://media.weblite.ca/files/photos/textarea_widget.png?max_width=400]]
| all
|-
| [[time]]
| A select list of times separated by a specified interval (default 30 minutes).
| 0.7
|-
| [[yui_autocomplete]]
| An autocomplete widget ported from the [http://developer.yahoo.com/yui/autocomplete/ Yahoo UI Library].

[[Image:http://media.weblite.ca/files/photos/yui_autocomplete.png?max_width=400]]
| 1.0
|}",,en,0
Writing_Custom_Authentication_Plugins,22,Writing_Custom_Authentication_Plugins,"==Writing a Custom Authentication Plugin for Xataface==

[[toc]]

Xataface has a pluggable [[authentication]] framework that allows you to easily write your own custom [[authentication]] modules to tie in with other systems.  Several plugins have already been created including:

* [[CAS Authentication Module|Yale CAS]]
* [[LDAP Authentication Module|LDAP]]
* [[Facebook Authentication Module|Facebook]]
* [[HTTP Authentication Module|HTTP]]

===Example: Creating a custom authentication plugin===

Before we begin, a couple of conventions:

# '''%XATAFACE_ROOT%''' refers to your Xataface installation directory.  This is where all of the Xataface files are located includeing dataface-public-api.php
# '''%SITE_ROOT%''' refers to your Xataface application's installation directory.  This is where your conf.ini file, index.php, and other application files are stored.

====About our plugin====

Our plugin will be the simplest, most useless authentication plugin you can imagine.  It simply checks an array of usernames and passwords to see if the password that the user supplied is valid.

====Creating our plugin====

# Create the '''%XATAFACE_ROOT%/modules/Auth''' directory if it doesn't exist already.  This directory will store all of our Xataface authentication plugins.
#Create the '''%XATAFACE_ROOT%/modules/Auth/XDB''' directory if it doesn't exist already. This directory will house all of the scripts and files associated with our custom plugin.
#Create a new PHP file named '''XDB.php''' inside our '''XDB''' directory that we just created, with the following contents:<code>
class dataface_modules_XDB {
    var $passwords = array(
        'steve' => 'stevespass',
        'mike' => 'foo'
    );
    function checkCredentials(){
        $auth =& Dataface_AuthenticationTool::getInstance();
        $creds = $auth->getCredentials();
        if ( @$this->passwords[$creds['UserName']] == $creds['Password'] ){
            return true;
        } else {
            return false;
        }
    }
}
</code>
# Now, change the '''[_auth]''' section of the conf.ini file to let Xataface know that we want to use our custom module:<code>
[_auth]
    auth_type=XDB
</code>
# Try to log into your application.  You'll notice that the only username/password combinations that are accepted are the ones that we specified in our '''$passwords''' array in our module.

This is just a simple example, but you can see how this can be expanded to provide more complex modules.

===checkCredentials() not enough?===

Some authentication plugins will need more control than simply checking credentials.  Some plugins may want to make use if their own login forms, or redirect to other sites to handle the authentication.  Xataface's [http://dataface.weblite.ca/Dataface_AuthenticationTool authentication tool] is up to the task, as virtually all parts of the login/logout process can be overridden and customized in your module.  The previous example shows how the getCredentials() method can be overridden, but there are other methods that can be implemented to customize the login process as well.

e.g.

* showLoginPrompt() - This method is called when it is time to display the login prompt for the user.  It could also be made to redirect to another site that has a login prompt.
* logout() - This is called when the user tries to log out.  If there are any special cookies of variables that need to be cleaned up to facilitate a successful logout, you could implement this method.
* [http://dataface.weblite.ca/getLoggedInUser getLoggedInUser()]
* [http://dataface.weblite.ca/getLoggedInUsername getLoggedInUsername()]
* getCredentials() - Handles the obtaining of credentials from the request or from the environment.
* authenticate() - Handles the whole login process

===See Also:===

* [[Application Delegate Class]] for before/after login/logout triggers that may be more appropriate in some circumstances than creating a custom authentication plugin.
* [[authentication|Xataface Authentication]]",,en,0
authentication,21,authentication,"==Xataface Authentication==

[[toc]]

Xataface comes with authentication ready to roll out of the box.  With a couple of [[_auth|configuration options]] in the [[conf.ini file]], you can activate the default authentication scheme which uses a table (of your choice) in the database to authenticate against.  It supports [[password encryption]], and even includes a [[registration form]] if you choose to allow registrations for your application.

In addition Xataface's authentication is pluggable, meaning you can write your own plug-ins to integrate your application with any authentication scheme you choose.  Some authentication modules that already exist include:

* [[CAS Authentication Module|Yale CAS]]
* [[LDAP_or_Active_Directory|LDAP]]
* [[Facebook Authentication Module|Facebook]]
* [[HTTP Authentication Module|HTTP]]

====See Also:====

* [[Writing Custom Authentication Plugins]]
* [[Authenticating Against the PHPBB Users table]]
* [[Authenticating Against the Joomla! Users Table]]

Depending on the complexity of the authentication scheme, these plugins may be easy or complex to create.

===Setting up Basic Authentication===

# Create a table (if you haven't already) to store your application's users.  At the bare minimum, this table should have fields to store the username and password (you may call these fields whatever you like).  An example table might be: <code>
CREATE TABLE `users` (
  `username` VARCHAR(32) NOT NULL,
  `password` VARCHAR(32) NOT NULL,
  PRIMARY KEY (`username`)
)
</code>
# Add the following ([[_auth|_auth section]]) to your [[conf.ini file]]: <code>
[_auth]
     users_table=users
     username_column=username
     password_column=password
</code>  This tell Xataface which table you are storing your user accounts in, and the names of the username and password columns.
# Add a sample user record to the users table if one does not exist yet.<code>
INSERT INTO `users` (`username`,`password`) VALUES ('steve','mypass')
</code>
# Load your application in your web browser and you'll notice a ""login"" link in the upper right that allows you to log in.


===Using MD5 Encryption for the Password===

It is good practice to perform some type of encryption on passwords that you store in a database, so that they will be safe, even if your server's security is compromised.  One common form of encryption it MD5.  You can apply encryption to your passwords by defining the '''encryption''' property to the '''[password]''' field's section of the users table [fields.ini file]. E.g.
<code>
[password]
    encryption=md5
</code>

This tells Xataface to save data to the password field of the users table with MD5 encryption.

In order to switch to MD5 encryption with an existing Xataface installation, all un-encrypted (plain text) passwords must be first converted to MD5. There are several ways to do this. One method is to directly convert the passwords in the database with the MySQL MD5 function. This can be done from the command-line or using a tool such as phpMyAdmin. It can also be done solely within Xataface as follows, assuming a small number of users where you either know all of the passwords or are planning to change them:

# Log in to your Xataface application as an existing user with ADMIN-level access.
# Navigate to the users table. If you do not already have a link to it, modify your URL to include ""-table="" and the name of your users table.
# While logged in, add the encryption=md5 parameter to the fields.ini file as described above.
# Select each user and re-enter or reset their password. It will now be stored with MD5 encryption.
# After completing the above step for all users, you may log out and log back in to verify the change.

===Limiting Access Based on User===

Authentication and permissions are distinct issues, but they are related.  It is quite common to require a user to log in to access a section of an application.  Permissions can be defined in either the Application delegate class or a table's delegate class - or both.

As an example, if we want to require users to log in to access our application we could define the following getPermissions() method to our application delegate class:

<code>
<?php
class conf_ApplicationDelegate {
    function getPermissions(&$record){
        // $record is a Dataface_Record object
        $auth =& Dataface_AuthenticationTool::getInstance();
        $user =& $auth->getLoggedInUser();
        if ( $user ) return Dataface_PermissionsTool::ALL();
        else return Dataface_PermissionsTool::NO_ACCESS();
    }
}
</code>


===Checking Who Is Logged In===

The [http://dataface.weblite.ca/Dataface_AuthenticationTool Dataface_AuthenticationTool] class handles all of the dirty work of Xataface's authentication.  It provides public methods to check who is logged in and perform authentication if necessary.  Anywhere inside your Xataface application you can find out who is logged in using one of the following two methods:

* [http://dataface.weblite.ca/getLoggedInUser getLoggedInUser()] - Returns a [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object representing a record from the users table.
* [http://dataface.weblite.ca/getLoggedInUsername getLoggedInUsername()] - Returns a string.

It is quite useful in the getPermissions() method of your delegate classes to find out who is logged in:

<code>
function getPermissions(&$record){
    $auth =& Dataface_AuthenticationTool::getInstance();
    $user =& $auth->getLoggedInUser();
    if ( $user and $user->val('username') == 'shannah' ){
        // Steve is logged in so we give him special permissions
        return Dataface_PermissionsTool::ALL();
    } else {
        // Steve is not logged in so we give only read only permissions
        return Dataface_PermissionsTool::READ_ONLY();
    }
}
</code>

====Checking Who is Logged In from a Template====

All templates in Xataface have access to the *$ENV* array that contains references to lots of useful information, including the currently logged in user:

* '''$ENV.user''' - The user object of the currently logged in user (or null if nobody is logged in).  This is a [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object.
* '''$ENV.username''' - The name of the currently logged in user.  A string.

For example:

<code>
<!-- 
     Print 'Hello Steve' if Steve is logged in,
     'Hello Helen' if Helen is logged in, or just 
     'Hello' if nobody is logged in. 
-->
Hello {$ENV.username}

<!-- Print some personal user info -->
{if $ENV.user}
    Phone number: {$ENV.user->val('phone')}<br/>
    Email address: {$ENV.user->val('email')}<br/>
{/if}
</code>
This example presumes that the users table has 'phone' and 'email' fields.


====See Also:====

* [http://xataface.com/documentation/tutorial/getting_started/permissions Permissions Section of Getting Started Tutorial]
* [http://xataface.com/documentation/how-to/disallow_tables How to disallow access to tables in conf.ini file]
* [http://xataface.com/documentation/how-to/security_filters How to use security filters to hide records from certain users]
* [[LDAP_or_Active_Directory| Using LDAP or Active Directory for Authentication]]
* [[_auth|_auth section directives in conf.ini file]]","authentication, [_auth], CAS Authentication, Authentication Modules, Basic Authentication, Security",en,0
DataGrid,32,DataGrid,"==Xataface DataGrid Module==

Created by Steve Hannah, [http://weblite.ca Web Lite Solutions Corp.]

===Synopsis===

The Xataface DataGrid module uses the Ext DataGrid component (http://extjs.com) to add an editable grid component to your Xataface application.

[[toc collapse=0]]

===Requirements===

* PHP 4.3+
* MySQL 4.1+
* Xataface 0.8+

===License===

This module is distributed with ExtJS 2.2, which is distributed under the GPL v 3 (http://extjs.com/products/license.php).

In order to be compatible with the ExtJS license, this module is also distributed under the terms of the GPL v3 (http://www.gnu.org/copyleft/gpl.html).

===Demo Video===

<nowiki>
<embed src=""http://media.weblite.ca/lib/flvplayer.swf"" width=""640"" height=""500"" bgcolor=""#FFFFFF"" type=""application/x-shockwave-flash"" pluginspage=""http://www.macromedia.com/go/getflashplayer"" flashvars=""file=http%3A%2F%2Fs3.amazonaws.com%2Fweblite_media%2FDataGrid-640x480.flv&image=http%3A%2F%2Fmedia.weblite.ca%2Ffiles%2Fphotos%2FDataGrid-640x480.flv.jpg&showdigits=true&autostart=false"" />
</nowiki>

===Screenshots===

Click on image to enlarge

<nowiki>
<script language=""javascript"" type=""text/javascript"" src=""http://media.weblite.ca/index.php?-action=gallery&-table=files&categories=8&-cursor=0&-skip=0&-limit=30&-mode=list&-photo_max_width=640&--format=js""></script>

<div style=""clear:both"">&nbsp;</div>
</nowiki>


===Demo===

# LibrarianDB Demo: http://demo.weblite.ca/apps/librariandb/index.php?-table=books&-action=DataGrid_view , '''Log in with username ""admin"" and password ""password""'''

===Download===

* [https://sourceforge.net/project/platformdownload.php?group_id=250381 DataGrid-0.2]
* SVN Repository: http://weblite.ca/svn/dataface/modules/DataGrid

===Installation===

# Download and extract the DataGrid directory into your xataface/modules directory.
# Add the following line to the [_modules] section of your application's [[conf.ini file]]:<code>
modules_DataGrid=modules/DataGrid/DataGrid.php
</code>
# Ensure that your [[permissions]] are set up appropriately to allow your users to access the grid action (see next section).

===Setting Up Permissions===

This module defines the following [[permissions]]:

* DataGrid:view_grid  	- Permission to view the data grid for a table.
* DataGrid:create_grid	- Permission to create a new data grid
* DataGrid:edit_grid		- Permission to edit an existing data grid
* DataGrid:update			- Permission to update records via the grid
* DataGrid:manage_grids	- Permission to access the datagrid control panel

In order for a user to access/use the grid he must be granted at least the Datagrid:view_grid and DataGrid:update [[permissions]].  Both of these [[permissions]] are included in the following system roles by default:

* EDIT
* EDIT AND DELETE
* DELETE
* ADMIN
* MANAGER

And of course these [[permissions]] are included with the call to Dataface_PermissionsTool::ALL() .

If you have assigned your own custom roles and want to enable access to the grid, you can simply add the following to your role definition in your [[permissions.ini file]]:
<code>
[MY ROLE]
    DataGrid:view_grid=1
    DataGrid:update=1
</code>

If you want to explicitly disable the grid for a role, you can extend the role and deny those same [[permissions]]:
<code>
[MY ROLE extends MY ROLE]
	DataGrid:view_grid=0
	DataGrid:update=0
</code>

	
===Usage===

Once installed, log in as a user that has permission to access the grid. You should notice a new tab along with ""details"", ""list"", and ""find"", called ""grid"". Click on the ""grid"" tab to access the grid.

You can double click on any field to edit it.  Modified fields will be marked in red, and automatically saved every 5 seconds - after the changes are saved the field is no longer marked in red.

===Limitations===

Currently only fields with the following widget types are available to be edited in the grid:

# text
# textarea
# select
# date/datetime/time

Other types of fields will simply not be included in the grid.

===Support/Questions===

Visit the Xataface forum at http://xataface.com/forum
	

",,en,0
Email,54,Email,"==Xataface Email Module==

[[toc]]

The Xataface Email module allows you to convert your database into a mailing list so that you can easily send email to any found set of records, as long as the records contain an email address to send to.

==Features==

* Send email to any found set.
* Mail merge macros
* HTML Email support (uses NicEdit WYSIWYG editor for email editing).
* Opt out support (allows recipients to opt out of your mailing list).

==Requirements==

* Xataface 1.0+
* MySQL 4.1+
* PHP 5+

==Download==

https://sourceforge.net/project/platformdownload.php?group_id=253820

==Installation==

# Download and extract Email directory so that it is located inside the xataface/modules directory (i.e. xataface/modules/Email)
# Add the following to the ''[_modules]'' section of your application's conf.ini file:<code>
modules_Email=""modules/Email/Email.php""
</code>
# Configure the [email] action in your application's actions.ini file.  See the section called 'Configuration' for configuration details.
# Add a line to your crontab file to send out pending email periodically.  The line should look like:<code>
* * * * * /usr/bin/php <cronpath> <indexpath> <indexurl> mail

where <cronpath> is the absolute path to the cron.php script.
      <indexpath> is the absolute path to your application's index.php script.
      <indexurl> is the absolute url to your application's index.php script.
		
For example:

* * * * * /usr/bin/php /var/www/xataface/modules/Email/cron.php \
		/var/www/myapp/index.php \
		http://example.com/myapp/index.php \
		mail
</code> If you want to see what this line should be like for your server, you can simply point your browser to the email_install action of your application (i.e. http://example.com/yourapp/index.php?-action=email_install) and it will generate this line to copy and paste into your crontab.  Note that the /usr/bin/php portion of this line may vary according to your environment.  It represents the path to your PHP binary.
# That's it!  You're ready to send email.  See the ''Usage'' section to see how to send email from your application.

==Configuration==

Though the email action may work out of the box, you will likely have to configure it to work the way you want.  Some examples of things you will want to configure include:

# Limit the email action to only be available for certain tables.
# Apply permissions to the action so that only administrators can send email.
# Set the name of the column that contains email address (default is 'email').
# Change the name of the table that is used to store sent email messages.

===Overriding the ''[email]'' action===

The first thing you need to do to configure the email action is override it in your appliation's actions.ini file.  You can do this by adding the following to your [[actions.ini file]]:
<code>
[email > email]
</code>

Now any directives you add in this section will override the email action.

====Examples:====

=====Limiting email action to certain tables=====

In your appliation's [[actions.ini file]]:
<code>		
[email > email]
    condition=""$query['-table'] == 'Pledge' or $query['-table'] == 'User'""
</code>


=====Limiting email action by permission=====

By default your users require the ''email'' permission in order to have access to the email form.  This permission is not included with any roles by default so you'll need to extend any roles that you want to have access to the email access and explicitly add the ''email'' permission.  The exception to this rule is if you have assigned your users the ''Dataface_PermissionsTool::ALL()'' permissions in your ''getPermissions()'' method.

Suppose you want the ''READ ONLY'' role to have access to the email action, you could add the following to your application's [[permissions.ini file]]:
<code>
[READ ONLY extends READ ONLY]
     email=1
</code>   			

=====Changing the name of the email address column=====

By default, the Email module will try to guess which column contains the email address for a table.  Generally it looks for a column named ''email''.  You can override this setting to explicitly tell the module which column contains the email address by overriding the ''email_column'' directive of the ''email'' action in your application's [[actions.ini file]]:
<code>
[email > email]
    email_column = ""emailAddress""
</code>

=====Changing the name of the table that stores the sent email====

Xataface automatically stores each sent email for your records.  By default it stores these emails in a table named ''newsletters''.  You can override this table name with the ''email_table'' directive in your application's [[actions.ini file]].  This table will be automatically created by Xataface when email is sent out.
<code>
[email > email]
    email_table = ""newsletters""
</code>
	
=====Altogether=====

<code>
[email > email]
    condition=""$query['-table'] == 'Pledge' or $query['-table'] == 'User'""
    permission=email
    email_column = ""emailAddress""
    email_table = ""newsletters""
</code>


==Usage:==

===Sending Email to All Records of a Table===

# Navigate to a table for which your email module is enabled, and click on the ''list'' tab.
# Click on the ""Email"" icon in the upper right corner.  This should display an email form.<nowiki>
<img src=""http://media.weblite.ca/files/photos/email_icons.png""/>
</nowiki>
# Fill in the email form and press Save.<nowiki>
<div><img src=""http://media.weblite.ca/files/photos/email_form.png?max_width=500""/></div>
</nowiki>
# You should receive a message saying that the email has been queued for delivery.  Your cron script will automatically begin sending emails the next time around.  So make sure that you have yoru cron script set up properly.

===Opting Out of the Email List===

If you have received an email that was sent via the email module you can easily opt out of the mailing list by clicking on the link at the end of the email.  This link will bring you to a webpage that asks you to confirm that you no longer wish to receive email from this list.



==Using a View to add Email Action to Related Record List==

You can simulate a many-to-many [[relationships.ini file|relationship]] in a mysql view by creating a view with all possible combinations. 

e.g. If you have a Many to Many [[relationships.ini file|relationship]] between books and authors your [[relationships.ini file|relationship]] from the books table might be something like: 

<code>

[authors] 
__sql__ = ""select * from authors a inner join book_authors ab on a.author_id=ab.author_id where ab.book_id='$book_id'"" 

</code>

And your relationship from the authors table would be something like: 
<code>
[books] 
__sql__ = ""select * from books b inner join book_authors ab on b.book_id=ab.book_id where ab.author_id='$author_id'"" 
</code>

Now if our goal was to be able to send email to all authors of a particular book (i.e. send to the authors relationship), we could create a view: 
<code>
create view book_authors_maillist as 
select * from authors a inner join book_authors ab on a.author_id=ab.author_id 
</code>

This view can now be used in xataface like a regular table (if you add a [[fields.ini file]] for it and [[Key|mark the primary key columns]]). If you wanted to find all authors for a certain book you would just do: 

index.php?-action=list&-table=book_authors_maillist&book_id=10 

So you could easily create an action in the [[actions.ini file]] that would like to the mail action on the book_authors_maillist table with the parameters you wanted. 

e.g. 

<code>
[related_authors_mail] 
    category=related_list_actions 
    url=""{$site_href}?-action=email&-table=book_authors_maillist&book_id={$record->val('book_id')}"" 
    icon=""{$dataface_url}/images/mail_icon.gif"" 
    url_condition=""$record"" 
    condition=""$query['-table']=='books' and $query['-relationship'] == 'authors'"" 
    permission=""email"" 
</code>


This action would send mail to only the authors related to the current books. It would be made available in the icons in the upper right on the related list view of only the authors of a book.

===Mail Merge===

The 'Embed Macro' shown above the email form lists the fields which may be included in the email.

Say you have a field called 'email_firstname'. You would type this into the message area like this: %email_firstname%

When the email is sent, this is substituted for the record of that recipient.

Eg. Dear %email_firstname% would be received by email as Dear Tom

If the particular record of the field you are merging is blank, then (in this case) the first name will not be shown.","Email,Email module,Sending Email,Maillist",en,0
examples,34,examples,"==Xataface Examples==

[[toc]]

This section includes concrete examples of how Xataface has been used in the past.

===Demo Applications===

{| class=""listing listing2""
|-
! Screenshot
! Title/Description
! Developed by
|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://demo.weblite.ca/apps/librariandb/]]
| '''Librarian DB'''

A searchable database of library books.  Useful for small libraries (e.g. Church Libraries).

Log in with:
username: admin
password: password

[http://demo.weblite.ca/apps/librariandb/ Try the app]
| [http://solutions.weblite.ca Web Lite Solutions Corp.]

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://demo.weblite.ca/apps/webauction/]]
| '''Web Auction'''

A simple web-based auction application for organizations to hold auctions.

Login with:
username: admin
password: password

[http://demo.weblite.ca/apps/webauction/ Try the app]
| [http://solutions.weblite.ca Web Lite Solutions Corp.]


|}

===Websites Powered by Xataface===

{| class=""listing listing2""
|-
! Screenshot
! Title/Description
! Developed by
|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://fueleconomydb.com]]
| '''Fuel Economy Database''' - A searchable database of gas mileage and fuel economy statistics for automobiles from 1986 to present.

[http://fueleconomydb.com Visit the site]
| [http://solutions.weblite.ca Web Lite Solutions Corp.]
|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://physics.sfu.ca]]
| '''Department of Physics, Simon Fraser University'''
This website is completely powered by Xataface.  It is backed by a MySQL database that stores faculty members, research groups, news, events, and more.  Faculty members are able to update their personal profiles and research profiles through a Xataface administration console.

[http://physics.sfu.ca Visit the site]
| [http://fas.sfu.ca/ SFU Faculty of Applied Sciences]

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://science.ca]]
| '''Science.ca'''

The source for science in Canada.  Includes profiles for prominent scientists as well as other useful science-related information.  Xataface is used to power the bilingual (English/French) capabilities of this site.  It includes web-based administrative console for the administrator to manage all content, and for translators to translate the content.

[http://science.ca Visit the site]
| Science.ca web team

|-

| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://translation.weblite.ca]]
| '''Simple Website Translation Engine'''

A service that allows website owners to easily convert their website into multiple languages.  Support human and machine translation.  This service is powered by Xataface, and provides an administrative console for users to manage their website translations.

[http://translation.weblite.ca Visit the Site]

[http://swete.weblite.ca More about this service]

| [http://translation.weblite.ca Web Lite Translation Corp.]

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://www.credituniondb.com]]
| '''Credit Union Database'''

A database of credit unions in the United States.  This site is powered by Xataface.

[http://www.credituniondb.com Visit the site]

| Vlad

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://ierg.net/lessonplans/unit_plans.php]]
| '''IERG Lesson Plans Database'''

A searchable database of lesson plans created by the Imaginative Education Research Group.  This database is managed by Xataface.  It provides researchers with a web-based control panel to manage their lesson plans.

[http://ierg.net/lessonplans/unit_plans.php Visit the site]

| [http://solutions.weblite.ca Web Lite Solutions Corp.]

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://ierg.net/people/]]
| '''IERG People Database'''

A simple database to manage the contributors and associates of the Imaginative Education Research Group.  Administrators have a web-based control panel to manage the people profiles in this database.

[http://ierg.net/people/ Visit the site]

| [http://solutions.weblite.ca Web Lite Solutions Corp.]

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://sustain-gradnetwork.envr.sfu.ca/]]
| '''Sustainability Research Database'''

A database at Simon Fraser University for grad students to post and share research profiles.

[http://sustain-gradnetwork.envr.sfu.ca/ Visit the site]

| [http://fas.sfu.ca Faculty of Applied Sciences Web Team]

|-
| [[Image:http://images.websnapr.com/?size=150&key=40f0knTakb1b&url=http://apps.weblite.ca/]]
| '''Web Lite Applications Catalog'''

A catalog of applications available through Web Lite Solutions.  Allows users to set up their own online applications on Web Lite's servers.  This site is completely powered by Xataface.

[http://apps.weblite.ca/ Visit the site]

| [http://solutions.weblite.ca Web Lite Solutions Corp.]
|}


","examples, samples",en,0
preferences,10,preferences,"==Xataface Preferences==

[[toc]]

Xataface preferences can be defined in 3 ways:

# In the ''[_prefs]'' section of rhe [[conf.ini file]] for global static preferences.
# Implementing the [[getPreferences]] method in the [[Application Delegate Class]]
# In the [[__prefs__]] section of the fields.ini file for a table for static preferences on that table.  (Limited to only certain preferences).

===Example [_prefs] section===
In the conf.ini
<code>
[_prefs]
    hide_updated=1
    hide_posted_by=1
</code>

===Example [[getPreferences]] method===
In the [[Application Delegate Class]]:
<code>
function getPreferences(){
    return array('hide_update'=>1, 'hide_posted_by'=>1);

}
</code>

===Available Preferences===

{| class=""listing listing2""
! Name
! Description
! Default
! Version
|-
| show_result_stats
| Show the result statistics (e.g. found x of y records in table z)
| 1
| 0.6
|-
| show_jump_menu
| Show he drop-down menu that allows you to ""jump"" to any record in the found set.
| 1
| 0.6
|-
| show_result_controller
| Show Next, previous, page number .. links...
| 1
| 0.6
|-
| show_table_tabs
| Show  Details, List, Find, etc... tabs.
| 1
| 0.6
|-
| show_actions_menu
| Show New record, Show all, delete, etc..
| 1
| 0.6
|-
| show_logo
| Show logo at top of app
| 1
| 0.6
|-
| show_tables_menu
| Show the tabs to select a table.
| 1
| 0.6
|-
| show_search
| Show search field in upper right.
| 1
| 0.6
|-
| show_record_actions
| Show actions related to particular record
| 1
| 0.6
|-
| show_bread_crumbs
| Show bread crumbs at top of page to show where you are.
| 1
| 0.6
|-
| show_record_tabs
| View, Edit, Translate, History, etc...
| 1
| 0.6
|-
| show_record_tree
| Show tree to navigate the relationships of this record.
| 1
| 0.6
|-
| list_view_scroll_horizontal
| Whether to scroll list horizontal if it exceeds page width
| 1
| 0.6
|-
| list_view_scroll_vertical
| Whether to scroll list vertical if it exceeds page height.
| 1
| 0.6
|-
| hide_posted_by
| Whether to hide the ''posted by'' text in glance lists (e.g. in the view tab, the related records are shown in the left column.  This hides the ''posted by'' text next to each related record.
| 0
| 1.0b4
|-
| hide_updated
| Whether to hide the ''updated'' text in the glance lists (e.g. in the view tab, the related records are shown in the left column.  This hides the ''updated'' text next to each related record.
| 0
| 1.0b4
|-
| SummaryList_logo_width
| The width of the logo to be used as the preview image in summary lists.
| null
| 0.7
|-
| SummaryList_hideSort
| Hides the sort control for a summary list (the box that allows users to sort by column).
| 0
| 0.7
|-
| hide_user_status
| Hides the user's status (e.g. ""You are logged in as ...""
| 0
| 0.7
|-
| hide_personal_tools
| Hides the personal tool links in upper right.  This includes likes such as ""Control Panel"" and ""My Profile""
| 0
| 0.7
|-
| hide_resultlist_controller
| Hides the controller for a result list (E.g. next/back/results per page etc...).
| 0
| 0.7
|-
| hide_related_sections
| Hides the sections of the view tab that show the related records.  These are the sortable section boxes.  Not the related tabs.
| 0
| 1.3
|-
| hide_record_search
| Hides the record search form that appears in the view tab.  Not to be confused with the find tab.
| 0
| 1.3
|-
| show_resultlist_controller_only_when_needed
| Sets the resultlist controller (e.g. back/next/results per page/etc...) to only show up if paging is required (i.e. if there are more records than can be shown on one page (according to the '-limit' parameter).
| 0
| 1.0
|-
| hide_record_view_logo
| Hides the logo for a record that appears in the upper left of the view tab for each record.
| 0
| 0.7
|-
| horizontal_tables_menu
| Whether to force the tables menu to appear as tabs along the top of the page (alternative is as a menu on the left). If there are 10 or fewer allowed tables, then the default is 1, otherwise the default is set to 0.
| 1
| 0.6
|-
| hide_result_filters
| In list view, setting this value to 1 will cause the column filters to be hidden (the select lists to filter the results).
| 0
| 0.7
|-
| disable_select_rows
| A value of 1 causes the checkboxes in each row of the list view to be hidden.
| 0
| 0.7
|-
| result_list_use_geturl
| Use the getURL() method to link to records in the list view rather than the default (which uses the -cursor parameter).
| 0
| 0.7
|-
| disable_ajax_record_details
| Whether to disable the ajax record details (the '+' sign beside each record in list view that expands to show the record details.
| 1
| 0.7
|-
| use_old_resultlist_controller
| As of Xataface 1.1, a new style result list controller is used that resembles facebook.  It is more slimmed down and is easier to manage.  If you prefer the old controller, set this preference to 1.
| 0
| 1.1
|}

===Inverse Preferences===

The following preferences perform the inverse of some of the options above. When these options are set to 1, their respective option is set to 0.

{| class=""listing listing2""
! Name
! Inverse
|-
| hide_nav_menu
| show_tables_menu
|-
| hide_view_tabs
| show_table_tabs
|-
| hide_result_controller
| show_result_controller
|-
| hide_table_result_stats
| show_result_stats
|-
| hide_search
| show_search
|}
","preferences, prefs, getPreferences",en,0
ShoppingCart,31,ShoppingCart,"==Xataface Shopping Cart Module==

[[toc]]

Status: Under development
Current Version: 0.2

===Synopsis===

Add a shopping cart to your xataface application.  You can treat any record as a product that can be sold.  Includes Paypal connectivity, shipping calculation, and more.

===Requirements===

* Xataface 1.0 or higher
* PHP 5 or higher
* MySQL 4.1 or higher

===Installation Instructions===

# Download the ShoppingCart module, extract it, and place the ShoppingCart directory in your Xataface modules directory. (i.e. /path/to/xataface/modules/ShoppingCart).
# Add the following line to the [_modules] section of your [[conf.ini file]]:<code>
modules_ShoppingCart=modules/ShoppingCart/ShoppingCart.php
</code>
# Add the following to the beginning of your [[index.php file]]:<code>
function __autoload($class){
    if ( $class == 'ShoppingCart' ) require_once 'modules/ShoppingCart/lib/ShoppingCart/ShoppingCart.class.php';
}
</code>
# In the [[fields.ini file]] for any table whose records you wish to represent items for sale, add the following:<code>
[__implements__]
    InventoryItem=1
</code>
# Specify which fields should be used for the item description, price, width, height, length, and weight in the [[fields.ini file]] for each table whose records you wish to represent items for sale by adding the following directives to the appropriate fields:<code>
ShoppingCart.description=1
ShoppingCart.unitPrice=1
ShoppingCart.weight=1
ShoppingCart.width=1
ShoppingCart.height=1
ShoppingCart.length=1
</code> E.g. if your table has a field named """"price"""" that you want to represent the unit price, you would have something like:<code>
[price]
    ShoppingCart.unitPrice=1
</code>  The shopping cart module will make its best guess on which fields to use for these values if they are not explicitly specified.
# Specify the paypal account where money should be deposited by adding the following to your application's [[actions.ini file]]:<code>
[view_cart]
    paypal.account=""youremail@example.com""
</code>


===Usage Instructions===

Once the Shopping Cart module is installed you can:

# Add items to your shopping cart
# View your cart contents
# Checkout and pay with paypal

====Adding Items to the Cart====

In the View tab of any salable record, you'll notice a little block on the left side of the page with the heading ""Add Item to Cart"".  This includes a field to specify the quantity and a button to add the item to the shopping cart.

====Viewing Cart Contents====

The Shopping Cart module automatically introduces an action to view the cart contents.  This action is named ""view_cart"".  Hence you can always view the cart contents by entering the URL: index.php?-action=view_cart .

====Checking Out====

# View the cart contents.
# Click ""Check out""
# This will take you to a paypal page to pay for your items.


==Actions==

This module adds the following actions to your application.

{| class=""listing listing2""
|-
! Name
! Content-type
! Description
! Version
|-
| checkout
| text/html
| Sends user to paypal to pay for the contents of their cart.
| 0.1
|-
| calculate_shipping
| text/html
| Calculates the shipping charges for the cart.
| 0.1
|-
| add_to_cart
| text/html
| Adds an item to the cart.
| 0.1
|-
| clear_cart
| text/html
| Empties the shopping cart.
| 0.1
|-
| get_shipping_provinces
| text/json
| Returns JSON array of provinces for a given country.
| 0.1
|-
| invoices
| text/html
| Displays the current user's invoices.
| 0.1
|-
| payment_complete
| text/html
| Page that is displayed after a successful payment on paypal.
| 0.1
|-
| paypal_ipn
| none
| Handles paypal events such as successful payments.
| 0.1
|-
| refresh_shipping_methods
| text/html
| Refreshes the shipping methods available to the system.
| 0.1
|-
| set_shipping_method
| text/html
| Sets the selected shipping method to a particular method.
| 0.1
|- 
| view_cart
| text/html
| View the cart contents.
| 0.1
|}

==Blocks and Slots==

This module adds the following blocks and slots to your applications.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| shipping_method
| A block with a form to select the shipping method.
| 0.1
|-
| add_to_cart
| A block with a form to add a record/item to the shopping cart.
| 0.1 
|}

==Application Delegate Class Hooks==

You can modify the shopping cart behavior by defining the following methods to the application delegate class.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| isShippingMandatory
| Returns a boolean value indicating whether the user must select a shipping method.
| 0.1
|-
| getDefaultShippingMethod
| Returns a string with the name of the default shipping method to be used.
| 0.1
|}


==Table Delegate Class Hooks==

You can modify the behavior of the shopping cart by defining the following methods to the delegate class of any table that implements the InventoryItem ontology (i.e. any table that is to be used to store products that can be added to the cart).

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| field__taxes
| A calculated field that returns an associative array of all applicable taxes for a product.
| 0.1
|}

==Internal Storage==

This module creates the following tables to store its data:

===dataface__invoices===

The dataface__invoices table stores the actual invoices for purchases made.  An invoice is automatically created as soon as the user ""checks out"".

{| class=""listing listing2""
|-
! Column Name
! Data Type
! Description
! Version
|-
| InvoiceID
| int(11)
| Auto incrementing primary key for the invoice.
| 0.1
|-
| dateCreated
| datetime
| The date that the invoice was created.
| 0.1
|-
| dateModified
| datetime
| The date that the invoice was last modified
| 0.1
|-
| status
| enum
| The status of the invoice (either PENDING, PAID, or APPROVED).
| 0.1
|-
| amount
| decimal(10,2)
| The total amount on the invoice.
| 0.1
|-
| paymentMethod
| varchar(32)
| The name of the payment method used.
| 0.1
|-
| referenceID
| varchar(64)
| ??
| 0.1
|-
| username
| varchar(32)
| The username of the user who owns this invoice.
| 0.1
|-
| firstName
| varchar(32)
| The first name of the payer.
| 0.1
|-
| lastName
| varchar(32)
| The last name of the payer.
| 0.1
|-
| address_name
| varchar(100)
| The name on the shipping address.
| 0.1
|-
| address1
| varchar(100)
| The shipping address line 1.
| 0.1
|-
| address2
| varchar(100)
| The shipping address line 2.
| 0.1
|-
| city
| varchar(40)
| The shipping address city.
| 0.1
|-
| province
| varchar(2)
| The shipping province or state.
| 0.1
|-
| country
| varchar(2)
| The shipping country.
| 0.1
|-
| postalCode
| varchar(32)
| The shipping postal code.
| 0.1
|-
| shipping_method
| varchar(50)
| The name of the shipping method to use.
| 0.1
|-
| phone
| varchar(32)
| The phone number of the payer.
| 0.1
|-
| email
| varchar(127)
| The email address of the buyer.
| 0.1
|-
| data
| text
| Serialize shopping cart data.
| 0.1
|}


===dataface__shipping_methods===

Stores the available shipping methods.

{| class=""listing listing2""
|-
! Column Name
! Data Type
! Description
! Version
|-
| shipping_method_id
| int(11)
| Auto increment ID for a shipping method.
| 0.1
|-
| shipping_method_name
| varchar(50)
| The name of the shipping method.
| 0.1
|-
| shipping_method_label
| varchar(100)
| The label for the shipping method (displayed to the user).
| 0.1
|-
| shipping_method_enabled
| tinyint(1)
| Whether or not this shipping method is currently enabled.
| 0.1
|-
| shipping_method_module
| varchar(32)
| The name of the handler that this shipping method belongs to.
| 0.1
|}

==Payment Handlers==

Information about payment handlers to be added here.

==Shipping Handlers==

The Shopping Cart module is itself modular, allowing you to develop custom shipping handlers for different types of shipping.  A shipping handler is responsible for calculating shipping costs to a destination address.  Currently only a UPS shipping handler has been created, but it is not difficult to create other handlers.

===Shipping Handler Public Interface===

{| class=""listing listing2""
|-
! Method
! Description
! Version
|-
| calculateShipping
| Calculates the shipping cost for the current shopping cart, and adds the shipping cost to the cart as a line item.
| 0.1
|-
| getInfo
| Returns an array of shipping methods that can be handled by this handler.
| 0.1
|}






",,en,0
xataface_templates,23,xataface_templates,"==Xataface Templates==

[[toc]]

Xataface uses the [http://smarty.php.net Smarty Template Engine] to power all of its templates.  Templates are stored in the one of the following locations:

* %XATAFACE_ROOT%/Dataface/templates
* %SITE_ROOT%/templates

Where %XATAFACE_ROOT% is the Xataface directory (includes files such as dataface-public-api.php), and %SITE_ROOT% is the path to your application.

You may also have subdirectories within these templates directories.

===Cascading Templates===

Xataface uses a simple cascading technique for deciding which template to use.  If there are templates in the %SITE_ROOT%/templates and %XATAFACE_ROOT%/Dataface/templates directories with the same name, then Xataface will use the one in the %SITE_ROOT%/templates directory.  In this way, you are able to override any of Xataface's core templates by adding one of the same name to your %SITE_ROOT%/templates directory.

The most common template to override is the Dataface_Main_Template.html template which defines the look and feel for the entire application (e.g. header, footer, etc...).  Hence, if you wanted to customize the look & feel of your application, you would likely start by copying %XATAFACE_ROOT%/Dataface/templates/Dataface_Main_Template.html into the %SITE_ROOT%/templates directory and make modifications to it as desired.

===Useful Smarty Tags introduced by Xataface===

In addition to the standard set of Smarty tags, Xataface templates provide some of its own.

==Xataface Templates==

Xataface uses the [http://smarty.php.net Smarty Template Engine] to power all of its templates.  Templates are stored in the one of the following locations:

* %XATAFACE_ROOT%/Dataface/templates
* %SITE_ROOT%/templates

Where %XATAFACE_ROOT% is the Xataface directory (includes files such as dataface-public-api.php), and %SITE_ROOT% is the path to your application.

You may also have subdirectories within these templates directories.

===Cascading Templates===

Xataface uses a simple cascading technique for deciding which template to use.  If there are templates in the %SITE_ROOT%/templates and %XATAFACE_ROOT%/Dataface/templates directories with the same name, then Xataface will use the one in the %SITE_ROOT%/templates directory.  In this way, you are able to override any of Xataface's core templates by adding one of the same name to your %SITE_ROOT%/templates directory.

The most common template to override is the Dataface_Main_Template.html template which defines the look and feel for the entire application (e.g. header, footer, etc...).  Hence, if you wanted to customize the look & feel of your application, you would likely start by copying %XATAFACE_ROOT%/Dataface/templates/Dataface_Main_Template.html into the %SITE_ROOT%/templates directory and make modifications to it as desired.

===Useful Smarty Tags introduced by Xataface===

In addition to the standard set of Smarty tags, Xataface templates provide some of its own.

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| [[templates:tags:use_macro|use_macro]]
| Include another template with the option to override certain sections.
| 0.6
|-
| define_slot
| Marks a section that can be overridden by other templates that include this one via the use_macro tag.
| 0.6
|-
| fill_slot
| Overrides content in a template that has been included via the use_macro tag.
| 0.6
|-
| block
| Marks an insertion point where content can be inserted by delegate classes and modules.
| 0.6
|-
| load_record
| Loads a [http://dataface.weblite.ca Dataface_Record] object from the database to be used in the template.
| 0.6
|-
| group
| Groups an array of records together based on a field value.
| 0.6
|-
| img
| Displays a thumbnail of an image.
| 0.6
|-
| actions
| Loads an associative array of actions defined in the actions.ini file, based on certain criteria.
| 0.6
|-
| actions_menu
| Displays a menu of actions based on certain criteria.
| 0.6
|-
| record_actions
| A specialization of the actions_menu tag.  This displays a menu of actions only in the record_actions category.
| 0.6
|-
| record_tabs
| A specialization of the actions_menu tag.  This displays a menu of actions only in the record_tabs category.
| 0.6
|-
| result_controller
| Displays the paging controls for the current table's records.   Use this for any listing of records.
| 0.6
|-
| result_list
| Displays the result list (from the list tab) for the current request.
| 0.6
|-
| related_list
| Displays the related records list for the current request.
| 0.6
|-
| bread_crumbs
| Displays the bread crumbs for the current request.
| 0.6
|-
| search_form
| Displays the find form for the current table.
| 0.6
|-
| language_selector
| Displays a menu to select the user's preferred language.
| 0.6
|-
| next_link
| Displays a link to the next XXX records.
| 0.6
|-
| prev_link
| Displays a link to the previous XXX records.
| 0.6
|-
| jump_menu
| Displays the select list of the records found in this found-set so that the user can jump directly to any record.
| 0.6
|-
| limit_field
| Displays a text field for the user to select the number of records to display per page.
| 0.6
|-
| result_index
| Displays the index of pages (1 to XXX) for this query.
| 0.6
|-
| summary_list
| Displays a list of records in the current found set using a summary format rather than the regular table format.
| 0.6
|-
| sort_controller
| Displays a control to sort the results on any column.
| 0.6
|-
| glance_list
| Displays a simple, brief list of records matching certain criteria.
| 0.6
|-
| record_view
| Loads structured data for a record as required for the view tab.
| 0.6
|-
| feed
| Generates a link to an RSS feed based on certain criteria.
| 0.6
|-
| translate
| Display a section of text in the user's selected language. (i18n).
| 0.6
|-
| if_allowed
| The contents of this block are shown only if the user has certain permissions.
| 0.6
|-
| editable
| Make a section of the page editable using AJAX.
| 0.6
|-
| abs
| Convert a URL into an absolute URL.
| 0.6
|}


===Useful Template Variables===

Xataface makes certain variables available to every template:

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| $ENV.REQUEST
| Reference to the $_REQUEST array (HTTP Request parameters, both GET and POST)
| 0.6
|-
| $ENV.SESSION
| Reference to the $_SESSION array (the session variables)
| 0.6
|-
| $ENV.DATAFACE_PATH
| The file system path to the Xataface directory (i.e. the directory containing all of the Xataface files such as dataface-public-api.php).
| 0.6
|-
| $ENV.DATAFACE_URL
| The URL to the Xataface directory.
| 0.6
|-
| $ENV.DATAFACE_SITE_PATH
| The file system path to your application directory. (i.e. the directory containing your conf.ini and index.php files).
| 0.6
|-
| $ENV.DATAFACE_SITE_URL
| The URL to your application directory.
| 0.6
|-
| $ENV.DATAFACE_SITE_HREF
| The URL to your application's script.  This differs from the $ENV.DATAFACE_SITE_URL variable in that this also includes the script name.
| 0.6
|-
| $ENV.SCRIPT_NAME
| Same as $ENV.DATAFACE_SITE_HREF
| 0.6
|-
| $ENV.APPLICATION
| A reference to the application's conf array (i.e. the parsed contents of the conf.ini file).
| 0.6
|-
| $ENV.APPLICATION_OBJECT
| A reference to the Dataface_Application object for the application.
| 0.6
|-
| $ENV.SERVER
| A reference to the $_SERVER array.
| 0.6
|-
| $ENV.QUERY
| A reference to the current query (i.e.  Dataface_Application::getInstance()->getQuery())
| 0.6
|-
| $ENV.action
| The name of the current action as specified by the -action REQUEST parameter.
| 0.6
|-
| $ENV.table
| The name of the current table as specified by the -table REQUEST parameter.
| 0.6
|-
| $ENV.table_object
| A reference to the current table.
| 0.6
|-
| $ENV.relationship
| The name of the current relationship as specified by the -relationship REQUEST parameter.
| 0.6
|-
| $ENV.limit
| The value of the -limit REQUEST parameter.  This is the number of records to show per page.
| 0.6
|-
| $ENV.start
| The value of the -start REQUEST parmeter.  This is the starting point in the result set which is currently being displayed.
| 0.6
|-
| $ENV.resultSet
| A reference to the [http://dataface.weblite.ca/Dataface_QueryTool Dataface_QueryTool] object for this result set.
| 0.6
|-
| $ENV.record
| A reference to the [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object that is matched by the current query.
| 0.6
|-
| $ENV.mode
| The name of the current mode.  e.g. find, list, browse
| 0.6
|-
| $ENV.language
| The 2-digit ISO language code that is currently selected as the user's preferred language.
| 0.6
|-
| $ENV.prefs
| A reference to the preferences array ($conf['_prefs'])
| 0.6
|-
| $ENV.search
| The value of the current full-text search (i.e. the search that was entered into the upper right search field.
| 0.6
|}


==Smarty Plugins==

One of the most powerful features of [http://www.smarty.net Smarty] is its pluggable architecture.  You can easily add your own custom plugins to a registered ""plugins"" directory to add functions, modifiers, blocks, and other features to your templates.

Prior to Xataface 2.0, you Smarty plugins could only be placed in the  ''lib/Smarty/plugins'' directory of the Xataface distribution folder.  This is not very conducive to Xataface updates, though.  In general it is best practice to not change anything inside the xataface directory.  Most other configuration and extensions can be handled by making changes to your application's directory which override corresponding functionality in Xataface.

As of Xataface 2.0, you can create a directory named ''plugins'' to your application directory, Smarty knows to look in this directory for plugins.

For versions of Xataface prior to 2.0, you can make a small modification to the SkinTool to also add support as desribed in [http://xataface.com/forum/viewtopic.php?f=4&t=6722 this post].

===Example Plugin===

The following is an example Smarty plugin adapted from [http://www.smarty.net/docs/en/plugins.functions.tpl this page] but modified slightly to work in Xataface.  It is a simple ""eightball"" plugin that adds a tag {eightball} to Xataface that you can use in any of your templates.  Whenever this tag is rendered it outputs one of a set of predefined strings randomly.

# Add a ''plugins'' directory to your application directory.  i.e.  ''path/to/app/plugins''
# Add a file inside this ''plugins'' directory called ''<nowiki>function.eightball.php</nowiki>'' with the following content:<code>
<?php
/*
 * Smarty plugin
 * -------------------------------------------------------------
 * File:     function.eightball.php
 * Type:     function
 * Name:     eightball
 * Purpose:  outputs a random magic answer
 * -------------------------------------------------------------
 */
function smarty_function_eightball($params, Dataface_SkinTool $template)
{
    $answers = array('Yes',
                     'No',
                     'No way',
                     'Outlook not so good',
                     'Ask again soon',
                     'Maybe in your reality');

    $result = array_rand($answers);
    return $answers[$result];
}
</code>
# If you compare this function to the original example in [http://www.smarty.net/docs/en/plugins.functions.tpl the smarty tutorial] you'll notice that the 2nd parameter has been changed to type ''Dataface_SkinTool'' from ''Smarty_Internal_Template''. If you don't make this change, you will get a fatal error when you try to use the tag.  This function defines an ''{eightball}'' tag that can be added to any Smarty template in Xataface.
# Next we'll create a template that uses this tag.  If your application doesn't have a ''templates'' directory, create one now (i.e. path/to/app/templates).
# Add a file inside your templates directory called ''testing.html'' with the following content:<code>
The eight ball says {eightball}
</code>
# Now we need to display this template somewhere in our interface.  In this case, we'll choose the ''before_record_content'' block.  (This will render the template before the main section of the view tab).  Add the following method to your [[Application_Delegate_Class]]:<code>
function block__before_record_content(){
    df_display(array(), 'testing.html');
}
</code>
# Now if you load your application in a web browser and navigate to the details view for a record, you should see something like the following:
<nowiki><img src=""http://media.weblite.ca/files/photos/Screen_Shot_2012-04-16_at_12.33.01_PM.png?max_width=640""/></nowiki>

===See also:===

* [http://www.xataface.com/documentation/tutorial/getting_started/changing-look-and-feel Changing the Look & Feel of Xataface] (From the Getting Started Tutorial)
* [http://www.xataface.com/documentation/tutorial/customizing-the-dataface-look-and-feel Cusomizing the Xataface Look & Feel] Tutorial","templates, plugins, smarty",en,0
Troubleshooting,49,Troubleshooting,"==Xataface Troubleshooting==

This document is intended to help Xataface developers through some of the most common issues.

[[toc]]

==All I get is a blank white screen!==

The most common issue mentioned in the forums is that an application comes up with a blank white screen in the web browser.  This can happen for a number of reasons but the most common reason is because PHP has encountered a fatal error and your PHP installation is not set up to display errors.  

The first step to troubleshooting this problem must be to find out what the error is.  You can do that in one of the following ways:

# Check your Apache error log if you know where it is.  One common location on many linux installations is <code>
/var/log/httpd/error_log
</code> but your system may have it located elsewhere.  If you cannot find your error log, continue to the next option.
# Turn on the ''display_errors'' flag in your ''php.ini'' file.  I.e., in your ''php.ini'' file, find where it says <code>
display_errors Off
</code> and change it to <code>
display_errors On
</code>.  After this is done, restart your apache webserver.  If you don't know where your ''php.ini'' file is located see the section later in this document on locating your ''php.ini'' file.  If you don't have access to your php.ini file, move on to the next option.
# In your application's ''.htaccess'' file, add the following directives to enable displaying errors:<code>
php_flag display_errors on
</code> .  Note that this method will only work if your apache config file allows you to override these values at the directory level.  If you still get a blank white screen after this, continue to the next option.
# At the beginning of your application's index.php file, add the following:<code>
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'on');
</code> .  Note that if the error occurs in the parsing or compiling of your PHP files you will still get a blank screen.  But this will at least display runtime errors on the page.

Once you can see the error messages that caused the blank white screen you are in a much better position to solve the problem.

==Locating your php.ini file==

Locating your ''php.ini'' file is actually quite easy.  The quickest way is to create a php script with the following contents:
<code>
<?php
phpinfo();
</code>
then navigate to this page in your web browser.  This look at the line where it says the ''php.ini file''.  It will list the path there.",,en,0
URL_Conventions,37,URL_Conventions,"==Xataface URL Conventions==

[[toc]]

Xataface adheres to a few simple URL conventions for all of its actions.  When you understand how Xataface URLs work you begin to get far more out of your applications.  By specifying the appropriate query parameters to can jump directly to any point in your application, or produce a specific result set.

For example, the URL ''index.php?-table=people'' will take you to the ''people'' table (and since the default action for a Xataface application is ''list'', it will take you to the ''list'' view.

You could be more explicit by specifying the action in the URL directly: ''index.php?-table=people&-action=list''.  This would take you to the same screen.  From this example, you see that you can specify such things as the table and action via GET parameters.  Xataface accepts many more GET parameters also, as you'll see in the next section.

===Available GET Parameters===


{| class=""listing listing2""
|-
! Name
! Description
! Default
! Version
|-
| -action
| Specifies the action to perform.  E.g. ''browse'', ''list'', ''find'', ''edit'', ''new'', ... etc..
| list
| all
|-
| -table
| The name of the table to use as the context table.
| The first table in the [_tables] section of your [[conf.ini file]]
| all
|-
| -skip
| Skip a certain number of results in the current found set to display.  E.g. If there are 100 records in the table and you want to start browsing from the 30th record, you would set ''-skip=29''.

Not to be confused with the ''-cursor'' parameter which is used to specify which record to view in the ''details'' tab.
| 0
| all
|-
| -limit
| The maximum number of records in the found set to display.
| 30
| all
|-
| -cursor
| The index of the record in the current found set that is treated as the ""current"" record.  This is used in the ''details'' tab to identify which record to act on.  E.g. which record to view or edit.
| 0
| all
|-
| -sort
| A comma-delimited list of columns to sort the result set on.
| null
| all
|-
| -relationship
| If we are browsing related records, this specifies the name of the relationship.
| null
| all
|-
| -related:start
| If we are browsing related records, this is the first record in the relationship to show.
| 0
| all
|-
| -related:limit
| If we are browsing related records, this is the number of records to show per page.
| 30
| all
|-
| -search
| A keyword search term to filter the found set on.  Any row containing any field that matches the query will be returned.
| null
| all
|-
| --no-query=1
| A flag to indicate that xataface should not query the database by default.  This flag is used in the new record form to prevent the form parameters from being interpreted as query parameters to search in the database.  If you set this flag, it likely result in a message saying ""No records found"".  Generally you would only use this in a custom action where you are not relying on Xataface's default found set.
| 0
| 1.3
|}

There are many other GET parameters that are used in various contexts but the above parameters are available throughout the entire application.

===Finding Records using the URL===

Notice that all of the GET parameters mentioned in the previous section begin with a hyphen (i.e. '-').  This is a convention Xataface uses to distinguish directives from search queries.  All parameters that do not begin with '-' are treated as a query to filter the found set.

For example, ''first_name=bob'' used as a GET parameter would cause the found set to be filtered so that only records where the ''first_name'' column contains the phrase ""bob"" are returned.  Putting this all together, suppose we wanted to show the list tab for the ''people'' table, but only wanted to show the people with first names containing ""bob"":

index.php?-action=list&-table=people&first_name=bob

====Exact, Range, and Pattern Matching====

By default, queries on text columns look for partial matches.  I.e. if you search for ""bob"" it will match ""bob"", ""bobby"", ""rubob"", and any other text that contains ""bob"".  If you are only interested in finding records that match ''exactly'' ""bob"", then you can prepend an ""="" to the query.  E.g. ''first_name==bob'', or the full URL:

index.php?-action=list&-table=people&first_name==bob

This should show the ''list'' tab for the ''people'' table with only records with first name exactly ""bob"".

There are a number of modifiers that you can prepend to your query to modify how it is executed.  They are as follows:

=====Search Operators=====

{| class=""listing listing2""
|-
! Prefix
! Usage Example
! Description
|- 
| >
| age=>10
| Match records greater than search parameter.
|-
| <
| age=<10
| Match records less than search parameter.
|-
| >=
| age=>=10
| Match records greater than or equal to the search parameter.
|-
| <=
| age=<=10
| Match records less than or equal to the search parameter.
|-
| ..
| age=10..20
| Match records in a given range.
|-
| =
| first_name==bob
| Match records that exactly match the search parameter (if there is no prefix then it will search for partial matches on text/varchar/char fields.).
|-
| ~
| first_name=~a%
| Exact match, but you can include wildcards such as '%' and '?' in your search.
|}


=====Search Examples=====

Given the following data set:

{| class=""listing listing2""
|-
! first_name
! age
|-
| Bob
| 10
|-
| Cindy
| 12
|-
| Julie
| 6
|-
| Jake
| 8
|-
| Kabob
| 16
|}

Here are some example queries on this data set and their results:

{| class=""listing listing2""
|-
! Query
! Matches
|- 
| age=>10 
| match records where ''age'' is greater than 10.  This includes ''Cindy'' and ''Kabob''.
|-
| age=<10 
| match records where ''age'' is less than 10.  This includes ''Julie'' and ''Jake''
|-
| age=>=10 
| match records where ''age'' is greater or equal to 10.  This includes ''Bob'', ''Cindy'', and ''Kabob''.
|-
| age=<=10
| match records where ''age'' is less than or equal to 10. This includes ''Bob'', ''Julie'', and ''Jake''.
|-
| age=8..10
| match records where ''age'' is between 8 and 10.  This includes ''Bob'' and ''Jake''.
|-
| first_name=bob
| Matches records where ''first_name'' contains ""bob"".  This includes ''Bob'' and ''Kabob''.
|-
| first_name==bob
| Matches records where ''first_name'' is exactly ""bob"".  This includes ''Bob'' only.
|-
| first_name=~J%
| Matches records that begin with ""J"".  This includes ''Jake'' and ''Julie''
|}

====Matching on Related Records====

It is also possible to match records based on their related data (i.e. data that is not physically stored in the record itself, but in related records via a relationship).  For example if we want to find authors who have written about a particular topic, we would normally have to first find all of the articles that contain a topic, and then cross-reference that result against the ''authors'' table.  With Xataface we can perform this query directly from the ''authors'' table using something like the following query:
 index.php?-table=authors&articles/title=sports
This assumes that the ''authors'' table has a relationship named ''articles'' that contains all of the articles that an author has written.  So the above query returns precisely those authors who have written at least one article whose ''title'' field contains the phrase ""sports"".


=====Anatomy of a Related Query=====

 %relationship%/%field%=%query%
This matches all records in the current table such that at least one record in its ''<relationship>'' relationship matches the query: ''%field%=%query%''.


====Using the ''OR'' Operator====

Xataface allows you to search for more than one value at a time using the ''OR'' operator.  E.g.
 first_name=bob+OR+steve
Would match all records with ''first_name'' containing ""bob"" or ""steve"".
 first_name=bob+OR+=steve
Would match all records with ''first_name'' containing ""bob"" or exactly matching ""steve""
 age=<10+OR+>20
Would match all records with age less than 10 or greater than 20.

====Combining Multiple Queries in One Request====

Xataface allows you to filter on more than one field at a time.  If you combine multiple queries in the same request it has the effect of strengthening the filter, matching only those rows that match ''both'' queries.  E.g.
 age=>10&first_name=bob
would match all records where ''age'' is greater than 10 '''AND''' that have ''first_name'' containing ""bob"".

=====Examples of Combined Queries=====

Given the same data set as the previous set of examples:

{| class=""listing listing2""
|-
! first_name
! age
|-
| Bob
| 10
|-
| Cindy
| 12
|-
| Julie
| 6
|-
| Jake
| 8
|-
| Kabob
| 16
|}

 first_name=bob&age=11
would return no matches because there are no records that contain both ''first_name'' ""bob"" and ''age'' 11.  However
 first_name=bob&age=10
would return only ''Bob'' and
 first_name=bob&age=16
would return only ''Kabob''.

====Special Common Queries====

=====Search For Null or Blank Value=====

Searching for a null value or a blank value is an exact match for """".  Therefore you can simply search for ""="".  E.g. To find records with a null or blank first_name you would use the query ''first_name==''.  Or the full query:
 index.php?-table=people&first_name==

=====Search for Non-blank Value=====

Searching for a non-blank value is the same as searching for a value greater than """".  Therefore you can simply search for "">"".  E.g. if you wanted to find records with a first_name, you would use the query ''first_name=>''.  Or the full query:
 index.php?-table=people&first_name=>

==Preserved vs Non-preserved Parameters==

As mentioned above any parameters that are prefixed by a hyphen (i.e. ""="") are treated as directives rather than search filters.  Hence if you want to use your own GET parameters you should always prefix them with a ""-"" to ensure that Xataface does not attempt to apply it as a search filter.  In order to keep a consistent context for users, all browsing within the same table preserves both search queries and directives.  Hence if you go to the URL:
 index.php?-table=people&-action=list&first_name=bob
It will show you the ''list'' tab of the ''people'' table with only those records with ''first_name'' ""bob"".  Now if you click on the ''details'' tab it will preserve your query ''first_name''.  The query will become something like:
 index.php?-table=people&-action=details&first_name=bob&...etc... more parameters
(Although the parameters may appear in a different order).  This allows you to navigate forward and back to previous and next records and stay within the same found set.  It also ensures that if you click on the ''list'' tab to return to the list view, it will retain your place in the list.

Note that navigating within the same table it will also preserve your directives.  E.g. If you specify the ''-limit'' directive to show 100 records per page:
 index.php?-table=people&-action=list&-limit=100
And then you click on the ''details'' tab, it will retain your ''-limit'' parameter.  Of course the ''-limit'' parameter is not actually used by the ''details'' action because it works on only one record at a time (it uses the ''-cursor'' parameter instead), when you click back on the ''list'' tab it will still show you 100 records per page.

Because of this, we call the ''-limit'' parameter a preserved parameter.  It is retained when navigating within the same table.  '''Note:''' parameters are retained in the HTTP Query string, not in sessions or cookies.  This ensures that there are no surprises when you enter a URL to your Xataface application.

===Unpreserved Parameters===

If you ''don't'' want Xataface to preserve one of your parameters, you should prefix two hyphens to the parameter name.  I.e. ""--"".  One example of an unpreserved parameters throughout Xataface applications is the ''--msg'' parameter.  The value of this parameter will be displayed on the page as an info message to the user.  Clearly you don't want this parameter preserved across requests, as you only want the user to see a message once.  E.g.
 index.php?--msg=Record+Successfully+saved.
Would didsplay the mesage ""Record Successfully Saved"" at the top of the page.  If you click on any link in the application, it will not retain the ''--msg'' parameter so you will not see the message on subsequent requests.

This parameter is useful if you want to give feedback to the user about an action that has been carried out.

===Summary===

{| class=""listing listing2""
|-
! Parameter Type
! Prefix
! Examples
! Description
|-
| Preserved
| -
| -limit, -skip, -cursor, -action, -table
| Parameter value is preserved when user navigates away from the page (within the same table).
|-
| Unpreserved Parameters
| --
| --msg
| Parameter is ''NOT'' retrained with the user navigates away from the page.
|}





","URL Conventions, GET Parameters, POST parameters, Request Parameters",en,0
__prefs__,9,__prefs__,"==__prefs__ fields.ini Section==

A global section of the [[fields.ini file]] that sets the preferences for the given table and its records.

E.g.
<code>
[__prefs__]
    hide_posted_by=1 ; Hides the ""Posted by"" text in glance lists (e.g. related records in the view tab).
    hide_updated=1 ; Hides the ""Updated"" text in glance lists (e.g. the related records in the view tab).
</code>


===Available Preferences===

Ultimately, all of the preferences available at a global level should be available here, however currently this is not the case and only selected preferences are available at the table level.

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[hide_posted_by]]
| HIdes the ''posted_by'' text in glance lists.  E.g. In the view tab of a record, the related records are shown in the left column.  This will hide the ''posted_by'' text next to each related record.
| 1.0b4
|-
| [[hide_updated]]
| Hides the ''updated'' text in glance lists.  E.g. In the view tab of a record, the related records are shown in the left column.  This will hide the ''updated'' text next to each related record.
| 1.0b4
|-
|}",,en,0
testpage2,2,testpage2,"Another test page
[[testpage]]",,en,0
timestamp,44,timestamp,"Return to [[fields.ini file]]

A very simple sample of this could be your table contains the table date_created as a type of date.  In your fields.ini, you would include this:

<code>
[date_created]
timestamp=insert
widget:type=hidden
</code>

The widget:type=hidden will make the field not visible during entry and editing.  And the timestamp=insert causes the field to be filled upon insertion of a new record.

===Possible Values===

* '''update''' - Causes timestamp to be updated whenever the record is modified.
* '''insert''' - Causes the timestamp to be updated only when the record is first inserted.","timestamp, date, datetime",en,0
lookup,61,"The Lookup Widget","Return to [[widget:type]] page to see list of all widget types.
Back to [[fields.ini file]] to see other fields.ini directives.

[[toc]]

===Synopsis===

The lookup widget allows users to look a record from another table to insert into the field.  It is like a select widget except that it doesn't use a vocabulary.  Instead you just specify a table on which it should search using the widget:table directive.  In order to use the lookup widget to edit a field, you should set the [[widget:type]] directive of the [[fields.ini file]] for the field to '''lookup''.  I.e.
<code>
[fieldname]
    widget:type=lookup
    widget:table=mytable
</code>

'''Note that the lookup widget requires the [[widget:table]] directive to be set to the target table of the lookup or it will not work properly.'''

===Required Directives===

The following [[fields.ini file]] directives are required to accompany the field definition if a lookup widget is used:

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| widget:table
| The name of the table in which the lookup widget should look up related records.
| 1.0
|}


===Optional Directives===

The following additional optional directives may be used to customize the behaviour of the lookup widget:

{| class=""listing listing2""
|-
! Name
! Description
! Version
|-
| widget:filters:-limit
| Sets the number of records that are shown by default in the lookup widget.  Default is 30 if this is omitted. E.g.<code>widget:filters:-limit=100</code> to show 100 records at a time.
| 1.0
|-
| widget:filters:-sort
| Specifies the columns to sort the results on. E.g. <code>widget:filters:-sort=category_name asc, year desc</code>
| 1.0
|-
| widget:filters:*
| Any valid Xataface directive can be used to filter the results by specifying widget:filters:param  (where ""param"" is a valid Xataface GET parameter, which could include a column name to filter results on, or other filter directives). <code>widget:filters:country=Canada</code> To only show results with Country=Canada.
| 1.0
|-
| widget:filters:*=$*
| Dynamic filters.  Causes the options in the record browser to be filtered on the value of another field in the form.  e.g. <code>widget:filters:country_id=""$country_id""</code> would show only results with records having country_id matching the value of the 'country_id' field in the current form.
| 1.3.1
|}

See [[URL Conventions]] for an overview of the types of GET parameters Xataface can take.  Any GET parameters that manipulate a query can be used with the widget:filters:* directive to modify the query results that are shown in the lookup widget.


===Example===

In this example we have a field named appointee that is supposed to reference the contacts table.  So in the [[fields.ini file]] we would have:

<pre>
[appointee]
    widget:type=lookup
    widget:table=contacts
</pre>

Initially we just have a little find icon next to the field. If the user clicks it, a dialog pops up enabling them to search for the contact that they want:

[[Image:http://media.weblite.ca/files/photos/Picture%2023.png?max_width=640]]


===Additional Tips===

Although the lookup widget does not use a vocabulary as indicated in the Synopsis above, it is still useful to define a vocabulary in the fields.ini file for this field. The reason is because the lookup widget is only used with the edit action, where you are inserting or editing data into the field. However, it is not used to the display the data in the view or list actions. Therefore, you must still have a vocabulary defined to properly display these values.

In order to customize the display of the lookup widget's select list, you must edit the delegate class for the table which is referenced by the widget:table directive. There are two important points to note:

# The items in the selection list are formatted based on the getTitle(&$record) delegate class function if it is defined. However, ...
# The Search box will search on text in VARCHAR and TEXT fields. If you need to search for data in numeric fields, you can create a grafted field using a function such as CONCAT() to display numbers as text.

Links:
* [http://xataface.com/forum/viewtopic.php?f=4&t=6723 Lookup widget on view with compound primary key]","lookup widget, widget:filters, widget:-filters:limit, widget:table",en,0
__field__permissions,50,__field__permissions,"This method can be used to set the default permissions for all fields in a designated table, when specified in that table's delegate class. It comes in handy in situations when you want to deny access to all fields except for those designated, rather then specifying each field to deny individually. For example, to revoke edit permissions from all fields but one, the user must first have edit permissions to the table overall, otherwise the Edit tab/action will not appear. Then, use this __field_permissions method to revoke edit permissions from all fields. Finally, use the fieldname__permissions method (see below) to allow access to only those fields needed.

=== Also See: ===

* [[How_to_granulate_permissions_on_each_field]]
* [[fieldname__permissions]]",,en,0
table,66,table,"When using widget:type table, it will store the data as XML.

So the field type must be TEXT (or varchar... but text is better). You can decide which columns you want in the table by creating sub-fields in your fields.ini file as follows:

Suppose you want a column called 'name' and a column called 'url'

<code>
[myfield]
widget:type=table
[myfield:name]
[myfield:url]
</code>

Now when you access the stored value using the Dataface API, the value of myfield will be stored as an array of associative arrays. e.g. 

<code>
foreach ( $record->val('myfield') as $vals){ echo $vals['name'].' -- '.$vals['url']; }
</code>",,en,0
no_access_text,59,no_access_text,"Whenever the NO_ACCESS permission is given for a field, normally the text NO ACCESS appears.  But we might want to display another text.  Here is an example of the text subscribe is used instead of NO ACCESS whenever the NO_ACCESS permissions is given.

<code>function no_access_text(&$record){
		return ""Subscribe"";
	}
</code>",,en,0
relationship,68,"The relationship fields.ini directive","[[fields.ini file|Return to fields.ini file directives]]

[[toc]]

===Synopsis===

Certain types of widgets (e.g. grid (v1.0) and checkbox (v1.2)) support the relationship directive which allows them to effectively add/remove records from a specified relationship.  This directive only works with transient fields.

===Example 1: Checkboxes to add/remove categories===

(Note: This example requires Xataface 1.2 or higher to work)

Suppose we have a database that keeps track of courses and the branch of research that they belong to.  A course can be part of multiple branches.  We want to be able to select the branches that a particular course belongs to on the edit form for that course using checkboxes.

Table Structure:
<code>
courses:
   course_id : int (primary key)
   course_title : varchar

branches:
   branch_id : int (primary key)
   branch_name : varchar
   branch_description: text

course_branches:
   course_id : int
   branch_id : int
</code>

Relationship definition:  (from the tables/courses/[[relationships.ini file]]):
<code>
[branches]
    course_branches.course_id=""$course_id""
    course_branches.branch_id=branches.branch_id
</code>

Field definitions: (from tables/courses/[[fields.ini file]]):
<code>
[branches]
  transient=1
  relationship=branches
  widget:type=checkbox
</code>

Things to notice:
# This is a many-to-many relationship (hence the need for the course_branches join table.
# The [branches] field is a transient field.
# The relationship directive from the [[fields.ini file]] references our branches relationship that was defined in the [[relationships.ini file]].
# You can call the field anything that you like.  There is no need for it to have the same name as the relationship.  It just turned out that way in this example.  

===Example 2: Using a grid widget===

Let's modify example 1 slightly to use a grid widget instead of checkboxes.  The grid widget will allow us edit the records in a relationship using dynamic table.  It automatically uses the correct widget for each column of the table according to the definition in the target table's [[fields.ini file]].  Most of the definition can remain the same.  We only change the [[fields.ini file]] directive:

<code>
[branches]
  transient=1
  relationship=branches
  widget:type=grid
  widget:columns=""branch_name,branch_description""
</code>

In this case we are able to edit the branch name and description in each row of the grid.

===See Also===

* [[grid|The grid widget]]
* [[checkbox|The checkbox widget]]
* [[relationships.ini file|The relationships.ini file]]
* [[fields.ini file|The fields.ini file]]","grid widget, relationship, checkbox",en,0
Application_Delegate_Class,12,"Application Delegate Class","[[toc]]

===Synopsis===

The application delegate class is similar to the [[Delegate_class_methods|table_delegate_class]] except that it is applicable to the application as a whole, not just one table.  It allows the developer to implement hooks that will be executed by Xataface to modify behavior.

Examples of customizations that can be made with the Application Delegate class include:

* Permissions
* User Preferences
* Custom content to be inserted into templates.
* Triggers
* more.

===Location===

The delegate class is optional and should be located in the conf/ApplicationDelegate.php file in the application directory.

===Example===

<code>
<?php
class conf_ApplicationDelegate {
   function getPermissions(&$record){
       return Dataface_PermissionsTool::NO_ACCESS();
   }
}
</code>

===Available Methods===

====Triggers====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| after_action_activate
| Trigger called after activation is complete.  Activation occurs after a user registers and responds to the registration confirmation email.
| 1.2.5
|-
| after_action_login
| Trigger called after a user logs in
| 1.0
|-
| after_action_logout
| Trigger called after a user logs out
| 1.0
|-
| after_action_edit
| Trigger called after the edit action completes.
| 1.0
|-
| after_action_new
| Trigger called after new action completes.
| 1.0
|-
| after_action_delete
| Trigger called after the delete action completes.
| 1.0
|-
| [[after_action_activate]]
| Trigger called after successfully email validation (after registering).
| 1.2
|-
| [[before_authenticate]]
| Trigger called just before authentication is carried out.  This allows you to change the authentication type based on such things as SESSION variables etc...
| 1.2.5
|-
| [[beforeHandleRequest]]
| Trigger called on each page request immediately before the action handler is called.  This is handy if you need to perform some action on each page request, such as changing the default action depending on the logged in user.
| 1.0
|-
| [[loginFailed]]
| Trigger called after a failed login attempt.  Allows you to provide your own logging.
| 2.0.1
|-
| [[startSession]]
| If implemented, this overrides how Xataface starts its sessions.  If you implement this method, your custom method should at least include a call to [http://php.net/session_start session_start].
| 1.2.5
|}

====Preferences====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| getPreferences
| Returns the user preference settings.
| 0.6
|}


====Permissions====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| getPermissions
| Returns the permissions available for a given record.
| 0.6
|-
| getRoles
| Returns the roles allowed for a given record.
| 1.0
|-
| __field__permissions
| Returns the default permissions for a field of a given record.
| 1.0
|-
| __field__roles
| Returns the default roles for a field of a given record.
| 1.0
|-
| fieldname__permissions
| Returns the permissions that are allowed for the field ""fieldname"" on a given record.
| 0.7
|-
| fieldname__roles
| Returns the roles that are allowed for the field ""fieldname"" on a given record.
| 1.0
|-
| rel_relationshipname__permissions
| Returns the permissions pertaining to the relationship ''relationshipname'' on a given record.
| 1.0
|-
| rel_relationshiopname__roles
| Returns the role or roles pertaining to the relationship ''relationshipname'' on a given record.
| 1.0
|}

See [[permissions]] for more information about Xataface's permissions architecture and how to implement custom application permissions.

<nowiki><a name=""registration""></a></nowiki>
====Registration====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[beforeRegister]]
| Trigger called before the user registration form is saved.
| 1.0
|-
| [[afterRegister]]
| Trigger called after registration form is saved.
| 1.0
|-
| [[validateRegistrationForm]]
| Validates the input into the registration form.
| 1.0
|-
| [[sendRegistrationActivationEmail]]
| Overrides the sending of the registration activation email.
| 1.0
|-
| [[getRegistrationActivationEmailInfo]]
| Overrides the activation email info.  Returns an associative array of the email details (e.g. subject, to, headers, etc...
| 1.0
|-
| [[getRegistrationActivationEmailSubject]]
| Returns the subject of the activation email.
| 1.0
|-
| [[getRegistrationActivationEmailMessage]]
| Returns the message body for the activation email.
| 1.0
|-
| [[getRegistrationActivationEmailParameters]]
| Returns the parameters for the actication email.
| 1.0
|-
| [[getRegistrationActivationEmailHeaders]]
| Returns the headers for the activation email.
| 1.0
|-
| [[after_action_activate]]
| Trigger fired after activation is complete.
| 1.2
|}

See [[registration form]] for more information about Xataface's registration system and how to allow users to register for an account on your application.

<nowiki><a name=""password-reset""></a></nowiki>
====Forgot Password====

{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getPasswordChangedEmailInfo]]
| Optional method to define the settings for the email that is sent to the user upon successful resetting of their password using the password reset function.  
| 1.3
|-
| [[getResetPasswordEmailInfo]]
| Optional method to define the settings for the email that is sent when a user requests to reset their password.  This step comes before the password changed email as first the user requests a password reset and receives this email.  Then they click a link in this email to reset the password upon which time they receive a second email containing their temporary password.  That email is generated by the [[getPasswordChangedEmailInfo]] method if defined.  If this method is not defined then a generic email predefined in Xataface will be sent instead.
| 1.3
|}




====RSS Feed Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getFeedItem]]
| For RSS Feeds, overrides the defaults and returns an associative array with feed elements for a particular record
| 1.0
|-
| [[getFeed]]
| For RSS feeds, overrides the default feed for a query, returning an array of feed items.
| 1.0
|-
| getFeedSource
| Overrides the default feed source parameter for an RSS feed.
| 1.0
|-
| [[getRelatedFeed]]
| For RSS feeds, overrides the default feed for a related feed.
| 1.0
|-
| getRSSDescription
| Overrides the default generated RSS description for a record.
| 1.0
|}


====Template Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[block__blockname]]
| Outputs content that is meant to override a slot or a block named ""blockname"".
| 0.6
|-
| [[getNavItem]]
| Overrides the navigation menu item for a particular table.
| 1.3
|-
| [[navItemIsSelected]]
| Overrides the ""selected"" setting for nav menu items.  This is used by the default implementation of [[getNavItem]].
| 1.3
|-
| [[getTemplateContext]]
| Returns an associative array of variables that should be made available to all templates.
| 1.0
|}

====Output Cache Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[getOutputCacheUserId]]
| Returns a unique user id that is used by the output cache to ensure that different users don't use the same cached page (unless appropriate).   This is generally not necessary as the output cache by default uses a different cache for each user... but in some cases you may want to use a different cache for the same user.
| 2.0
|}

====Valuelist Customization====
{| class=""listing listing2""
! Name
! Description
! Version
|-
| [[valuelist__valuelistname]]
| Defines a valuelist named ''valuelistname''.
| 0.7
|}
","application delegate class",en,0
LDAP_or_Active_Directory,65,"How to authenticate users with LDAP or Active Directory","[[toc]]

It is often easier to use the existing LDAP or Active Directory to authenticate users in Xataface than to create a new password for every user in the table users.

===In the conf.ini===

In the conf.ini file, in the [auth] part, you need to add your LDAP or AD configuration data :

<code>[_auth]
auth_type=ldap
users_table = xata_users
username_column = id
	ldap_host = ""xxx.xxx.xxx.xxx""
	ldap_port = ""389""
	ldap_base = ""OU=blabla,DC=blablabla""</code>

Here in the table users, you need the login but the password can be just ''PASS'', because the password will be fetched into the LDAP base.
You need to add the [http://weblite.ca/svn/dataface/modules/Auth/ldap/trunk/ auth module] in the conf/modules directory.

===See Also===

* [[authentication]] - Overview of Authenthentication features in Xataface","LDAP,Active Directory,Authentication",en,0
modules,30,"Xataface Modules","[[toc]]

Xataface provides a number of hooks that allow developers to create modules to extend its functionality.  This page lists a handful of the currently available modules.

* [[ShoppingCart|Shopping Cart]] - Converts your application into a shopping cart.
* [[Filemaker]] - Export record sets as Filemaker XML.
* [[DataGrid|Data Grid]] - Editable Datagrid.
* [[Email]] - Convert your database into a email list.  Send email to any found set.
* [[reCAPTCHA module]] - A reCAPTCHA module to add CAPTCHA support to your Xataface forms.
* [[XataJax]] - Platform for building Web 2.0 AJAX applications with Xataface.  Will be a standard component for Xataface starting with version 1.3.

==Module Installation==

You can add modules in either:

# DATAFACE_PATH/modules directory (since 1.0)
# DATAFACE_SITE_PATH/modules directory (since 1.3)

Modules in the DATAFACE_SITE_PATH directory will supersede modules in the DATAFACE_PATH/modules directory (since 1.3).

To activate a module for your application you also need to add an entry to the [[_modules]] section of your [[conf.ini file]].  Each module will come with its own installation instructions.

==Authentication Modules==

Modules to add alternative authentication methods are added to the modules/Auth directory.

==Developing Your Own Modules==

See [[Module Developers Guide]].","modules, captcha",en,0
