<?xml version="1.0"?>
<record><wiki id="wiki?page_id=87">
	<page_name>sql_delegate_method</page_name>
	<page_id>87</page_id>
	<page_title>__sql__ Delegate Method</page_title>
	<content>return to [[Delegate class methods]]

===Synopsis===

The __sql__ delegate class method can be defined in any delegate class to specify the SQL query that should be used to fetch records for a given table.  This method overrides the [[__sql__]] directive of the fields.ini file.  This strategy is primarily used to graft columns from another table onto the base table.

=====Use Caution=====

This is an advanced feature and, if used incorrectly, can muck up your application. Make sure that your SQL query includes a superset of the columns in the base table, and is a row-for-row match for the rows in the base table.  I.e. you should never use an internal join.  Always use a left join so that all of the rows of the base table are returned even if the join table doesn&apos;t have a corresponding row.

If you want to simply filter a table&apos;s records, and don&apos;t need to graft any additional columns onto the table, you should use the [[setSecurityFilters]] method.

===Example===

Given the table foo, its delegate class:

&lt;code&gt;
class tables_foo {
    function __sql__(){
        return &quot;select f.*, c.category_name from foo f left join categories c on f.category_id=c.category_id&quot;;
    }
}
&lt;/code&gt;

This effectively grafts a column &quot;category_name&quot; onto the foo table based on a join with the categories table.

</content>
	<keywords>__sql__, SQL queries, delegate class</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=106">
	<page_name>__global__</page_name>
	<page_id>106</page_id>
	<page_title>__global__ section for the fields.ini file</page_title>
	<content>Return to [[fields.ini file]]

[[toc]]

===Synopsis===

The fields.ini file supports a __global__ section that applies to all fields in the current table.  This is particularly useful for setting up default functionality that you wish to see on all fields except a few.  For example you may wish to have all fields hidden from list view by default, and only explicitly enable a few.  Same for CSV export or the details form.

===Example 1: Hiding All Fields from List View===

In the fields.ini file:
&lt;code&gt;
[__global__]
    ;; hide all of the fields from list view
    visibility:list=hidden

[first_name]
    ;; show the first name in list view 
    visibility:list=visible

[last_name]
    visibility:list=visible

;;.... etc....
&lt;/code&gt;

In the above example we used the __global__ section to declare that we want all fields to be hidden from list view by default.  Then we explicitly showed first_name and last_name in list view. In this case only first_name and last_name will appear in the list view.

==See Also==

*[[fields.ini file]]
*[[visibility:list]]</content>
	<keywords>__global__, fields.ini, visibility:list</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=97">
	<page_name>_auth</page_name>
	<page_id>97</page_id>
	<page_title>_auth section of the conf.ini file</page_title>
	<content>[[conf.ini file|Return to conf.ini file]]

[[toc]]

===Synopsis===

The &apos;&apos;_auth&apos;&apos; section of the conf.ini file includes configuration directives to enable authentication in a Xataface application.  For more information about authentication and registration see [[authentication]].  This section may include the following directives:

===Directives===

{| class=&quot;listing listing2&quot;
|-
! Directive
! Description
! Required
! Default
! Version
|-
| users_table
| The name of the table that contains your user accounts.
| Yes
| None
| 0.6
|-
| username_column
| The name of the column that stores the username.
| Yes
| None
| 0.6
|-
| password_column
| The name of the column that stores the password.
| Required if using basic authentication.
| None
| 0.6
|-
| auth_type
| Specifies the authentication module that is being used.  E.g. basic, cas, ldap, http, facebook, etc...
| No
| basic
| 0.6
|-
| allow_register
| Flag to enable user registration.  If this is set to 1, then a &apos;&apos;register&apos;&apos; link will appear below the login form.
| No
| 0
| 0.8
|-
| session_timeout
| Number of seconds of inactivity after which the user will be logged out. Note: Arithmetic don&apos;t work in the conf.ini, use seconds.
| No
| 86400 (=&gt; 24*60*60 (24 hours))
| 1.3rc4
|}

===See Also===

* [[authentication]] - Overview of Xataface Authentication
* [[conf.ini file]] - Directives available in the conf.ini file.</content>
	<keywords>_auth,authentication,conf.ini file,allow_register</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=114">
	<page_name>XataJax_Compiler</page_name>
	<page_id>114</page_id>
	<page_title>Introduction to the XataJax Compiler</page_title>
	<content>Return to [[XataJax]]

&apos;&apos;&apos;DISCLAIMER&apos;&apos;&apos;: This page introduces features that require Xataface 1.3 or higher.  At present (Jan. 2011) only Xataface 1.2.6 has been released to the public.

[[toc]]

===Synopsis===

The XataJax compiler is a Javascript CSS compiler and linker that comes with the [[XataJax]] module and will be a standard part of Xataface starting in version 1.3.  It provides a mechanism to process and compile (or so to speak) all of the javascripts required for a page request at the time that the page is requested.  This results in a more scalable, manageable javascript and CSS source base - and in improved performance for your applications.

===Compiler Directives===

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| [[xatajax include directive|include]]
| Includes another javascript file inside the current one in place of this directive.  Sample code:&lt;code&gt;//include &lt;myscript.js&gt;&lt;/code&gt;
| XataJax 0.1 Xataface 1.3
|-
| [[xatajax require directive|require]]
| Includes another javscript file inside the current one only if that file hasn&apos;t already been included.  Sample code: &lt;code&gt;//require &lt;myscript.js&gt;&lt;/code&gt;
| XataJax 0.1 Xataface 1.3
|-
| [[xatajax require-css directive|require-css]]
| Includes a CSS script in the CSS file.  This will will search in the [[Dataface_CSSTool]] include path for the script.  Sample code: &lt;code&gt;//require-css &lt;mystyles.css&gt;&lt;/code&gt;
| XataJax 0.1 Xataface 1.3
|-
| [[xatajax load directive|load]]
| Loads the specified Javascript file in a separate script tag.  This enables you to reference other scripts without including them in the same bundle, allowing for more effective caching.  Sample code: &lt;code&gt;//load &lt;myscript.js&gt;&lt;/code&gt;
| XataJax 0.1 Xataface 1.3
|}


===How it Works===

The XataJax compiler works similar to a regular code compiler.  It provides 4 server-side directives to allow you to express dependencies between scripts and stylesheets:

# &apos;&apos;&apos;include&apos;&apos;&apos; : Includes another javascript file inside the current script in place of the &apos;&apos;&apos;include&apos;&apos; directive.
# &apos;&apos;&apos;require&apos;&apos;&apos; : Includes another javascript file inside the current script (if it hasn&apos;t already been included) - i.e. if a script is included twice with a require directive, it will only actually be included once.
# &apos;&apos;&apos;load&apos;&apos;&apos; : Registers a dependency to another script, but doesn&apos;t include it in the same bundle.  This may be used if your script requires code from another javascript, but you don&apos;t want it all to be bundled into the same javascript file.  This may help with caching in certain cases.
# &apos;&apos;&apos;require-css&apos;&apos;&apos; : Registers a dependency to a CSS file.   If your script depends on a CSS file, then it can be registered in this way.


===Brief Example===

&apos;&apos;scriptA.js&apos;&apos;:
&lt;code&gt;
//require &lt;scriptB.js&gt;
alert(&apos;You are in script A&apos;);
&lt;/code&gt;

&apos;&apos;scriptB.js&apos;&apos;:
&lt;code&gt;
alert(&apos;You are in script B&apos;);
&lt;/code&gt;

If you loaded &apos;&apos;scriptA.js&apos;&apos;, it would actually result in the following javascript being executed:
&lt;code&gt;
alert(&apos;You are in script B&apos;);
alert(&apos;You are in script A&apos;);
&lt;/code&gt;

Notice that it included &apos;&apos;scriptB.js&apos;&apos; inside script A before the alert of script A.  That is why script B&apos;s alert comes first.  Note that this example won&apos;t work if you simply try to load scriptA.js directly in Apache.  These directives are only evaluated if the scripts are served by Xataface.  Here is a simple Xataface action that demonstrates how to use this in your Xataface script.

====Creating a custom action====

In your application directory, create an &apos;&apos;actions&apos;&apos; directory if you don&apos;t already have one.  Then create a single file named &apos;&apos;hello.php&apos;&apos; with the following content:
&lt;code&gt;
class actions_hello {
    function handle($params){
        $jsTool = Dataface_JavascriptTool::getInstance();
        $jsTool-&gt;addPath(&apos;js&apos;, DATAFACE_SITE_URL.&apos;/js&apos;);
        $jsTool-&gt;import(&apos;scriptA.js&apos;);
        echo &apos;&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&apos;.$jsTool-&gt;getHtml().&apos;&lt;/body&gt;&lt;/html&gt;&apos;;
        exit;
    }
}
&lt;/code&gt;

&apos;&apos;&apos;About this code:&apos;&apos;&apos;

&lt;code&gt;$jsTool = Dataface_JavascriptTool::getInstance();&lt;/code&gt;
We start by obtaining an instance of the JavascriptTool.  This is the object that does all of the magic of compiling your scripts and managing dependencies.

&lt;code&gt;$jsTool-&gt;addPath(&apos;js&apos;, DATAFACE_SITE_URL.&apos;/js&apos;);&lt;/code&gt;
This line adds the &apos;&apos;js&apos;&apos; directory to the tool&apos;s include path, and specifies (with the 2nd parameter) the URL to reach this directory also.  The JavascriptTool works like most source code compilers.  You need to give it the path where it can expect to find its libraries and scripts.  Only paths that you add here will be searched for javascripts.  You can add as many paths as you like.  By default it will have the DATAFACE_PATH/js and the XATAJAX_PATH/js directories in the include path so you can directly reference any scripts in those directories always.

&lt;code&gt; $jsTool-&gt;import(&apos;scriptA.js&apos;);&lt;/code&gt;
This is where we declare that we want to use &apos;&apos;scriptA.js&apos;&apos; in the current request.  This line then assumes that the scriptA.js file is located in one of the directories of the current include path.  In our case we make sure that it resides in the DATAFACE_SITE_PATH/js directory.

&lt;code&gt;echo &apos;&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;&apos;.$jsTool-&gt;getHtml().&apos;&lt;/body&gt;&lt;/html&gt;&apos;;&lt;/code&gt;
On this line we simply output the HTML script tags that the javascript tool generates linking to our resulting script.  


Now we can test our our action by going to the page index.php?-action=hello.  If everything worked correctly you should see the appropriate alert dialogs appear  - first telling you you&apos;re in Script B, then telling you you&apos;re in Script A.  If it doesn&apos;t work, you should check your javascript error logs to see what went wrong.

&apos;&apos;&apos;NOTE:&apos;&apos;&apos; - This simple example actually shows you the step of writing out the HTML tags explicitly with the getHtml() method.  If you are using a standard Xataface template that is based on the Dataface_Main_Template.html template, then this step is unnecessary because the XataJax module will automatically include this HTML just before the closing &lt;/body&gt; tag in your pages.



</content>
	<keywords>XataJax, compiler, javascript, css, compiler</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=113">
	<page_name>XataJax</page_name>
	<page_id>113</page_id>
	<page_title>Introduction to XataJax</page_title>
	<content>[[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 &amp; Linker]]
# A Javascript component library &amp; API

====The Javascript/CSS Compiler &amp; 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&apos;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&apos;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 &amp; 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.</content>
	<keywords>XataJax, Ajax, Web 2.0</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=101">
	<page_name>Introduction_to_the_Xataface_API</page_name>
	<page_id>101</page_id>
	<page_title>Introduction to the Xataface API</page_title>
	<content>Back to [http://xataface.com/wiki the wiki]

[[toc]]

===Synopsis===

Xataface is provides an API to help in developing your own custom actions.  This API includes objects and functions to more easily interact with the database (i.e. search, edit, delete, and save records), build forms, use templates, and more.  This section of the wiki endeavors to highlight some of the more useful and commonly used aspects of the API.

===The dataface-public-api.php Facade===

Much of the functionality provided by the Xataface API is wrapped up easy-to-use functions which are made available in the dataface-public-api.php script, which is always present in a Xataface application (it is loaded at the beginning of your index.php file).

===Some Common Tasks===

====Loading a Single Record from the Database====

&lt;code&gt;
// Load record from &apos;people&apos; table matching person_id=10
$record = df_get_record(&apos;people&apos;, array(&apos;person_id&apos;=&gt;10)); 

// Load record from people table with first_name &apos;John&apos; and last_name &apos;Smith&apos; 
$record2 = df_get_record(&apos;people&apos;, array(&apos;first_name&apos;=&gt;&apos;=John&apos;, &apos;last_name&apos;=&gt;&apos;=Smith&apos;));

// $record and $record2 are Dataface_Record objects.
echo &quot;Loaded Person: &quot;.$record-&gt;val(&apos;person_id&apos;).
      &quot; named &quot;.$record-&gt;val(&apos;first_name&apos;).&apos; &apos;.$record-&gt;val(&apos;last_name&apos;);
&lt;/code&gt;

In the above examples we load a [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object and use the val() method to display particular field values.

The 2nd arguments of df_get_record() is an array which serves as a query.  See [[URL Conventions]] for more examples of the types of queries that you can provide here.

====Loading a set of records from the Database====

&lt;code&gt;
//  Load the first 30 canadians from the people table
$people = df_get_records_array(&apos;people&apos;, array(&apos;nationality&apos;=&gt;&apos;=canadian&apos;));
foreach ( $people as $person){
    // $person is a Dataface_Record object
    echo &quot;&lt;br&gt;Person &quot;.$person-&gt;val(&apos;person_id&apos;).&quot; is named &quot;.$person-&gt;val(&apos;first_name&apos;);
}
&lt;/code&gt;

&apos;&apos;&apos;Caveat:  Note that when loading records using df_get_records_array() it only loads a preview of each record for memory&apos;s sake.&apos;&apos;&apos;  A preview of the record is the same as a full record except that all fields are truncated to be less than 255 characters.  If you have long text fields that you need to load, then these will be truncated.  There are a few different solutions if you need to load the entire contents of a long field, including:

* Use df_get_record instead.  (This is only preferable if you are only loading a single record).
* Use the [[struct]] [[fields.ini file]] directive on the field to designative the field contents as a &apos;stucture&apos; that should never be truncated.
* Use the extended form of &apos;&apos;df_get_records_array()&apos;&apos; with the 5th parameter (preview) set to false.  E.g. &lt;code&gt;
$people = df_get_records_array(&apos;people&apos;,array(), null, null, false);
&lt;/code&gt;

====Editing and Saving a Record====

&lt;code&gt;
$person = df_get_record(&apos;people&apos;, array(&apos;person_id&apos;=&gt;10));

// Using setValue() to set a single field value.
$person-&gt;setValue(&apos;first_name&apos;, &apos;Peggy&apos;);

// Using setValues() to set multiple field values at once
$person-&gt;setValues(array(&apos;first_name&apos;=&gt;&apos;Peggy&apos;, &apos;last_name&apos;=&gt;&apos;Sue&apos;));

// Commit the changes to the database
$person-&gt;save();
&lt;/code&gt;

</content>
	<keywords>xataface api, df_get_record, df_get_records_array, Dataface_Record, Editing, Saving, Loading, Searching</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=76">
	<page_name>GettingStarted:customizing</page_name>
	<page_id>76</page_id>
	<page_title>Customizing Field labels, descriptions, and widgets</page_title>
	<content>==Customizing Field labels, descriptions, and widgets==

Using simple INI configuration files, you can customize the look and feel of your application. You can change widgets, labels, field descriptions, and more.
In the previous 2 sections we learned how to create a simple application by desiging a database and then installing the basic directory structure to make our application operational. Now it is time to &quot;decorate&quot; the application a little bit. Decoration occurs by way of simple configuration files that are placed in strategic locations in the application. We can customize such things as:

* Widget types (e.g., use a select list for a field rather than a text field)
* Labels (e.g., The ProgramName field&apos;s label can say &quot;Program Name&quot; instead of just &quot;ProgramName&quot;)
* Field Descriptions . You can add descriptions to fields to help explain their meaning and how to use the application.
* HTML attributes. (e.g., Make a text field 50 characters wide)

===Table Configuration Directories===

You will recall, that when we used the &apos;makesite&apos; script to generate the directory structure for our web application, it created a directory named &apos;tables&apos;, with subdirectories named after each of the tables in our database. The directory structure of the application looked like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/directory-structure-1.gif]]

The &apos;tables/Program&apos; and &apos;tables/Course&apos; are refered to as &quot;table configuration directories&quot; . All of the configuration files a table in a Xataface application are stored in its associated table configuration directory. For example all configuration files for the &apos;Program&apos; table are located in the &apos;tables/Program&apos; directory.

There are 4 main files that are generally contained in a table&apos;s configuration directory:

* &apos;&apos;&apos;fields.ini&apos;&apos;&apos; - Contains configuration for the fields of the table (e.g., field labels, descriptions, widget types, etc...)
* &apos;&apos;valuelists.ini&apos;&apos;&apos; - Contains value lists (vocabularies) that can be used in the table to limit input into certain fields like select lists.
* &apos;&apos;&apos;relationships.ini&apos;&apos;&apos; - Defines the relationships between this table and other tables in the application.
* &apos;&apos;&apos;&lt;TableName&gt;.php&apos;&apos;&apos; (where &lt;TableName&gt; is the name of the table. - A delegate PHP class that allows you to further customize the behavior of the application with respect to this table. May contain custom fields, importing/exporting functionality, permissions information, and more...

===Customizing Labels and Descriptions===

We will start off by adding custom labels and descriptions to the &apos;Program&apos; table of our &apos;FacultyOfWidgetry&apos; application. This sort of customization settings are placed in a file named &apos;fields.ini&apos; inside the table&apos;s configuration directory.

# Create the &apos;fields.ini&apos; file in the Program table configuration directory (i.e., tables/Programs/fields.ini).
# Add the following to this file:&lt;code&gt;
[ProgramName]
	widget:label = &quot;Program Name&quot;
	widget:description = &quot;Enter the name of the program&quot;
&lt;/code&gt;&lt;nowiki&gt;&lt;br&gt;&lt;/nowiki&gt;Now look at the &quot;Edit Record&quot; form in the Xataface application:

[[Image:http://xataface.com/documentation/tutorial/getting_started/program-name-label-1.gif]]


Notice how the label for the &quot;ProgramName&quot; now says &quot;Program Name&quot; (note the space between &quot;Program&quot; and &quot;Name&quot;). And its description matches the description specified in the fields.ini file.

The widget:label and widget:description attributes can be defined for any field in any table of the application.

===Using different widgets===

If no widgets are defined in the fields.ini file, a Xataface application will make a best guess at the type of widget that should be used to edit the value in a field. In general, the widgets used by default are as follows:

* VARCHAR, CHAR, INT : html text field
* DATE, DATETIME fields: calendar widget
* TEXT fields : html text area
* BLOB fields : html file upload field
* INT Fields with &quot;AUTO INCREMENT&quot; : html hidden field
* VARCHAR or CHAR fields with &quot;Password&quot; or &quot;password&quot; as part of the name : html password field
* ENUM fields : html select list
* SET fields : html checkbox group (not yet supported as of this writing).

You can change the widget that is used to edit a field by specifying a &quot;widget:type&quot; attribute for the field in the fields.ini file. For more information about the available widgets, see [[widget:type]].

====Example: Using HTML Editor to edit the HTMLOutline field====

Clearly the HTMLOutline field in the Program table is intended to store HTML content. By default our application only provides a text area to do the editing so the user is expected to enter the HTML markup by hand. It would be much better to provide the user with a WYSIWYG (What you see is what you get) HTML editor widget. That is exactly what we are going to do.
We will add a section to the fields.ini file so that it now looks like: &lt;code&gt;
[ProgramName]
	widget:label = &quot;Program Name&quot;
	widget:description = &quot;Enter the name of the program&quot;

[HTMLOutline]
	widget:type = &quot;htmlarea&quot;
&lt;/code&gt;

Now refresh the Xataface application in your web browser and look at the edit form for a record of the Program table:

[[Image:http://xataface.com/documentation/tutorial/getting_started/htmlarea-1.gif]]

As you can see, the HTMLOutline field now has an HTML Editor widget for editing. Most users will find this much nicer to work with than a normal text area. Xataface uses FCKEditor for its html editor widget.

There are a number of widgets that can be specified in the [[widget:type]] parameter:

* &apos;&apos;&apos;[[checkbox]]&apos;&apos;&apos; - An HTML checkbox (or checkbox group depending on context).
* &apos;&apos;&apos;[[date]]&apos;&apos;&apos; - Month/Day/Year select lists for selecting dates.
* &apos;&apos;&apos;[[calendar]]&apos;&apos;&apos; - A text field with a button that opens a small calendar widget when clicked.
* &apos;&apos;&apos;[[group]]&apos;&apos;&apos; - A complex widget type for editing multiple values as a group (useful for XML fields)
* &apos;&apos;&apos;[[hidden]]&apos;&apos;&apos; - a hidden field
* &apos;&apos;&apos;[[password]]&apos;&apos;&apos; - An HTML password widget
* &apos;&apos;&apos;[[select]]&apos;&apos;&apos; - An HTML select list (requires the &apos;vocabulary&apos; attribute)
* &apos;&apos;&apos;[[static]]&apos;&apos;&apos; - an uneditable field
* &apos;&apos;&apos;[[table]]&apos;&apos;&apos; - A complex widget type for editing multiple values in a tabular format (Useful for XML fields)
* &apos;&apos;&apos;[[text]]&apos;&apos;&apos; - an html text field
* &apos;&apos;&apos;[[textarea]]&apos;&apos;&apos; - an html text area

===Changing HTML attributes of widgets===

Sometimes you may want even finer grained control of your widgets&apos; appearance than to just specify the type, label, and desription. Perhaps you want to make a text field 50 characters wide, or to set the CSS class of the html element. This can be done using the &apos;widget:atts:&apos; parameter for a field. A short example is the easiest way to explain how this works.

Modify the fields.ini for the Program table so it looks like:&lt;code&gt;
[ProgramName]
widget:label = &quot;Program Name&quot;
widget:description = &quot;Enter the name of the program&quot;
widget:atts:size = 50
widget:atts:style = &quot;font-size: 24pt; font-family: Apple Chancery&quot;

[HTMLOutline]
widget:type = htmlarea
&lt;/code&gt;

We have added 2 lines:&lt;code&gt;
widget:atts:size = 50
widget:atts:style = &quot;font-size: 24pt; font-family: Apple Chancery&quot;
&lt;/code&gt;

What this does is add the html attributes size=&quot;50&quot; and style=&quot;font-size: 24pt; font-family: Apple Chancery&quot; to the html text field that is used to edit the ProgramName field.
Look at the results:

[[Image:http://xataface.com/documentation/tutorial/getting_started/widget-atts-1.gif]]

The HTML tag for the text field now looks like:&lt;code&gt;
&lt;input class=&quot;default&quot; id=&quot;ProgramName&quot; name=&quot;ProgramName&quot; 
	type=&quot;text&quot; size=&quot;50&quot; 
	style=&quot;font-size: 24pt; 
		font-family: Apple Chancery&quot; 
	value=&quot;Basic Widgetry&quot; 
/&gt;	
&lt;/code&gt;
In fact you can add arbitrary attributes to any of the fields using the same convention. Some useful examples are:

* &apos;&apos;&apos;[[widget:atts:rows]]&apos;&apos;&apos; for text areas to set the number of rows of text they should display.
* &apos;&apos;&apos;[[widget:atts:cols]]&apos;&apos;&apos; for text areas to set the number of columns (1 character = 1 column)
You can even use javascript calls in here if you like:
* &apos;&apos;&apos;[[widget:atts:onclick]]&apos;&apos;&apos; = &quot;doJsFunction();&quot;

===Download source files===

[http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-6-tar.gz Download the source files] for this application as a tar.gz archive
These source files reflect the state of the application at the current point of the tutorial. As changes are made to the application in later sections, downloads of those versions are made available for download also.

===Summary===
In this section we learned how to change the labels, descriptions, and widgets for fields. We also learned how to add HTML attributes to the widgets to achieve very fine-grained control over the display of our forms.</content>
	<keywords>widget labels descriptions onclick handlers</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=77">
	<page_name>GettingStarted:valuelists</page_name>
	<page_id>77</page_id>
	<page_title>Using Valuelists</page_title>
	<content>==Using Value-lists==

Value-lists serve as vocabularies that can be used for fields such as select lists, checkbox groups, and auto-complete fields.

So far we have not used any enumerated fields such as select lists, checkbox groups, or auto-completion fields in our examples. This is because we are missing a key ingredient that is required by all of these widget types: a vocabulary. We need a way to define options for these fields.

This is where &apos;valuelists&apos; come into play. A valuelists is essentially a list of key-value pairs that can be used as a vocabulary in enumerated fields like checkbox groups, select lists, and auto-completion fields. Valuelists are defined in the valuelists.ini file in each table&apos;s configuration directory.

===Example 1: Use a select list for the Subject field in the Course table===

The &quot;Subject&quot; field in the &quot;Course&quot; table really shouldn&apos;t be a free-form field that will accept any value. The user should just be able to pick from a finite list of subjects in a select list. To make these changes we will follow these steps:

# Create the configuration directory for the &quot;Course&quot; table if it does not exist yet.
# Create a file named &apos;fields.ini&apos; inside the Course table&apos;s configuration directory (i.e., tables/Course/fields.ini), if it does not already exist.
# Create a file named &apos;valuelists.ini&apos; inside the Course table&apos;s configuration directory (i.e., tables/Course/valuelists.ini) if it does not already exist.
Your application directory structure should now look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/application-structure-valuelists.gif]]
# Edit the valuelists.ini file so that it looks like:&lt;code&gt;
[Subjects]
	ENGL = English
	MATH = Math
	PHYS = Physics
	CHEM = Chemistry
&lt;/code&gt; This defines a valuelist named &apos;Subjects&apos; with values {ENGL, MATH, PHYS, CHEM} and associated labels {English, Math, Physics, Chemistry}. The values (i.e., ENGL, MATH, etc..) represent what will be stored in the database, and the values is a user-friendly representation that will be displayed on the screen.
# Now we edit the fields.ini file so that it looks like:&lt;code&gt;
[Subject]
	widget:type = select
	vocabulary = Subjects
&lt;/code&gt; This tells Xataface that we want to use a select widget to edit the &quot;Subject&quot; field, and its values should be drawn from the &quot;Subjects&quot; valuelist.
#Navigate to the &quot;Course&quot; table in our application and select &quot;new record&quot; from the &quot;Actions to be performed menu&quot; in the top left.&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/actions-menu-1.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;br/&gt;&lt;/nowiki&gt;This will bring up a form to create a new Course record, so that we can see what the form looks like. It should look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/new-course-form-1.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;Notice that the &quot;Subject&quot; field is represented by a select widget, its options are as follows:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/course-subject-pulldown-1.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt; And if you look at the HTML source code for this select list, it would look like:&lt;code&gt;
&lt;select class=&quot;default&quot; id=&quot;Subject&quot; name=&quot;Subject&quot;&gt;
	&lt;option value=&quot;&quot;&gt;Please Select...&lt;/option&gt;
	&lt;option value=&quot;ENGL&quot;&gt;English&lt;/option&gt;
	&lt;option value=&quot;MATH&quot;&gt;Math&lt;/option&gt;
	&lt;option value=&quot;PHYS&quot;&gt;Physics&lt;/option&gt;
	&lt;option value=&quot;CHEM&quot;&gt;Chemistry&lt;/option&gt;
&lt;/select&gt;
&lt;/code&gt;

===Example 2: Using a checkbox group for the &apos;Subject&apos; field===

In Example 1, we showed how to use a select list for the &apos;Subject&apos; field in the &apos;Course&apos; table. This is great if each course can only be one subject. But what if a course can be categorized in 2 subject areas. Then we will need a widget the allows you to select multiple items. Checkbox groups work well for this.
Make a change to the &apos;fields.ini&apos; file for the &apos;Course&apos; table to change the widget:type attribute of the &apos;Subject&apos; field to &apos;checkbox&apos; as follows:&lt;code&gt;
[Subject]
widget:type = checkbox
vocabulary = Subjects
&lt;/code&gt;

Now load the form again and notice that the &apos;Subject&apos; field is now represented by checkboxes.

[[Image:http://xataface.com/documentation/tutorial/getting_started/checkbox-group-1.gif]]

You may be wondering how we store multiple values in a single field. In this case Subject is treated as a &apos;repeat&apos; field where each value is on a separate line. I.e., with the form above, if we clicked &apos;save&apos; and checked the values stored in the database we would see:&lt;code&gt;
PHYS
CHEM
&lt;/code&gt;

As the value in the &apos;Subject&apos; field. Please note that if you are going to use a repeating field like this, you should make sure that the field is &apos;big&apos; enough to store all of the values. E.g., I think my Subject field was a VARCHAR(64) (64 characters long), so the sum of the lengths of all of the values &apos;checked&apos; for &apos;Subject&apos; should be less than 64.

===Example 3: Dynamic Valuelists based on the results of SQL queries===

Example 1 &amp; 2 demonstrated the basic idea of valuelists and how they can be used as values for select lists and checkbox groups. However defining valuelists &quot;statically&quot; inside the valuelists.ini file doesn&apos;t really seem to offer anything over using and ENUM or SET field in the MySQL database. In many cases we want the user to be able to choose from a number of options that are pulled from the database. For example, we may want the user to be able to specify the Program that a Course belongs to, using a pull-down list.

Recall that when we created the &apos;Course&apos; table we included a field named &apos;ProgramID&apos; to store the ID number of the Program that this course belongs to. It would be unreasonable to expect the users of your application to remember the ID number of the Program to which the course belongs when they are filling in the &apos;Course&apos; form. It would be much better if the user could choose the program from a list of available programs. Fortunately, this functionality is simple to add:

# Add a valuelist named &apos;Programs&apos; to the valuelists.ini file for the &apos;Course&apos; table as follows:&lt;code&gt;
[Programs]
	__sql__ = &quot;SELECT ProgramID, ProgramName FROM Program ORDER BY ProgramName&quot;
&lt;/code&gt; &apos;&apos;&apos;Note: Make sure you use two underscores on either side of &apos;sql&apos; in the above example. It should be &apos;__sql__&apos; not &apos;_sql_&apos;.&apos;&apos;&apos;&lt;nowiki&gt;&lt;p&gt;&lt;/nowiki&gt;This valuelist will be a list of the records in the &apos;Program&apos; table in alphabetical order on the program name. Note that this query selects 2 columns. The first column is always taken to be the ID column of the value-list and the 2nd column (if specified) is the Name column of the valuelist. The ID column is what will actually be stored in the database, and the Name column is what will be shown to the user in place of the ID.&lt;nowiki&gt;&lt;/p&gt;&lt;/nowiki&gt;
# Add a field definition for the ProgramID field in the fields.ini file of the &apos;Course&apos; table as follows:&lt;code&gt;
[ProgramID]
	widget:type = select
	vocabulary = Programs
&lt;/code&gt;

Now we can load up our form and see what it looks like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/programid-select-list.gif]]

We can see that the ProgramID field now appears with a select list of all of the programs in the database. The HTML code for the select list is:&lt;code&gt;
&lt;select class=&quot;default&quot; id=&quot;ProgramID&quot; name=&quot;ProgramID&quot;&gt;
	&lt;option value=&quot;&quot;&gt;Please Select...&lt;/option&gt;
	&lt;option value=&quot;2&quot;&gt;Advanced Widgetry&lt;/option&gt;
	&lt;option value=&quot;1&quot;&gt;Basic Widgetry&lt;/option&gt;
	&lt;option value=&quot;3&quot;&gt;International Widgetry&lt;/option&gt;
&lt;/select&gt;&lt;/code&gt;

===Download Source Files===

[http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-7-tar.gz Download application source files as tar.gz archive]

These source files reflect the application&apos;s state at this point in the tutorial. As changes are made to the application in later sections, modified source archives will be available to be downloaded.

===Summary===

In this section, we have learned how to use valuelists to add selection lists and checkbox groups to our web forms. We also shows how valuelists can be dynamically defined using SQL. Using valuelists in this way is like defining a many-to-one relationship to our database (in example 3, it was many &apos;Course&apos; records to one &apos;Program&apos; record). In the next section we will learn how to add many-to-many and one-to-many relationships to our database in such a way that records can be easily added and removed from relationships using Xataface.</content>
	<keywords>valuelists, __sql__, select lists, checkbox options,checkbox groups,vocabularies</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=5">
	<page_name>valuelists.ini_file</page_name>
	<page_id>5</page_id>
	<page_title>valuelists.ini_file</page_title>
	<content>==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 &quot;people&quot; its valuelists.ini file will be stored in &quot;tables/people/valuelists.ini&quot;.

In addition you can define an application-wide valuelists.ini file in the root of your application&apos;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.

&lt;code&gt;
[colors]
    r=Red
    b=Blue
    g=Green
&lt;/code&gt;

This example would define a single valuelist named &quot;colors&quot; with 3 values: r,g, and b (with corresponding labels &quot;Red&quot;, &quot;Green&quot;, and &quot;Blue).  The values (the left of the equals sign) are stored in the database, while the labels are rendered on screen for the user&apos;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.

&lt;code&gt;
[colors]
    __sql__ = &quot;select colorCode, colorName from colors&quot;
&lt;/code&gt;


===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:

&lt;code&gt;
function valuelist__colors(){
    return array(
        &apos;r&apos;=&gt;&apos;Red&apos;,
        &apos;g&apos;=&gt;&apos;Green&apos;,
        &apos;b&apos;=&gt;&apos;Blue&apos;
    );
}
&lt;/code&gt;

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:

&lt;code&gt;
function valuelist__colors(){
    static $colors = -1;
    if ( !is_array($colors) ){
        $colors = array();
        $res = mysql_query(&quot;select colorCode, colorName from colors&quot;, df_db());
        if ( !$res ) throw new Exception(mysql_error(df_db()));
        while ($row = mysql_fetch_row($res) ) $colors[$row[0]] = $row[1];
    }
    return $colors;
}
&lt;/code&gt;

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.</content>
	<keywords>valuelists, dynamic valuelists, programmatically defined valuelists</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=95">
	<page_name>validators</page_name>
	<page_id>95</page_id>
	<page_title>validators:NAME fields.ini directive</page_title>
	<content>Return to [[fields.ini file]]

[[toc]]

===Synopsis===

In the fields.ini file you can specify validation rules to be applied to any field by adding the validators:NAME directive in that field&apos;s section of the [[fields.ini file]].

===Available Validators===

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Value
! Version
|-
| required
| Field is required
| 1
| All
|-
| maxlength
| Maximum number of characters allowed.
| $length
| All
|-
| minlength
| Minimum number of characters allowed.
| $length
| All
|-
| rangelength
| Range (min and max) characters allows
| $min,$max
| All
|-
| email
| Input must be syntactically correct email address.
| 1
| All
|-
| emailorblank
| Accepts an email address or a blank field.
| 1
| All
|-
| regex
| Input must match the provided regular expression.
| A regular expression
| All
|-
| lettersonly
| Input must contain only letters (i.e. [a-zA-Z]
| 1
| All
|-
| numeric
| The input must contain a valid positive or negative integer or decimal number.
| 1
| All
|-
| nopunctuation
| The input must not contain any of these characters: &lt;nowiki&gt;( ) . / * ^ ? # ! @ $ % + = , &quot; &apos; &amp;gt; &amp;lt; ~ [ ] { }.&lt;/nowiki&gt;
| 1
| All
|-
| nonzero
| The input must not begin with zero.
| 1
| All
|-
| uploadedfile
| The element must contain a successfully uploaded file.
| 1
| All
|-
| maxfilesize
| The uploaded file must be no more than $size bytes.
| $size
| All
|-
|filename
| The uploaded file must have a filename that matches the regular expression $file_rx.
| $file_rx
| All
|}


===Examples===

To make a the first_name field required we add the following to the [[fields.ini file]]:
&lt;code&gt;
[first_name]
    validators:required=1
&lt;/code&gt;

&apos;&apos;&apos;Note that fields that are declared NOT NULL in the database are required by default.&apos;&apos;&apos;.  If you wanted to remove the &apos;&apos;required&apos;&apos; validator from a field that is NOT NULL in the database you would add the following to the [[fields.ini file]]:
&lt;code&gt;
[first_name]
    validators:required=0
&lt;/code&gt;

===See Also===

* [[fieldname__validate]] - For more complex validation you can define the [[fieldname__validate]] method in the [[Delegate class methods|Table Delegate Class]].
* [http://www.devarticles.com/c/a/Web-Graphic-Design/Using-HTML-Quickform-for-Form-Processing/12/ HTML_QuickForm article] going over HTML_Quickform validation.  Dataface&apos;s forms are built on HTML_QuickForm.
* [http://xataface.com/documentation/tutorial/getting_started/validation Form Validation] - Section from getting started tutorial introducing form validation in a tutorial format.

</content>
	<keywords>validation, form validation, validators,validator:name</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=96">
	<page_name>validators:VALIDATOR_NAME:message</page_name>
	<page_id>96</page_id>
	<page_title>validators:VALIDATOR_NAME:message directive for the fields.ini file</page_title>
	<content>Return to [[fields.ini file]]

[[toc]]

===Synopsis===

If you want to customize the error message associated with a particular [[validator|validation rule]] you can use the validators:VALIDATOR_NAME:message directive in the fields.ini file.

===Format===

&lt;code&gt;
[myfield]
    validators:VALIDATOR_NAME:message = MESSAGE
&lt;/code&gt;

===Examples===

If you don&apos;t like the default error message that is displayed when you make the first_name field required, you can customize it with your own message.  E.g.
&lt;code&gt;
[first_name]
    validators:required=1
    validators:required:message = &quot;Please enter your first name&quot;
&lt;/code&gt;

===See Also===

* [[validators]] - The [[fields.ini file]] directive for adding a validation rule to a field.  This directive must be used in conjunction with [[validators]].
* [[fieldname__validate]] - For more complex validation rules you can define them in the table delegate class.
* [http://xataface.com/documentation/tutorial/getting_started/validation Form Validation] - Section in the Getting Started tutorial on form validation.</content>
	<keywords>validation messages,error messages,form validation rules</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=94">
	<page_name>fieldname__validate</page_name>
	<page_id>94</page_id>
	<page_title>fieldname__validate Delegate Class Method</page_title>
	<content>Return to [[Delegate class methods]]

[[toc]]

===Synopsis===

Xataface allows you to add validation on any particular field in table by adding a fieldname__validate method to the table&apos;s delegate class of the form:
&lt;code&gt;
function myfield__validate(&amp;$record, $value, &amp;$params){
    if ( $value != &apos;Steve&apos; ){
        $params[&apos;message&apos;] = &apos;Sorry you must enter &quot;Steve&quot;&apos;;
        return false;
    }
    return true;
}
&lt;/code&gt;

===Parameters===

* &amp;$record : A [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object encapsulating the record we are validating.  Note that the values of this object correspond with the submitted values from the form, and not necessarily the actual values of the record in the database.
* $value : The value that is being inserted.
* &amp;$params : An output array that can be used to pass back a message if validation fails.  You would set this array&apos;s &apos;message&apos; parameter to be a message.

===Returns===

Returns a boolean value.  True if the value is ok and false if validation failed.

===See Also===

* [[validators]] - For simple validation rules you can use the [[validators|validator:VALIDATOR_NAME]] directive of the [[fields.ini file]].
* [http://xataface.com/documentation/tutorial/getting_started/validation Form Validation] - Section on form validation in the Getting Started tutorial.

</content>
	<keywords>validate, validation, delegate class validation, custom validator</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=37">
	<page_name>URL_Conventions</page_name>
	<page_id>37</page_id>
	<page_title>URL_Conventions</page_title>
	<content>==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 &apos;&apos;index.php?-table=people&apos;&apos; will take you to the &apos;&apos;people&apos;&apos; table (and since the default action for a Xataface application is &apos;&apos;list&apos;&apos;, it will take you to the &apos;&apos;list&apos;&apos; view.

You could be more explicit by specifying the action in the URL directly: &apos;&apos;index.php?-table=people&amp;-action=list&apos;&apos;.  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&apos;ll see in the next section.

===Available GET Parameters===


{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Default
! Version
|-
| -action
| Specifies the action to perform.  E.g. &apos;&apos;browse&apos;&apos;, &apos;&apos;list&apos;&apos;, &apos;&apos;find&apos;&apos;, &apos;&apos;edit&apos;&apos;, &apos;&apos;new&apos;&apos;, ... 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 &apos;&apos;-skip=29&apos;&apos;.

Not to be confused with the &apos;&apos;-cursor&apos;&apos; parameter which is used to specify which record to view in the &apos;&apos;details&apos;&apos; 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 &quot;current&quot; record.  This is used in the &apos;&apos;details&apos;&apos; 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 &quot;No records found&quot;.  Generally you would only use this in a custom action where you are not relying on Xataface&apos;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. &apos;-&apos;).  This is a convention Xataface uses to distinguish directives from search queries.  All parameters that do not begin with &apos;-&apos; are treated as a query to filter the found set.

For example, &apos;&apos;first_name=bob&apos;&apos; used as a GET parameter would cause the found set to be filtered so that only records where the &apos;&apos;first_name&apos;&apos; column contains the phrase &quot;bob&quot; are returned.  Putting this all together, suppose we wanted to show the list tab for the &apos;&apos;people&apos;&apos; table, but only wanted to show the people with first names containing &quot;bob&quot;:

index.php?-action=list&amp;-table=people&amp;first_name=bob

====Exact, Range, and Pattern Matching====

By default, queries on text columns look for partial matches.  I.e. if you search for &quot;bob&quot; it will match &quot;bob&quot;, &quot;bobby&quot;, &quot;rubob&quot;, and any other text that contains &quot;bob&quot;.  If you are only interested in finding records that match &apos;&apos;exactly&apos;&apos; &quot;bob&quot;, then you can prepend an &quot;=&quot; to the query.  E.g. &apos;&apos;first_name==bob&apos;&apos;, or the full URL:

index.php?-action=list&amp;-table=people&amp;first_name==bob

This should show the &apos;&apos;list&apos;&apos; tab for the &apos;&apos;people&apos;&apos; table with only records with first name exactly &quot;bob&quot;.

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=&quot;listing listing2&quot;
|-
! Prefix
! Usage Example
! Description
|- 
| &gt;
| age=&gt;10
| Match records greater than search parameter.
|-
| &lt;
| age=&lt;10
| Match records less than search parameter.
|-
| &gt;=
| age=&gt;=10
| Match records greater than or equal to the search parameter.
|-
| &lt;=
| age=&lt;=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 &apos;%&apos; and &apos;?&apos; in your search.
|}


=====Search Examples=====

Given the following data set:

{| class=&quot;listing listing2&quot;
|-
! 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=&quot;listing listing2&quot;
|-
! Query
! Matches
|- 
| age=&gt;10 
| match records where &apos;&apos;age&apos;&apos; is greater than 10.  This includes &apos;&apos;Cindy&apos;&apos; and &apos;&apos;Kabob&apos;&apos;.
|-
| age=&lt;10 
| match records where &apos;&apos;age&apos;&apos; is less than 10.  This includes &apos;&apos;Julie&apos;&apos; and &apos;&apos;Jake&apos;&apos;
|-
| age=&gt;=10 
| match records where &apos;&apos;age&apos;&apos; is greater or equal to 10.  This includes &apos;&apos;Bob&apos;&apos;, &apos;&apos;Cindy&apos;&apos;, and &apos;&apos;Kabob&apos;&apos;.
|-
| age=&lt;=10
| match records where &apos;&apos;age&apos;&apos; is less than or equal to 10. This includes &apos;&apos;Bob&apos;&apos;, &apos;&apos;Julie&apos;&apos;, and &apos;&apos;Jake&apos;&apos;.
|-
| age=8..10
| match records where &apos;&apos;age&apos;&apos; is between 8 and 10.  This includes &apos;&apos;Bob&apos;&apos; and &apos;&apos;Jake&apos;&apos;.
|-
| first_name=bob
| Matches records where &apos;&apos;first_name&apos;&apos; contains &quot;bob&quot;.  This includes &apos;&apos;Bob&apos;&apos; and &apos;&apos;Kabob&apos;&apos;.
|-
| first_name==bob
| Matches records where &apos;&apos;first_name&apos;&apos; is exactly &quot;bob&quot;.  This includes &apos;&apos;Bob&apos;&apos; only.
|-
| first_name=~J%
| Matches records that begin with &quot;J&quot;.  This includes &apos;&apos;Jake&apos;&apos; and &apos;&apos;Julie&apos;&apos;
|}

====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 &apos;&apos;authors&apos;&apos; table.  With Xataface we can perform this query directly from the &apos;&apos;authors&apos;&apos; table using something like the following query:
 index.php?-table=authors&amp;articles/title=sports
This assumes that the &apos;&apos;authors&apos;&apos; table has a relationship named &apos;&apos;articles&apos;&apos; 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 &apos;&apos;title&apos;&apos; field contains the phrase &quot;sports&quot;.


=====Anatomy of a Related Query=====

 %relationship%/%field%=%query%
This matches all records in the current table such that at least one record in its &apos;&apos;&lt;relationship&gt;&apos;&apos; relationship matches the query: &apos;&apos;%field%=%query%&apos;&apos;.


====Using the &apos;&apos;OR&apos;&apos; Operator====

Xataface allows you to search for more than one value at a time using the &apos;&apos;OR&apos;&apos; operator.  E.g.
 first_name=bob+OR+steve
Would match all records with &apos;&apos;first_name&apos;&apos; containing &quot;bob&quot; or &quot;steve&quot;.
 first_name=bob+OR+=steve
Would match all records with &apos;&apos;first_name&apos;&apos; containing &quot;bob&quot; or exactly matching &quot;steve&quot;
 age=&lt;10+OR+&gt;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 &apos;&apos;both&apos;&apos; queries.  E.g.
 age=&gt;10&amp;first_name=bob
would match all records where &apos;&apos;age&apos;&apos; is greater than 10 &apos;&apos;&apos;AND&apos;&apos;&apos; that have &apos;&apos;first_name&apos;&apos; containing &quot;bob&quot;.

=====Examples of Combined Queries=====

Given the same data set as the previous set of examples:

{| class=&quot;listing listing2&quot;
|-
! first_name
! age
|-
| Bob
| 10
|-
| Cindy
| 12
|-
| Julie
| 6
|-
| Jake
| 8
|-
| Kabob
| 16
|}

 first_name=bob&amp;age=11
would return no matches because there are no records that contain both &apos;&apos;first_name&apos;&apos; &quot;bob&quot; and &apos;&apos;age&apos;&apos; 11.  However
 first_name=bob&amp;age=10
would return only &apos;&apos;Bob&apos;&apos; and
 first_name=bob&amp;age=16
would return only &apos;&apos;Kabob&apos;&apos;.

====Special Common Queries====

=====Search For Null or Blank Value=====

Searching for a null value or a blank value is an exact match for &quot;&quot;.  Therefore you can simply search for &quot;=&quot;.  E.g. To find records with a null or blank first_name you would use the query &apos;&apos;first_name==&apos;&apos;.  Or the full query:
 index.php?-table=people&amp;first_name==

=====Search for Non-blank Value=====

Searching for a non-blank value is the same as searching for a value greater than &quot;&quot;.  Therefore you can simply search for &quot;&gt;&quot;.  E.g. if you wanted to find records with a first_name, you would use the query &apos;&apos;first_name=&gt;&apos;&apos;.  Or the full query:
 index.php?-table=people&amp;first_name=&gt;

==Preserved vs Non-preserved Parameters==

As mentioned above any parameters that are prefixed by a hyphen (i.e. &quot;=&quot;) 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 &quot;-&quot; 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&amp;-action=list&amp;first_name=bob
It will show you the &apos;&apos;list&apos;&apos; tab of the &apos;&apos;people&apos;&apos; table with only those records with &apos;&apos;first_name&apos;&apos; &quot;bob&quot;.  Now if you click on the &apos;&apos;details&apos;&apos; tab it will preserve your query &apos;&apos;first_name&apos;&apos;.  The query will become something like:
 index.php?-table=people&amp;-action=details&amp;first_name=bob&amp;...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 &apos;&apos;list&apos;&apos; 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 &apos;&apos;-limit&apos;&apos; directive to show 100 records per page:
 index.php?-table=people&amp;-action=list&amp;-limit=100
And then you click on the &apos;&apos;details&apos;&apos; tab, it will retain your &apos;&apos;-limit&apos;&apos; parameter.  Of course the &apos;&apos;-limit&apos;&apos; parameter is not actually used by the &apos;&apos;details&apos;&apos; action because it works on only one record at a time (it uses the &apos;&apos;-cursor&apos;&apos; parameter instead), when you click back on the &apos;&apos;list&apos;&apos; tab it will still show you 100 records per page.

Because of this, we call the &apos;&apos;-limit&apos;&apos; parameter a preserved parameter.  It is retained when navigating within the same table.  &apos;&apos;&apos;Note:&apos;&apos;&apos; 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 &apos;&apos;don&apos;t&apos;&apos; want Xataface to preserve one of your parameters, you should prefix two hyphens to the parameter name.  I.e. &quot;--&quot;.  One example of an unpreserved parameters throughout Xataface applications is the &apos;&apos;--msg&apos;&apos; parameter.  The value of this parameter will be displayed on the page as an info message to the user.  Clearly you don&apos;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 &quot;Record Successfully Saved&quot; at the top of the page.  If you click on any link in the application, it will not retain the &apos;&apos;--msg&apos;&apos; 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=&quot;listing listing2&quot;
|-
! 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 &apos;&apos;NOT&apos;&apos; retrained with the user navigates away from the page.
|}





</content>
	<keywords>URL Conventions, GET Parameters, POST parameters, Request Parameters</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=38">
	<page_name>How_to_build_a_PHP_MySQL_Application_with_4_lines_of_code</page_name>
	<page_id>38</page_id>
	<page_title>How to build a PHP MySQL Application with 4 lines of code</page_title>
	<content>&apos;&apos;&apos;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&apos;s Not a code generator.&apos;&apos;&apos;

[[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&apos;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 &apos;&apos;myapp&apos;&apos;.
# Download the latest version of [http://xataface.com Xataface] and copy it into your application directory that we just created.  (i.e. &apos;&apos;myapp/xataface&apos;&apos;.
# Create a configuration file named &apos;&apos;conf.ini&apos;&apos; inside your application directory (i.e. &apos;&apos;myapp/conf.ini&apos;&apos;) to store your database connection info:&lt;code&gt;
[_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
&lt;/code&gt;
# Create an .htaccess (i.e. &apos;&apos;myapp/.htaccess&apos;&apos;) file to prevent Apache from serving your &apos;&apos;conf.ini&apos;&apos; file:&lt;code&gt;
&lt;FilesMatch &quot;\.ini$&quot;&gt;
Deny from all
&lt;/FilesMatch&gt;
&lt;/code&gt;  &apos;&apos;&apos;Note:  If you are not using Apache as your web server you&apos;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&apos;s directory.&apos;&apos;&apos;  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. &apos;&apos;myapp/index.php&apos;&apos;) to serve as an access point for your application:&lt;code&gt;
&lt;?php
// Include the Xataface API
require_once &apos;xataface/dataface-public-api.php&apos;;

// Initialize Xataface framework
df_init(__FILE__, &apos;xataface&apos;)-&gt;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)
&lt;/code&gt;
# Create a &apos;&apos;templates_c&apos;&apos; directory to store cached smarty templates or your application (i.e. &apos;&apos;myapp/templates_c&apos;&apos;, and make sure that it is writable by the webserver:
 $ mkdir templates_c
 $ chmod 777 templates_c


That&apos;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.



</content>
	<keywords>tutorial, getting started, installation, first app, 4 lines of code</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=81">
	<page_name>GettingStarted:triggers</page_name>
	<page_id>81</page_id>
	<page_title>Triggers</page_title>
	<content>==Triggers==

Triggers are methods that can be defined to carry out custom behaviors when certain events occur in the application (e.g., when records are saved, inserted, or deleted).

Triggers are generally regarded as one of the more advanced features of database applications. Despite the &quot;advanced&quot; status of triggers, however, they are very simple to use and can be leveraged by Xataface developers to add powerful functionality to their applications.

So what can you do with a trigger?

* Send a confirmation email every time a new record is inserted into a table.
* Delete records related to a record that is being deleted (to maintain the consistency of the database).
* Add custom logging functionality.
* Add extra permissions or validation rules (although these are probably better handled with the validation framework).

You can really do just about anything you want with a trigger. A trigger is essentially just a custom PHP method that is called by Xataface when certain events occur.

===What triggers are available?===

As of version 0.5.3 Xataface supports the following triggers:

* &apos;&apos;&apos;beforeSave&apos;&apos;&apos; : called just before a record is saved (either inserted or updated).
* &apos;&apos;&apos;afterSave&apos;&apos;&apos; : called just after a record is saved (either inserted or updated).
* &apos;&apos;&apos;beforeInsert&apos;&apos;&apos; : called just before a record is inserted.
* &apos;&apos;&apos;afterInsert&apos;&apos;&apos; : called just after a record is inserted.
* &apos;&apos;&apos;beforeUpdate&apos;&apos;&apos; : called just before a record is updated.
* &apos;&apos;&apos;afterUpdate&apos;&apos;&apos; : called just after a record is updated.
* &apos;&apos;&apos;beforeDelete&apos;&apos;&apos; : called just before a record is deleted.
* &apos;&apos;&apos;afterDelete&apos;&apos;&apos; : called just after a record is deleted.
* &apos;&apos;&apos;beforeAddRelatedRecord&apos;&apos;&apos; : called just before a related record (new or existing) is added to a relationship.
* &apos;&apos;&apos;afterAddRelatedRecord&apos;&apos;&apos; : called just after a related record (new or existing) is added to a relationship.
* &apos;&apos;&apos;beforeAddNewRelatedRecord&apos;&apos;&apos; : called just before a new related record is added.
* &apos;&apos;&apos;afterAddNewRelatedRecord&apos;&apos;&apos; : called just after a new related record is added.
* &apos;&apos;&apos;beforeAddExistingRelatedRecord&apos;&apos;&apos; : called just before an existing related record is added.
* &apos;&apos;&apos;afterAddExistingRelatedRecord&apos;&apos;&apos; : called just after an existing related record is added.

===How do you define a trigger?===

Triggers are always defined as methods of the delegate class for a table. As an example, suppose we wanted to add a trigger to send a the administrator a notification email every time a new record is inserted into the &apos;Course&apos; table. The steps would be as follows:

# Create a delegate class for the &apos;Course&apos; table (if one does not already exist) by creating a file named &apos;Course.php&apos; inside the &apos;tables/Course&apos; directory.
# Add the following to the Delegate class file to make it a valid delegate class:&lt;code&gt;&lt;?
class tables_Course {}
&lt;/code&gt;
# Okay, we want our trigger to be called every time a record is inserted. There are 2 possible triggers that can be defined, then:&lt;nowiki&gt;
&lt;ul&gt;
&lt;li&gt;beforeInsert&lt;/li&gt;
&lt;li&gt;afterInsert&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this case it is probably more appropriate to define the afterInsert trigger because we really only want to send the notification email after the insert has successfully taken place. Therefore, we will define the afterInsert() method in our delegate class as follows:&lt;/p&gt;
&lt;/nowiki&gt;&lt;code&gt;
&lt;?
class tables_Course {
	....
    /**
     * Trigger that is called after Course record is inserted.
     * @param $record Dataface_Record object that has just been inserted.
     */
    function afterInsert(&amp;$record){
        mail(&apos;admin_email@yourdomain.com&apos;,&apos;Subject Line&apos;, &apos;Message body&apos;); 
    }
}
&lt;/code&gt;
# That&apos;s all for now. The afterInsert() method defined above will automatically be called every time a record is inserted into the Course table. This method, as we have defined it, will send a notification email to the administrator email.

===Sending feedback to the user===

The above example sends the email without any feedback to the application&apos;s user of whether the email succeeded or not. When the user inserts a new Course he will only see that the record was succesfully saved, but no mention is made of the email. The following example does the same thing as the previous one, except that it sends a confirmation to the user when the email has been successfully sent:
&lt;code&gt;
function afterInsert(&amp;$record){
    $response =&amp; Dataface_Application::getResponse();
        // get reference to response array

    if ( mail(&apos;shannah@sfu.ca&apos;, &apos;Subject Line&apos;, &apos;Message Body&apos;) ){
        $response[&apos;--msg&apos;] .= &quot;\nEmail sent to shannah@sfu.ca successfully.&quot;;
    } else {
        $response[&apos;--msg&apos;] .= &quot;\nMail could not be sent at this time.&quot;;
    }
}
&lt;/code&gt;

Now, when the user inserts a new record he will see a confirmation as follows:

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/trigger-after-insert-confirm.gif]]

Notice that we used the Dataface_Application::getResponse() function to obtain a reference to the application&apos;s response array. The response array is just a global array that is shared by the entire application that allows you to pass information easily from one part of the application to another. The &apos;--msg&apos; index of array is where you can place text that you wish to have displayed to the user as a confirmation.

&apos;&apos;&apos;Note&apos;&apos;&apos;: It is important to use &apos;=&amp;&apos; to assign the result of Dataface::getResponse() and not just &apos;=&apos;. e.g.:
&lt;code&gt;
$response =&amp; Dataface_Application::getResponse(); // correct!
$response = Dataface_Application::getResponse(); // WRONG!!
&lt;/code&gt;

This is because we need a reference to the response array, not a copy. That way when we assign a value to the &apos;--msg&apos; index it is applied to the actual response array and not a copy of it.

===Handling Errors===

The above method of sending messages to the user is useful for notifications and confirmations. However, in some cases you want to inform the user that an error occurred and cancel further operations. For example you may want to disallow a record to be inserted if a confirmation email cannot be sent. In this case we define the beforeInsert() trigger and return a PEAR_Error object if the email fails as follows:
&lt;code&gt;
&lt;?
class tables_Course {
    function beforeInsert(&amp;$record){
        $response =&amp; Dataface_Application::getResponse();
        if ( mail(&apos;shannah@sfu.ca&apos;, &apos;Notification&apos;, &apos;Your record was created&apos;)){
            $response[&apos;--msg&apos;] .= &quot;\nEmail sent successfully to shannah@sfu.ca&quot;;
        } else {
            return PEAR::raiseError(
                &quot;Errors occurred while sending email.  Record could not be inserted&quot;,
                 DATAFACE_E_NOTICE
            );
        }
    }
     
}
&lt;/code&gt;

This trigger is called just before a course record is inserted into the database. If the mail succeeds, then the user sees a success message. If it fails, on the other hand, the insert is cancelled, and the user will see a message as follows:

[[Image:http://framework.weblite.ca/documentation/tutorial/getting_started/trigger-error.gif]]


&apos;&apos;&apos;Note&apos;&apos;&apos;: Notice the use of the DATAFACE_E_NOTICE constant as a second parameter for PEAR::raiseError(). This is important as without it Xataface will display a less user-friendly error message complete with stack trace. If the error is such that you want a complete stack trace, you can use the DATAFACE_E_ERROR constant instead.</content>
	<keywords>triggers, beforeSave, afterSave, beforeInsert, afterInsert,sending email</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=109">
	<page_name>beforeSave</page_name>
	<page_id>109</page_id>
	<page_title>beforeSave Trigger</page_title>
	<content>Back to [[Delegate class methods]]

[[toc]]



===Synopsis===

The beforeSave trigger can be implemented in any table&apos;s [[delegate class|Delegate Class Methods]] to perform functionality that should be run *before* a record of that table is saved.  This is a useful place to insert additional field values depending on the input of the save record form.

This method is called both when records are inserted and when existing records are updated.  Some other triggers include [[beforeInsert]], [[beforeUpdate]], [[afterSave]], [[afterInsert]], and [[afterUpdate]], which do what you might expect.


===Method Signature===

&lt;code&gt;function beforeSave( Dataface_Record $record);&lt;/code&gt;

====Parameters====

# &apos;&apos;&apos;$record&apos;&apos;&apos; - The record that is about to be saved.  This is a [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object.

====Returns====

# [http://dataface.weblite.ca/Dataface_Error Dataface_Error] on failure (if you want to cancel the save).


===Examples===

Given a table named &quot;people&quot;, suppose we wanted to automatically populate a field named &quot;full_name&quot;  with the concatenation of the &quot;first_name&quot; and &quot;last_name&quot; fields.  (Note you could also achieve a similar thing by making a calculated field for &quot;full_name&quot;, but for this example, we assume that we actually want to store this in the database.

We create a beforeSave() trigger that automatically updates the &quot;full_name&quot; field every time the record is saved.

In the &quot;people&quot; table delegate class (i.e. tables/people/people.php)
&lt;code&gt;
class tables_people {
    function beforeSave($record){
        $record-&gt;setValue(&apos;full_name&apos;, 
            $record-&gt;val(&apos;first_name&apos;).&apos; &apos;.$record-&gt;val(&apos;last_name&apos;)
        );
    }
}
&lt;/code&gt;

==See Also==

* [http://www.xataface.com/documentation/tutorial/getting_started/triggers Triggers section of the Xataface Getting Started Tutorial]
</content>
	<keywords>triggers, beforeSave,</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=110">
	<page_name>Contribute_to_Xataface_Translation_Project</page_name>
	<page_id>110</page_id>
	<page_title>How to Contribute Translations</page_title>
	<content>[[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. &apos;&apos;&apos;NOTE: THIS IS NOT THE PREFERRED WAY TO CONTRIBUTE TRANSLATIONS.  PLEASE SEE &quot;Adding Translations Using Google Spreadsheets&quot; BELOW&apos;&apos;&apos;.

==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===

&lt;code&gt;
scripts.GLOBAL.FORMS.OPTION_PLEASE_SELECT = &quot;Please Select ...&quot;
save_button_label = &quot;Save&quot;
scripts.GLOBAL.MESSAGE.PERMISSION_DENIED = &quot;Permission Denied&quot;
scripts.GLOBAL.NO_RECORDS_MATCHED_REQUEST = &quot;No records matched your request.&quot;
&lt;/code&gt;

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:

&lt;code&gt;
scripts.GLOBAL.FORMS.OPTION_PLEASE_SELECT = &quot;SVP sélectionnez ...&quot;
save_button_label = &quot;Enregistrer&quot;
scripts.GLOBAL.MESSAGE.PERMISSION_DENIED = &quot;Permission Refusée&quot;
scripts.GLOBAL.NO_RECORDS_MATCHED_REQUEST = &quot;Aucun résultat ne correspond à votre requête.&quot;
&lt;/code&gt;

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.

&apos;&apos;&apos;NOTE: IT IS BETTER TO USE GOOGLE SPREADSHEETS TO EDIT TRANSLATIONS, THAN TO WORK WITH INI FILES DIRECTLY. PLEASE SEE &quot;Adding Translations Using Google Spreadsheets&quot; BELOW&apos;&apos;&apos;


==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&apos;t have to worry about this).

===Wrap Translations in Double Quotes===

All translations should be wrapped in double quotes.  E.g.
&lt;code&gt;
mykey=&quot;My Value&quot;
&lt;/code&gt;

If you forget to close a quote, it will likely cause a parse error and Xataface will fail to load the file.  E.g.
&lt;code&gt;
mykey=&quot;My Value
&lt;/code&gt;
would be a problem.


===Can&apos;t Use Double Quotes as Part of the Translation===

Since INI files use double quotes to wrap strings, you can&apos;t use a double quote inside your translation.  E.g. you can&apos;t do this:
&lt;code&gt;
mylink=&quot;&lt;a href=&quot;http://google.com&quot;&gt;Google&lt;/a&gt;&quot;
&lt;/code&gt;
because of the inline double quotes.

One way around this is to try to use single quotes where possible.  E.g.
&lt;code&gt;
mylink=&quot;&lt;a href=&apos;http://google.com&apos;&gt;Google&lt;/a&gt;&quot;
&lt;/code&gt;

Another way around this is to the &apos;&apos;&quot;_Q&quot;&apos;&apos; key sequence, which Xataface will
automatically convert to a double quote for you at runtime.  E.g. You could do:
&lt;code&gt;
mylink=&quot;&lt;a href=&quot;_Q&quot;http://google.com&quot;_Q&quot;&gt;Google&lt;/a&gt;&quot;
&lt;/code&gt;

&apos;&apos;&apos;NOTE: If you use Google Spreadsheets to edit your translations, you won&apos;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.&apos;&apos;&apos;


===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:
&lt;code&gt;
No action found = &quot;No action found named &apos;$name&apos;&quot;
&lt;/code&gt;
has the variable &apos;&apos;$name&apos;&apos;.

So the French translation should maintain this variable.  E.g. in the fr.ini file:
&lt;code&gt;
No action found = &quot;Aucune action nommée &apos;$name&apos;&quot;
&lt;/code&gt;


==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&amp;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&apos;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&apos;t have to worry about encoding issues, and you don&apos;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:
&lt;code&gt;
&apos;Help!&apos;, I exclaimed
&lt;/code&gt;
If you unfocus from that cell it will only say:
&lt;code&gt;
Help!&apos;, I exclaimed
&lt;/code&gt;
If you go back into edit mode of the cell again, you&apos;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.:
&lt;code&gt;
&apos;&apos;Help!&apos;, I exclaimed
&lt;/code&gt;

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&apos;ve contributed a number of translations to the [https://spreadsheets.google.com/ccc?key=0AqJNZUI7flxSdFVLWDlnVVpQZ3dMaGZhVjVHN2c3bEE&amp;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 &apos;&apos;File&apos;&apos; &gt; &apos;&apos;Download as&apos;&apos; &gt; &apos;&apos;CSV (Current Sheet)&apos;&apos; 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:
&lt;code&gt;
$ php /path/to/xataface/tools/csv2ini.php /path/to/xataface-translations.csv /path/to/destination/dir/
&lt;/code&gt;

This will convert the xataface-translations.csv file into a set of language INI files and place them the specified destination directory  (don&apos;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.

&apos;&apos;&apos;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.&apos;&apos;&apos;




</content>
	<keywords>Translations, Google Spreadsheets, en.ini, fr.ini</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=44">
	<page_name>timestamp</page_name>
	<page_id>44</page_id>
	<page_title>timestamp</page_title>
	<content>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:

&lt;code&gt;
[date_created]
timestamp=insert
widget:type=hidden
&lt;/code&gt;

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===

* &apos;&apos;&apos;update&apos;&apos;&apos; - Causes timestamp to be updated whenever the record is modified.
* &apos;&apos;&apos;insert&apos;&apos;&apos; - Causes the timestamp to be updated only when the record is first inserted.</content>
	<keywords>timestamp, date, datetime</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=23">
	<page_name>xataface_templates</page_name>
	<page_id>23</page_id>
	<page_title>xataface_templates</page_title>
	<content>==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&apos;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 &amp; 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&apos;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 &amp; 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=&quot;listing listing2&quot;
|-
! 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&apos;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&apos;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&apos;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=&quot;listing listing2&quot;
|-
! 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&apos;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&apos;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()-&gt;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&apos;s preferred language.
| 0.6
|-
| $ENV.prefs
| A reference to the preferences array ($conf[&apos;_prefs&apos;])
| 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 &quot;plugins&quot; 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  &apos;&apos;lib/Smarty/plugins&apos;&apos; 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&apos;s directory which override corresponding functionality in Xataface.

As of Xataface 2.0, you can create a directory named &apos;&apos;plugins&apos;&apos; 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&amp;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 &quot;eightball&quot; 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 &apos;&apos;plugins&apos;&apos; directory to your application directory.  i.e.  &apos;&apos;path/to/app/plugins&apos;&apos;
# Add a file inside this &apos;&apos;plugins&apos;&apos; directory called &apos;&apos;&lt;nowiki&gt;function.eightball.php&lt;/nowiki&gt;&apos;&apos; with the following content:&lt;code&gt;
&lt;?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(&apos;Yes&apos;,
                     &apos;No&apos;,
                     &apos;No way&apos;,
                     &apos;Outlook not so good&apos;,
                     &apos;Ask again soon&apos;,
                     &apos;Maybe in your reality&apos;);

    $result = array_rand($answers);
    return $answers[$result];
}
&lt;/code&gt;
# If you compare this function to the original example in [http://www.smarty.net/docs/en/plugins.functions.tpl the smarty tutorial] you&apos;ll notice that the 2nd parameter has been changed to type &apos;&apos;Dataface_SkinTool&apos;&apos; from &apos;&apos;Smarty_Internal_Template&apos;&apos;. If you don&apos;t make this change, you will get a fatal error when you try to use the tag.  This function defines an &apos;&apos;{eightball}&apos;&apos; tag that can be added to any Smarty template in Xataface.
# Next we&apos;ll create a template that uses this tag.  If your application doesn&apos;t have a &apos;&apos;templates&apos;&apos; directory, create one now (i.e. path/to/app/templates).
# Add a file inside your templates directory called &apos;&apos;testing.html&apos;&apos; with the following content:&lt;code&gt;
The eight ball says {eightball}
&lt;/code&gt;
# Now we need to display this template somewhere in our interface.  In this case, we&apos;ll choose the &apos;&apos;before_record_content&apos;&apos; block.  (This will render the template before the main section of the view tab).  Add the following method to your [[Application_Delegate_Class]]:&lt;code&gt;
function block__before_record_content(){
    df_display(array(), &apos;testing.html&apos;);
}
&lt;/code&gt;
# 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:
&lt;nowiki&gt;&lt;img src=&quot;http://media.weblite.ca/files/photos/Screen_Shot_2012-04-16_at_12.33.01_PM.png?max_width=640&quot;/&gt;&lt;/nowiki&gt;

===See also:===

* [http://www.xataface.com/documentation/tutorial/getting_started/changing-look-and-feel Changing the Look &amp; Feel of Xataface] (From the Getting Started Tutorial)
* [http://www.xataface.com/documentation/tutorial/customizing-the-dataface-look-and-feel Cusomizing the Xataface Look &amp; Feel] Tutorial</content>
	<keywords>templates, plugins, smarty</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=88">
	<page_name>secure</page_name>
	<page_id>88</page_id>
	<page_title>secure fields.ini directive</page_title>
	<content>[[fields.ini file]] directive used only with [[container fields]].  If this flag is set, then the field contents will be treated in a secure manner and will obey the application permissions.  If this directive is not set, then uploaded files in [[container fields]] are served directly by the web server without considering application permissions.  Setting this directive will cause the application use a special get_blob action to serve the uploaded file, and this obeys application permissions.

==Example==

Given a field to upload a PDF report, your [[fields.ini file]] section for this field might be something like:

&lt;code&gt;
[pdf_report]
    Type=container
    allowed_extensions=&quot;pdf&quot;
    savepath=&quot;uploads&quot;
    url=&quot;uploads&quot;
&lt;/code&gt;


Now if we upload a file named &quot;foo.pdf&quot; in this field, it will be uploaded to:
 http://www.example.com/path/to/myapp/uploads/foo.pdf

Now we change the field definition to use the secure directive:

&lt;code&gt;
[pdf_report]
    Type=container
    allowed_extensions=&quot;pdf&quot;
    savepath=&quot;uploads&quot;
    url=&quot;uploads&quot;
    secure=1
&lt;/code&gt;

In this case it will still upload files to the &apos;&apos;uploads&apos;&apos; directory, but all of the links generated in the Xataface interface (and via the &apos;&apos;display()&apos;&apos; and &apos;&apos;htmlValue()&apos;&apos; methods) will be for a URL like:
  http://www.example.com/path/to/myapp/index.php?-action=getBlob&amp;-table=mytable&amp;-field=pdf_report&amp;record_id=10

Which will serve up the PDF file as an attachment.

===Restricting Direct Access to uploads directory===

Note: You still need to restrict access to the uploads directory or it may be possible for users to still guess the absolute URL to files in it.  You can restrict access by placing an .htaccess file in the uploads directory (if you are using Apache) with the following contents:
&lt;code&gt;
deny from all
&lt;/code&gt;

If you are using IIS or another web server you should look into the methods available for you to restrict access to directories.

===HTTP Response Codes===

The [[getBlob action]] will return the following HTTP Response Codes:

* &apos;&apos;&apos;404&apos;&apos;&apos; - If either the record does not exist, or the record&apos;s specified container field is empty.
* &apos;&apos;&apos;403&apos;&apos;&apos; - If the current user doesn&apos;t have permission to access this record.
* &apos;&apos;&apos;500&apos;&apos;&apos; - If there is another error.  The actual error will be written to the error log.</content>
	<keywords>secure,fields.ini file</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=7">
	<page_name>Delegate_class_methods</page_name>
	<page_id>7</page_id>
	<page_title>Delegate_class_methods</page_title>
	<content>==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&apos;s [[table configuration directory|configuration directory]].  E.g. given a table named &quot;people&quot;, you would place the delegate class in the file &quot;tables/people/people.php&quot;

===Basic Delegate Class===

&lt;code&gt;
&lt;?php
class tables_people {}
?&gt;
&lt;/code&gt;

===Available Methods===

====Table Settings====

{| class=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! 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 &quot;fieldname&quot; on a given record.
| 0.7
|-
| fieldname__roles
| Returns the roles that are allowed for the field &quot;fieldname&quot; on a given record.
| 1.0
|-
| rel_relationshipname__permissions
| Returns the permissions pertaining to the relationship &apos;&apos;relationshipname&apos;&apos; on a given record.
| 1.0
|-
| rel_relationshipname__roles
| Returns the role or roles pertaining to the relationship &apos;&apos;relationshipname&apos;&apos; on a given record.
| 1.0
|}

====Triggers====

{| class=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| fieldname__htmlValue
| Returns the value of the field &quot;fieldname&quot; for a given record as HTML.
| 0.5
|-
| fieldname__display
| Returns the value of the field &quot;fieldname&quot; appropriate for displaying.
| 0.5
|-
| [[fieldname__default]]
| Returns the default value for the field &apos;&apos;fieldname&apos;&apos;.  New record forms will be prepopulated with this value.
| 0.7
|-
| [[fieldname__validate]]
| Validates the input for the field &apos;&apos;fieldname&apos;&apos;.
| 0.6
|-
| fieldname__parse
| Parses the input value for the field &apos;&apos;fieldname&apos;&apos;.  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 &apos;&apos;fieldname&apos;&apos; 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 &apos;&apos;fieldname&apos;&apos; 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 &apos;&apos;fieldname&apos;&apos; on the edit form.
| 0.6
|-
| [[field__pushValue]]
| Converts form input for field &apos;&apos;fieldname&apos;&apos; to be ready to store in a Dataface_Record.
| 0.6
|-
| [[field__pullValue]]
| Converts a value for field &apos;&apos;fieldname&apos;&apos; 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 &quot;fieldname&quot; 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=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| [[block__blockname]]
| Outputs content that is meant to override a slot or a block named &quot;blockname&quot;.
| 0.6
|}

====List Tab Customization====

{| class=&quot;listing listing2&quot;
! 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 &quot;fieldname&quot; 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=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! 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=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| [[valuelist__valuelistname]]
| Defines a valuelist named &apos;&apos;valuelistname&apos;&apos;.
| 0.7
|}


====Importing Records====
{| class=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| [[__import__filtername]]
| Defines an import filter to named &apos;&apos;filtername&apos;&apos; which is used to import records into the table.
| 0.7
|}
</content>
	<keywords>RSS,Feeds,delegate classes, triggers</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=40">
	<page_name>Introduction_to_RSS_Feeds_in_Xataface</page_name>
	<page_id>40</page_id>
	<page_title>Introduction_to_RSS_Feeds_in_Xataface</page_title>
	<content>==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&apos;s RSS article]:

&quot;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 &quot;feed&quot;, &quot;web feed&quot;,[3] or &quot;channel&quot;) 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 &quot;RSS reader&quot;, &quot;feed reader&quot;, or &quot;aggregator&quot;, 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&apos;s URI (often referred to informally as a &quot;URL&quot;, 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&apos;s subscribed feeds regularly for new work, downloads any updates that it finds, and provides a user interface to monitor and read the feeds.&quot;

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&apos;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 &apos;&apos;news&apos;&apos; table, so he navigates to the &apos;&apos;list&apos;&apos; tab of the &apos;&apos;news&apos;&apos; 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 &apos;&apos;news&apos;&apos; table.  When new records are inserted, he&apos;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 &apos;&apos;news&apos;&apos; table that contains the phrase &quot;Buffalo Bills&quot;, because he is a Buffalo Bills fan.  So he navigates to the &apos;&apos;news&apos;&apos; table, and does a search for the phrase &quot;Buffalo Bills&quot;.  Then he clicks on the &quot;RSS Feed&quot; 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 &apos;&apos;news&apos;&apos; items containing the phrase &quot;Buffalo Bills&quot;.  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 &apos;&apos;authors&apos;&apos; table and the &apos;&apos;books&apos;&apos; table named &apos;&apos;publications&apos;&apos;.  You can subscribe to the RSS feed for his publications by navigating to the &apos;&apos;publications&apos;&apos; tab for that author, then clicking on the &quot;RSS Feed&quot; icon in the upper right.  Now whenever this author adds a new book to his publications list, you&apos;ll be notified via RSS.



===Example usage in Xataface===

# A user wants to be alerted whenever a new item is inserted into the &apos;&apos;news&apos;&apos; table, so he navigates to the &apos;&apos;list&apos;&apos; tab of the &apos;&apos;news&apos;&apos; 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 &apos;&apos;news&apos;&apos; table.  When new records are inserted, he&apos;ll receive alerts in his RSS reader.
# A user wants to be alerted whenever a new record about &quot;Wayne Gretzky&quot; is inserted in to the &apos;&apos;news&apos;&apos; table.  He navigates to the &apos;&apos;news&apos;&apos; table, then performs a search for &quot;Wayne Gretzky&quot; using the top right search box.  Then, he clicks on the &quot;RSS Feed&quot; icon in the upper right of the result list.  Now, whenever a new item is inserted with the phrase &quot;Wayne Gretzky&quot;, 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=&quot;listing listing2&quot;
! 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 &apos;&apos;[_feed]&apos;&apos; section of your [[conf.ini file]].  This is sort of a &quot;one size fits all&quot; approach where all feeds generated from your application will share the same title.

E.g.

&lt;code&gt;
[_feed]
    title=&quot;My Site News&quot;
    description=&quot;News updates from my site&quot;
    link=&quot;http://www.example.com&quot;
&lt;/code&gt;

However, if we want our feed&apos;s information to depend on the user&apos;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.

&lt;code&gt;
function getFeed($query=array()){
    $params = array();
    if ( @$query[&apos;-search&apos;] ) $params[&apos;title&apos;] = &apos;&quot;&apos;.$query[&apos;-search&apos;].&apos;&quot; results&apos;;
    else $params[&apos;title&apos;] = &apos;All records from my table&apos;;
    return $params;
}
&lt;/code&gt;

Notice that I don&apos;t need to define all possible parameters.  Any parameters that I don&apos;t define will be provided automatically by Xataface, or it will simply use the values specified in your &apos;&apos;[_feed]&apos;&apos; 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&apos;t specify it explicitly, but you&apos;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.

&lt;code&gt;
function getFeedItem(&amp;$record)){
    return array(
        &apos;description&apos; =&gt; $record-&gt;val(&apos;body&apos;)
    );
}
&lt;/code&gt;

Once again, notice that we don&apos;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.


</content>
	<keywords>RSS Feeds</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=20">
	<page_name>relationships.ini_file</page_name>
	<page_id>20</page_id>
	<page_title>relationships.ini_file</page_title>
	<content>==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&apos;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&apos;s section of the relationship.ini file to customize the field&apos;s behavior.  Some directives are not applicable to all fields.

{| class=&quot;listing listing2&quot;
|-
! 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&apos;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 &quot;related_records_checkboxes&quot; 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: &quot;treetable&quot;
| 0.8
|-
| [[meta:class]]
| An optional special class to assign to the relationship.  E.g. &quot;parent&quot; or &quot;children&quot;.
| 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&amp;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]</content>
	<keywords>relationships.ini file, relationships</keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=111">
	<page_name>Relationship_Permissions</page_name>
	<page_id>111</page_id>
	<page_title>Relationship Permissions</page_title>
	<content>[[toc]]

==Synopsis==

As relationships are a core feature of Xataface, it is helpful to understand how to handle permissions on related records.  Even if you apply permissions to every table individually, you need to take into account the relationships that you have defined between tables, because they may open access to actions that you did not intend.

For example, suppose we have two tables: &apos;&apos;people&apos;&apos; and &apos;&apos;publications&apos;&apos;, and we have a relationship from &apos;&apos;publications&apos;&apos; table to the &apos;&apos;people&apos;&apos; table called &apos;&apos;publication_authors&apos;&apos;.

Suppose you give a user write access to a record of the publications table, but no access to the people table.  If you are allowing the &apos;&apos;add new related record&apos;&apos; permission on the &apos;&apos;publications&apos;&apos; table record, then the user will still be able to add new people, via the &quot;Add related people record&quot; function of the database.  This may or may not be desirable.

This article discusses the issues that arise due to relationships and permissions, and how to deal with them.

==Relationship Permissions==

The Xataface [[permissions.ini file]] defines a handful of permissions that are related to the management of related records.  These include:

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Included in Roles
|-
| [[add new related record]]
| Permission to add a new related record to a relationship.
| EDIT, DELETE, OWNER, ADMIN, MANAGER
|-
| [[add existing related record]]
| Permission to add an existing record to a relationship.
| EDIT, DELETE, OWNER, ADMIN, MANAGER
|-
| [[remove related record]]
| Permission to remove a record from a relationship.  (This only allows removing a record from the relationship - not deleting the record from the database, so this is only really relevant in a many-to-many relationship).
| EDIT, DELETE, OWNER, ADMIN, MANAGER
|-
| [[delete related record]]
| Permission to delete a related record.  This allows both removing the related record from the relationship, and deleting the record from the database.   This permission is not included in any default roles.  A combination of permission for [[remove related record]] in the source table and [[delete]] in the target table, are equivalent to access to this permission.  Use this permission only when you need to override the ability to delete records from the database based on membership in a relationship.
| -
|-
| [[view related records]]
| Permission to view the records of a relationship.
| READ ONLY, EDIT, DELETE, OWNER, ADMIN, MANAGER
|-
| [[related records feed]]
| Permission to access the RSS feed of a relationship.
| READ ONLY, EDIT, DELETE, OWNER, ADMIN, MANAGER
|}


==Fine-grained, Per-relationship Permissions==

You may often find that defining a flat set of permissions to all relationships on a record is insufficient for your purposes, because some relationships may demand different access levels than others.  You can override the permissions for any particular relationship by implementing the [[rel_relationshipname__permissions]] method in the table&apos;s delegate class, where &apos;&apos;relationshipname&apos;&apos; is the name of the relationship.

e.g.  Consider the relationship &apos;&apos;manufacturers&apos;&apos;:
&lt;code&gt;
function rel_manufacturers__permissions($record){
	// $record is a Dataface_Record object
	return array(
		&apos;view related records&apos; =&gt; 0
	);
}
&lt;/code&gt;
This will tell xataface that users should not be able to view related records on the &apos;&apos;manufacturers&apos;&apos; relationship.  This will override any permissions that were defined in the [[getPermissions]] method.


==More Complete Example==

In the following example, we design a products database.  We use 2 relationships on our products table:  One to keep track of the parts that are used in our product.  The other to keep track of the users that are allowed to edit our products.

We want to make it so that only the product owner can manage the editors for a product, but anyone in the product_editors relationship is allowed to edit the product or add/remove parts from the product.

We don&apos;t want to give any users access directly to the parts, product_parts, or product_editors tables.  We want all access to go through the relationships on the products table.

===Database/Relationship Design===

Consider a database with 4 tables:

# products (product_id, product_name, owner_username)
# parts (part_id, part_name)
# product_parts (part_id, product_id)
# product_editors (product_id, editor_username)
# users (username, password, role)

And we have the following relationships on the &apos;&apos;products&apos;&apos; table:

&lt;code&gt;
[parts]
    parts.part_id=product_parts.part_id
    product_parts.product_id=&quot;$product_id&quot;

[editors]
    product_editors.product_id=&quot;$product_id&quot;
&lt;/code&gt;


===Application Permissions : Very Restrictive===

Like a good boyscout, we define our default permissions in the [[Application Delegate Class]] to be very restrictive: Don&apos;t let anyone do anything.

&lt;code&gt;
class conf_ApplicationDelegate {
    function getPermissions($record){
        return Dataface_PermissionsTool::NO_ACCESS();
    }
}
&lt;/code&gt;


===Products Table Permissions: Less restrictive===

Now we open it up for our products table in the getPermissions() method of the products delegate class.

In tables/products/products.php:
&lt;code&gt;
class tables_products {
    function getPermissions($record){
        $user = Dataface_AuthenticationTool::getInstance()-&gt;getLoggedInUser();
        if ( $user and $record and $record-&gt;val(&apos;owner_username&apos;) == $user-&gt;val(&apos;username&apos;)){
        	// Give the record owner Edit permissions on the product
        	return Dataface_PermissionsTool::getRolePermissions(&apos;EDIT&apos;);
        }
        
        // Everybody else gets read only access to the products table.
        return Dataface_PermissionsTool::READ_ONLY();
    }
}

&lt;/code&gt;

===Checking if the current User is an Editor===

So far we have given the product owner edit permissions and everyone else read only permissions.  We still need to allow editors to edit the product.  In order to do this we need to be able to *efficiently* find out if the current user is an editor of a particular product.  There are a few different ways to do this, but some are better than others.  Some strategies include:

# Perform an SQL query inside the [[getPermissions]] method to see if the user is an editor for the product.  &apos;&apos;&apos;THIS IS VERY BAD!!!&apos;&apos;&apos; The [[getPermissions]] method should not include any IO or database queries because it is called a large number of times per request... making expensive calls in this method will slow down your app dramatically.
# Create a function to load and cache all of the current user&apos;s products so that this can be easily checked at will.  This is fine if the user is expected be able to edit only a few products.  If he could be an editor for thousands of products, this may not be practical as it will cause you to have to load thousands of records into memory on every page request.
# Use the [[__sql__]] method of the delegate class to create a grafted field on the &apos;&apos;products&apos;&apos; table indicating whether the current user is an editor for the product.  This results in a very quick and accessible indicator variable that can be used in the [[getPermissions]] method to check to see if the current user is an editor for the current product.  E.g.  In the tables/products/products.php file (delegate class):&lt;code&gt;
function __sql__(){
    return sprintf(&quot;select p.*, pe.editor_username from products p
                left join product_editors pe on p.product_id=pe.product_id
                where pe.editor_username=&apos;%s&apos;&quot;,
                addslashes(
                   Dataface_AuthenticationTool::getInstance()-&gt;getLoggedInUsername()
                )
            );
                
}&lt;/code&gt;

This will result in a situation where product records will have an additional field &apos;&apos;editor_username&apos;&apos; which will either be blank if the current user is not an editor for the product; or will contain the current user&apos;s username if they are an editor for the product.


===Table Permissions for Product Editors===

Now that we have a reliable way to tell, for any given product, whether the current user is, in fact, an editor, we can ammend the [[getPermissions]] method of the products table to include our editor permissions.

&lt;code&gt;
class tables_products {
    function getPermissions($record){
        $user = Dataface_AuthenticationTool::getInstance()-&gt;getLoggedInUser();
        if ( $user and $record and $record-&gt;val(&apos;owner_username&apos;) == $user-&gt;val(&apos;username&apos;)){
        	// Give the record owner Edit permissions on the product
        	return Dataface_PermissionsTool::getRolePermissions(&apos;EDIT&apos;);
        }
        
        if ( $user and $record and $record-&gt;val(&apos;editor_username&apos;) == $user-&gt;val(&apos;username&apos;) ){
            // If the user is an editor, we give them edit permissions
            // also
            return Dataface_PermissionsTool::getRolePermissions(&apos;EDIT&apos;);
        }
        
        
        if ( $user ){
        // Other logged in users have read only access
            $perms = Dataface_PermissionsTool::READ_ONLY();
            $perms[&apos;new&apos;] = 1; // We&apos;ll also let them add new products
            return $perms;
	}
	    
	// Regular users just get the default permissions as 
	// defined in the Application Delegate class
	return null;
    }
}

&lt;/code&gt;

===Removing Editor Access to the Editor Relationship===

You&apos;ll notice that at this point, the product editor has exactly the same permission as the product owner.  They both have permission to add and remove records from all relationships on the product.  However, we don&apos;t want them to be able to access the editors relationship at all.  We will use the [[rel_relationshipname__permissions]] method to override the permissions for the &apos;&apos;editors&apos;&apos; relationship.

In the tables/products/products.php delegate class:

&lt;code&gt;

function rel_editors__permissions($record){
    $user = Dataface_AuthenticationTool::getInstance()-&gt;getLoggedInUser();
	if ( $user and $record and $record-&gt;val(&apos;owner_username&apos;) == $user-&gt;val(&apos;username&apos;)){
		// Owners should just get their normal permissions
		return null;
	}
	
	if ( $user and $record and $record-&gt;val(&apos;editor_username&apos;) == $user-&gt;val(&apos;username&apos;) ){
		// If the user is an editor, we give them edit permissions
		// also
		return array(
		    &apos;view related records&apos; =&gt; 0,
		    &apos;add new related record&apos; =&gt; 0,
		    &apos;add existing related record&apos; =&gt; 0,
		    &apos;remove related record&apos; =&gt; 0,
		    &apos;delete related record&apos; =&gt; 0
		    );
	}
	
	// Other users just get their normal permissions
	return null;

}

&lt;/code&gt;


===Assigning product owner by default===

With the current permissions, something funny would happen.  Users have permission to add new records, but once the record is added they won&apos;t be able to edit it because they are neither an editor nor the owner of the product.  We&apos;ll fix this by assigning the current user as the product&apos;s owner using the [[beforeSave]] trigger in the products delegate class:

&lt;code&gt;
function beforeSave($record){
	$user = Dataface_AuthenticationTool::getInstance()-&gt;getLoggedInUser();
	if ( $user ){
    	$record-&gt;setValue(&apos;owner_username&apos;, $user-&gt;val(&apos;username&apos;));
    }
}
&lt;/code&gt;

===Testing Out Our Solution===

In your testing of the solution, you should find the following:

# Trying to access any table other than the &apos;&apos;products&apos;&apos; table should result in a &apos;&apos;permission denied&apos;&apos; error.
# If you access the &apos;&apos;products&apos;&apos; table, you should be able to see a list of existing products, and the &quot;Add New Record&quot; action.
# After you add a new product you should see that you are the product owner.
# As a product owner you should see both the &apos;&apos;parts&apos;&apos; and &apos;&apos;editors&apos;&apos; tabs in your product record.  You should be able to view and add new records to both of these relationships.
# Add another user as an editor to your product, then log in as that user.  You should be able to edit the product, but you shouldn&apos;t be able to see the &apos;&apos;editors&apos;&apos; tab for the product.

==See Also==

* [[permissions.ini file]] - Overview of the Xataface permissions.ini file
* [http://xataface.com/documentation/tutorial/getting_started/permissions Getting Started with Xataface Permissions]
* [[How to granulate permissions on each field]] - Brief tutorial on how to set permissions on a field by field basis.
* [[Delegate class methods]] - A list of all of the available delegate class methods that you can implement.  Many of them pertain to permissions and triggers.
* [[Application Delegate Class]] - Overview of the application delegate class.
* [[relationships.ini file]] - The relationships.ini file directives.
</content>
	<keywords>relationships, permissions, rel_relationshipname__permissions, getPermissions, permissions.ini</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=78">
	<page_name>GettingStarted:relationships</page_name>
	<page_id>78</page_id>
	<page_title>Relationships</page_title>
	<content>==Relationships==

Xataface allows you to define relationships between tables using the relationships.ini file.

Xataface applications without relationships between tables can be quite boring. In our FacultyOfWidgetry application, we have implicitly defined a relationship between the Program table and the Course table by adding a ProgramID field to the Course table. In the previous section we saw how to configure this relationship from the context of a &apos;Course&apos; by adding a select list to the Course table form to select the Program that the Course belongs to.

From the &apos;Program&apos; side it is a little bit more complicated. There are no fields in the &apos;Program&apos; table that can be edited to add a &apos;Course&apos; to the list of courses in a &apos;Program&apos;, and it would be highly inconvenient to have to edit a &apos;Course&apos; record in order to add the course to a &apos;Program&apos;. What we want is a sort of &apos;Add Course&apos; button to add a course to a &apos;Program&apos;. 

===Concepts, Definitions, and Terminology===

Before we can delve into examples, it will help to go over some of the concepts and terminology involved in relationships using Xataface. Xataface relationships are always defined in a one-way fashion from the point of view of one table. For example, if you define a one-to-many relationship from the &apos;Program&apos; table to the &apos;Course&apos; table, the mirror (many-to-one) relationship from &apos;Course&apos; to &apos;Program&apos; is not automatically created. This method of defining relationships allows us to unambiguously refer to the source and destination tables of a relationship.

&apos;&apos;&apos;Definition 1:&apos;&apos;&apos; The &apos;&apos;source table&apos;&apos; of a relationship is the table on which a relationship is defined. For example if we define a relationship named &apos;Courses&apos; on the &apos;Program&apos; table to associate courses in a given program, then the &apos;Program&apos; table would be considered the source table of the relationship, and the &apos;Course&apos; table would be a destination table of the relationship.

&apos;&apos;&apos;Definition 2:&apos;&apos;&apos; The &apos;&apos;destination table&apos;&apos; of a relationship a table from which related records are selected.

There may be multiple destination tables in a given relationship but only one source table. If there are multiple destination tables, then one of these tables is designated as the domain table and the remaining destination tables are called join tables. 

&apos;&apos;&apos;Definition 3:&apos;&apos;&apos; A &apos;&apos;domain table&apos;&apos; is a destination table which stores the object of the relationship. For example if we define a many-to-many relationship between the &apos;Program&apos; table and the &apos;Course&apos; table, (i.e., each program can contain multiple courses and each course can be part of multiple programs), then we would need to add a join table to map &apos;Course&apos; records to &apos;Program&apos; records. Let&apos;s call this table &apos;ProgramCourses&apos;. Each record of the &apos;ProgramCourses&apos; table would contain a 2 fields: a &apos;ProgramID&apos; field (to reference the program) and a &apos;CourseID&apos; field to reference the course. If we define the relationship from the point of view of a &apos;Program&apos; then the &apos;Program&apos; table would be the source table, the &apos;ProgramCourses&apos; table would be the join table, and the &apos;Course&apos; table would be the domain table.

Don&apos;t worry if these definitions and terms aren&apos;t clear at this point. Use this section as a reference for when you run across the terms later in the tutorial.

===Defining a relationship===

To define a relationship in Xataface, all you need to do is tell Xataface how to select the related records using SQL. Xataface will be able to figure out how to add/remove records to the relationship from this information. This information is defined inside a the &apos;relationships.ini&apos; file inside the configuration folder for the table.

====Example 1: Adding a &apos;Courses&apos; relationship to the &apos;Program&apos; table====

We want to be able to associate multiple courses with each program. We do this by defining a relationship on the &apos;Program&apos; table as follows:

# Add a file named &apos;relationships.ini&apos; to the &apos;Program&apos; table&apos;s configuration folder (i.e., tables/Program/relationships.ini). Your application&apos;s directory structure should now look like:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/directory-structure-relationships.gif]]&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;Notice, in particular the addition of the &apos;relationships.ini&apos; file in the &apos;Program&apos; directory.
# Add the following to the &apos;relationships.ini&apos; file:&lt;code&gt;
[Courses]
	Course.ProgramID = &quot;$ProgramID&quot;
&lt;/code&gt;	

This little snippet defines a relationship named &apos;Courses&apos; on the &apos;Program&apos; table. &apos;Program&apos; is the source table. &apos;Course&apos; is the destination table. There are no join tables because this is only a one-to-many relationship. You may be wondering what the $ProgramID means. This is a variable that represents the value of the &apos;ProgramID&apos; field in the source record. This relationship specifies that courses whose &apos;ProgramID&apos; field matches the value of the &apos;ProgramID&apos; field in the source record, are related to the source record. The english language makes this seem more difficult and complex than it really is.

Let&apos;s check out our changes. Since we have defined the relationship on the &apos;Program&apos; table, we will click on the &apos;Program&apos; link in the navigation menu:
[[Image:http://xataface.com/documentation/tutorial/getting_started/course-relationship-defined-1.gif]]

Notice that there is now a &apos;course&apos; tab at the top of the page. Click on this tab to see the courses that are related to this Program (as defined by our &apos;Courses&apos; relationship). If it says that &quot;No records matched the request&quot; or something to that effect, then you don&apos;t have any Course records in the relationship yet. Just click the &quot;Add New Courses Record&quot; button in the upper left to add a course. If there are courses in the relationship, then the Courses tab will look something like:

[[Image:http://xataface.com/documentation/tutorial/getting_started/courses-related-records.gif]]

Currently there is only one course in the program, but we can add more. If you click on the &quot;Add New Courses&quot; button in the upper left, you will be presented with a new course form that will allow you to add a new course in this Program.

===Example 2: Making the &apos;Courses&apos; relationship a Many-to-Many relationship===

Example 1 shows how Xataface can handle a one-to-many relationship. Now we will alter the database a little bit and turn this into a many-to-many relationship.

# Add a table named &apos;ProgramCourses&apos; to the database. The SQL table definition for this table should be something like:&lt;code&gt;
CREATE  TABLE  `ProgramCourses` (
	`ProgramID` INT( 11  )  NOT  NULL ,
	`CourseID` INT( 11  )  NOT  NULL ,
	PRIMARY  KEY (  `ProgramID` ,  `CourseID`  ) 
	) 
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;Note that it is important for ALL of your tables to have Primary keys. If a table is missing its primary keys, some strange behavior may occur with relationships involving that table.&lt;/p&gt;
&lt;p&gt;
The above defined table will serve as a join table between &apos;Program&apos; and &apos;Course&apos;
&lt;/p&gt;&lt;/nowiki&gt;
# Since this is now going to be a many-to-many relationship, we no longer need the &apos;ProgramID&apos; field in the &apos;Course&apos; table. (Do not confuse this with the ProgramID field in the &apos;Program&apos; table. That field is important and needed.). Before removing this field, we will transfer the information across so that the existing relationships are maintained. The following SQL query will effectively all of the old one-to-many relationships into equivalent many-to-many relationships:&lt;code&gt;
INSERT  INTO ProgramCourses( ProgramID, CourseID ) 
	SELECT ProgramID, CourseID
	FROM Course
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;	
And now we can remove the &apos;ProgramID&apos; field from the &apos;Course&apos; table.
ALTER  TABLE  Course  DROP  ProgramID&lt;/p&gt;&lt;/nowiki&gt;
# Finally, we will need to modify the relationship definition in the relationships.ini file of the &apos;Program&apos; table:&lt;code&gt;
[Courses]
	Course.CourseID = ProgramCourses.CourseID
	ProgramCourses.ProgramID = &quot;$ProgramID&quot; 
&lt;/code&gt;&lt;nowiki&gt;&lt;p&gt;
This means that all courses for which a (ProgramID, CourseID) pair matches the CourseID of the course and the ProgramID of the source Program record are included in the relationship.&lt;/p&gt;&lt;/nowiki&gt;
# Now we can check our application for changes. Go to the &apos;Program&apos; table in your application (using your web browser) and click on the &apos;courses&apos; tab once again:&lt;nowiki&gt;&lt;br/&gt;&lt;/nowiki&gt;[[Image:http://xataface.com/documentation/tutorial/getting_started/multi-relationship.gif]]&lt;nowiki&gt;
&lt;p&gt;
This looks almost the same as before. Notice, however that now there is an &quot;Add Existing Courses Record&quot; button at the top. This is because with a many-to-many relationship, you are able to add related records in 2 ways:&lt;/p&gt;&lt;/nowiki&gt;
## Adding a completely new record that did not exist before.
## Selecting a record that already exists and adding it to the relationship.

===Example 3: Defining Relationships using SQL===

The previous examples used a simple INI file syntax to define relationships. However, some people may be more comfortable defining their relationships using SQL. This is also possible. Let&apos;s look at the relationships.ini file from example 1:&lt;code&gt;
[Courses]
	Course.ProgramID = &quot;$ProgramID&quot;
&lt;/code&gt;

This also could have been defined as follows:&lt;code&gt;
[Courses]
	__sql__ = &quot;SELECT * FROM Course WHERE ProgramID=&apos;$ProgramID&apos;&quot;
&lt;/code&gt;

&apos;&apos;&apos;Note: Make sure you use two underscores on either side of &apos;sql&apos; in the above example. It should be &apos;__sql__&apos; not &apos;_sql_&apos;.&apos;&apos;&apos;

The two syntaxes are equivalent. In fact, the former will be converted into the later by Xataface behind the scenes.

Now let&apos;s look at example 2&apos;s relationships.ini file:&lt;code&gt;
[Courses]
	Course.CourseID = ProgramCourses.CourseID
	ProgramCourses.ProgramID = &quot;$ProgramID&quot; 
&lt;/code&gt;

This could have been written as:&lt;code&gt;
[Courses]
	__sql__ = &quot;SELECT * 
		FROM ProgramCourses, Course 
		WHERE Course.CourseID = ProgramCourses.CourseID 
		AND ProgramCourses.ProgramID = &apos;$ProgramID&apos;&quot;
&lt;/code&gt;

The two are equivalent. This example, however, shows how defining a relationship using SQL can be beneficial. The above SQL query will work but it can be done better using Joins as follows:&lt;code&gt;
[Courses]
	__sql__ = &quot;SELECT * 
		FROM ProgramCourses pc 
		INNER JOIN Course c ON pc.CourseID = c.CourseID 
		WHERE pc.ProgramID = &apos;$ProgramID&apos;&quot;
&lt;/code&gt;

All of these 3 methods will produce the same results, but the last one will probably give a little bit better performance.

===Relationship Restrictions===

Xataface has built-in logic to figure out how to add new and existing records to relationships that you define, as long as your relationships obey a few guidelines.

# All tables must have a Primary key
# The WHERE clause of your SQL definition for the relationship must contain only &apos;=&apos; comparisons, and &apos;AND&apos; conjunctions. i.e., it cannot receive an &apos;OR&apos; conjunction, nor can comparisons be done using &apos;&gt;&apos;, or &apos;&lt;&apos;. This is because given &apos;AND&apos; and &apos;=&apos; conjunctions it is easy for Xataface to be able to add records that will satisfy the relationship. If an &apos;OR&apos; conjunction is used, it makes it ambiguous (though this will probably be corrected in future Xataface releases.

===Download Source Files===

[http://xataface.com/documentation/tutorial/getting_started/facultyofwidgetry-8-tar.gz Download the source files for this application as a tar.gz archive]</content>
	<keywords>relationships</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=181">
	<page_name>after_action_activate</page_name>
	<page_id>181</page_id>
	<page_title>after_action_activate Delegate Class Method</page_title>
	<content>Return to [[Application Delegate Class]]

[[toc]]


The &apos;&apos;&apos;after_action_activate&apos;&apos;&apos; hook is a method that can be defined in the [[Application Delegate Class]] which is called after an account has been activated via the registration process.  The full registration process goes as follows:

# User fills in registration form.
# An email is sent to the user with a link to activate their account.
# User clicks on activation link.
# User is taken back to the application and activation occurs, which consists of creating a new record in the &apos;&apos;&apos;users&apos;&apos;&apos; table.
# The &apos;&apos;after_action_activate&apos;&apos; trigger is called.

===Since===

This hook has been available since Xataface Version 1.2

===Example===

&lt;code&gt;
/**
 * A trigger to send the user a confirmation email after their account has been activated.
 * @params array $params Associative array of passed parameters.  Contains a single key &apos;record&apos;
 * with the Dataface_Record object of the users table with the user that was activated.
 */
function after_action_activate(array $params){
    $user = $params[&apos;record&apos;];
    
    mail($user-&gt;val(&apos;email&apos;), &apos;Your account is activated&apos;, &apos;Your account has been activated... etc..&apos;);
}
&lt;/code&gt;

===See Also===

* [[Application Delegate Class]]
* [[registration_form]] - More information user registration forms.
* [[beforeRegister]] - Trigger called before the user registration form is saved.
* [[afterRegister]] - Trigger called after registration form is saved.
* [[validateRegistrationForm]] - Validates the input into the registration form.
* [[sendRegistrationActivationEmail]] - Overrides the sending of the registration activation email.
* [[getRegistrationActivationEmailInfo]] - Overrides the activation email info.  Returns an associative array of the email details (e.g. subject, to, headers, etc...
* [[getRegistrationActivationEmailSubject]] - Returns the subject of the activation email.
* [[getRegistrationActivationEmailMessage]] - Returns the message body for the activation email.
* [[getRegistrationActivationEmailParameters]] - Returns the parameters for the actication email.
* [[getRegistrationActivationEmailHeaders]] - Returns the headers for the activation email.
</content>
	<keywords>Registration, activation, register, activate, users</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=98">
	<page_name>registration_form</page_name>
	<page_id>98</page_id>
	<page_title>Setting up User Registration</page_title>
	<content>[[toc]]

===Synopsis===

Xataface optionally enables you to allow users to register for an account in your application.  If your &apos;&apos;users&apos;&apos; table includes a column for email, it will also perform email validation before the account is activated.  Before tackling user registration, it is good to have an understanding of Xataface&apos;s [[authentication]] and [http://xataface.com/documentation/tutorial/getting_started/permissions permissions] faculties.

===Enabling Registration===

To enable registration, simply add the following to the &apos;&apos;[[_auth]]&apos;&apos; section of the [[conf.ini file]]:

&lt;code&gt;
allow_register=1
&lt;/code&gt;

e.g. after adding this, your &apos;&apos;[[_auth]]&apos;&apos; section might look like:

&lt;code&gt;
[_auth]
     users_table=users
     username_column=username
     password_column=password
     allow_register=1
&lt;/code&gt;

After doing this, you&apos;ll notice a little &apos;&apos;Register&apos;&apos; link below the login form.  

[[Image:http://media.weblite.ca/files/photos/Picture%2036.png?max_width=640]]

Clicking on this link will produce a registration form for the user which is essentially a &quot;New Record&quot; form on your &apos;&apos;users&apos;&apos; table.

[[Image:http://media.weblite.ca/files/photos/Picture%2037.png?max_width=640]]

Some features of this registration form include:

* Checks to ensure that the username is unique
* If the users table contains an &apos;&apos;email&apos;&apos; field, it will use the user-entered address for email validation before activation is complete.

===Setting up Permissions to Support Registration===

&apos;&apos;&apos;Xataface &lt;= 1.2.4&apos;&apos;&apos;:   You must ensure that unlogged-in users have permission to add new records to the &apos;&apos;users&apos;&apos; table.  This means that your getPermissions() method on the users table should, at least, provide the &apos;&apos;new&apos;&apos; permission.  In addition these users must be granted the &apos;&apos;register&apos;&apos; permission in order to be able to register to begin with.

&apos;&apos;&apos;Xataface &gt;= 1.2.5&apos;&apos;&apos;:  You no longer need to provide the &apos;&apos;new&apos;&apos; permission to allow users to register.  You simply need to provide the &apos;&apos;register&apos;&apos; permission.

====Sample Permissions on Users Table====

In the tables/users/users.php file (assuming my &apos;&apos;users&apos;&apos; table is actually named &quot;users&quot;)

&lt;code&gt;
class tables_users {

    function getPermissions($record){
        if ( isAdmin() ) return null;
        $perms[&apos;register&apos;] = 1;
        return $perms;
     
    }
}
&lt;/code&gt;

&apos;&apos;&apos;Note that this example is only applicable for Xataface 1.2.5 or higher.  In Xataface 1.2.4 you needed to provide users with the &apos;&apos;new&apos;&apos; permission rather than the &apos;&apos;register&apos;&apos; permission, which opens up a small security hole since users could potentially just use the &quot;new&quot; action if they new the URL and by-pass the registration and activation email altogether&apos;&apos;&apos;.

Some notes on this example:

* The isAdmin() function is not part of Xataface.  It is used as a bit of *magic* here to reduce code.  It is supposed to simply return true if the currently logged in user is an admin.  Hence if the user is an admin, this method defers to the Application Delegate class&apos;s permissions (i.e. this method should not affect administrators).
* We are giving all users (logged in or not) the register permission which enables them to register for an account on the system.
* Generally you will want to restrict permissions on some of the fields in the users table.  E.g. users should not be able to set their role or access level when they register.  You can define more fine-grained permissions on these fields using the [[fieldname__permissions]] method of the users table delegate class (per the following example).

====Restricting Permissions on Particular Fields====

You probably don&apos;t want users to be able to set their access level when the register for an account, and your &quot;users&quot; table will quite often contain some field like &quot;role&quot; which stores this information.  So the previous example is not quite realistic.  You will also need to restrict permissions on the &quot;role&quot; field (and any other fields that you want to prevent users from setting themselves.

&lt;code&gt;
function role__permissions(&amp;$record){
    if ( isAdmin() ) return null;
    return Dataface_PermissionsTool::NO_ACCESS();
}
&lt;/code&gt;

This will cut off the user&apos;s ability to set their own role when they register.  You will likely want to set the default role value either in the mysql table definition or in the [[beforeInsert]] trigger.

===Email Validation===

As mentioned above, registration works by sending an activation email to the address specified in the user&apos;s registration.  This email contains a link back to the &apos;&apos;activate&apos;&apos; action of your Xataface application, which will create the user account and log the user in.  This implies that your &apos;&apos;users&apos;&apos; table must store an email address for your users.  If you add a field named &apos;&apos;email&apos;&apos; to the &apos;&apos;users&apos;&apos; table, Xataface will assume that you mean to use this field as the user&apos;s email address, and thus, for email validation.  However you can override this functionality and use *any* field as an email field by setting the &apos;&apos;email&apos;&apos; directive of the appropriate field in the [[fields.ini file]] for the &apos;&apos;users&apos;&apos; table.

&apos;&apos;&apos;Example: Assigning the my_addr field of the users table to be used for email validation&apos;&apos;&apos;:

In the tables/users/fields.ini file:
&lt;code&gt;
[my_addr]
    email=1
&lt;/code&gt;

====Disabling Email Validation====

99% of the time, email validation is the preferred way of ensuring that people who register are who they say they are.  You may, however, prefer to let users register directly without requiring the email activation step.  You can disable email validation by overriding the &apos;&apos;register&apos;&apos; action in the [[actions.ini file]] as follows:

In your application&apos;s [[actions.ini file]]:
&lt;code&gt;
[register &gt; register]
    email_validation=0
&lt;/code&gt;

After setting this, the user account will automatically be created, and the user logged in upon saving the registration form.

===Triggers: Overriding Registration Workflow===

Xataface provides a number of triggers in the [[Application Delegate Class]] to override and extend the behavior of the user registration and activation process.  For a list of available triggers see [[Application Delegate Class#registration]].


===Preventing Spam with CAPTCHA===

One problem with enabling automatic registration is that it invites SPAM in the form of bots that can learn how to automatically register for user accounts and then leave unwanted input into your application.  The Xataface [[reCAPTCHA module]] allows you to avoid these problems to some extent by forcing users who aren&apos;t logged in to fill a CAPTCHA field in order to successfully submit the form.  This is especially helpful for registration forms.

After installing the [[reCAPTCHA module]] the registration form will include a CAPTCHA field like the one depicted below:

[[Image:http://media.weblite.ca/files/photos/Picture%2038.png?max_width=640]]

For more information about the reCAPTCHA module [[reCAPTCHA module|click here]].
    </content>
	<keywords>registration form, _auth, authentication</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=115">
	<page_name>Using_RecordGrid</page_name>
	<page_id>115</page_id>
	<page_title>Using RecordGrid</page_title>
	<content>==Xataface RecordGrid Class and Template==

Also see [http://lamp.weblite.ca/dataface-0.6/docs/index.php?-table=Classes&amp;-action=browse&amp;ClassID=30| RecordGrid in the API Doc].


[[toc collapse=0]]

===Introduction===
As we learned in &apos;&apos;&apos;[http://xataface.com/documentation/tutorial/getting_started/dataface_actions Actions I: The Basics]&apos;&apos;&apos;, we can retrieve custom data from the DB in action via queries. This site deals with showing data in tabular form, like it could be received from even such a query. It is done by using Dataface_RecordGrid.


===First Example===
&lt;code&gt;
class actions_testTableAction {

	// Will be called from Xataface, if this action is called
	function handle(&amp;$params){
		$this-&gt;app =&amp; Dataface_Application::getInstance();  // reference to Dataface_Application object

		// Custom query
		$result = mysql_query(&quot;select * from testTable&quot;, $this-&gt;app-&gt;db());
		$body = &quot;&lt;br /&gt;&lt;br /&gt;&quot;;
		
		if(!$result)
		{
			// Error handling
			$body .= &quot;MySQL Error ...&quot;;
		}else
		{
			while($row = mysql_fetch_assoc($result))	// Fetch all rows
			{
				// Maybe do something with the single rows
				$data[] = $row;	// Add singe row to the data
			}
			mysql_free_result($result); // Frees the result after finnished using it

			$grid = new Dataface_RecordGrid($data);	// Create new RecordGrid with the data
			
			$body .= $grid-&gt;toHTML();	// Get the HTML of the RecordGrid
		}

		// Shows the content (RecordGrid or error message) in the Main Template
		df_display(array(&apos;body&apos; =&gt; $body), &apos;Dataface_Main_Template.html&apos;);
	}
}
&lt;/code&gt;

You get your data from the query, fetch it into an associative array, create with it an RecordGrid and use the toHTML function. This is sure better than manually create the html tags around the data.

=====Screenshot: Blank RecordGrid=====
&lt;nowiki&gt;
&lt;img src=&quot;http://i89.photobucket.com/albums/k234/horchr/xataface/RecordGrid_blank.png?max_width=610&quot;/&gt;
&lt;/nowiki&gt;

=====Screenshot: ResultList=====

&lt;nowiki&gt;
&lt;img src=&quot;http://i89.photobucket.com/albums/k234/horchr/xataface/RecordList.png?max_width=713&quot;/&gt;
&lt;/nowiki&gt;


===Colored Example===

As you see above, the resultlist has colored rows, our First Example not. But you can easily change this, when you override the Dataface_RecordGrid.html template:

&lt;code&gt;
&lt;table id=&quot;{$id}&quot; class=&quot;listing {$class}&quot;&gt;
	&lt;thead&gt;
		&lt;tr&gt;
		{foreach from=$labels item=label}
		&lt;th&gt;{$label}&lt;/th&gt;
		{/foreach}
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
		{section name=row loop=$data}
		&lt;tr class=&quot;listing {cycle values=&quot;odd,even&quot;}&quot;&gt;
			{foreach from=$columns item=col}
			&lt;td&gt;{$data[row][$col]}&lt;/td&gt;
			{/foreach}
		&lt;/tr&gt;
		{/section}
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;/code&gt;

The magic happens in &lt;tr class=&quot;listing {cycle values=&quot;odd,even&quot;}&quot;&gt;
The {cycle values=&quot;odd,even&quot;} value cycles these two values and creates so the alternating row classes, like they are in the RecordList. By the way, {cycle ...} is a Smarty Function, see [http://www.smarty.net/docsv2/en/language.custom.functions.tpl| Smarty Doc].

(Find fruther information to template overriding in the tutorial and its links: [http://xataface.com/documentation/tutorial/getting_started/changing-look-and-feel| Changing the Look and Feel])

=====Screenshot: colored RecordGrid=====

&lt;nowiki&gt;
&lt;img src=&quot;http://i89.photobucket.com/albums/k234/horchr/xataface/RecordGrid_colored.png?max_width=610&quot;/&gt;
&lt;/nowiki&gt;


===Example completly imitating ResultList===

The Colored Example doesn&apos;t look like the ResulList? Its rows aren&apos;t as high as theres? That&apos;s a styling matter or rather in this case a cause of the checkboxes. Here an example with checkboxes and added (empty) links, so it looks completly like the ResultList:

Change the part in action.php
&lt;code&gt;
			while($row = mysql_fetch_assoc($result))	// Fetch all rows
			{
				// Maybe do something with the single rows
				$row[&apos;&lt;input type=&quot;checkbox&quot;&gt;&apos;] = &apos;&lt;input type=&quot;checkbox&quot;&gt;&apos;;
				$data[] = $row;	// Add singe row to the data
			}
			mysql_free_result($result); // Frees the result after finnished using it

			$grid = new Dataface_RecordGrid($data,	// Create new RecordGrid with the data
				  array(&apos;&lt;input type=&quot;checkbox&quot;&gt;&apos;, &apos;testID&apos;, &apos;name&apos;, &apos;description&apos;, &apos;number&apos;),	
				//Order and selection of the colums
				  null);	// No other labels defined -&gt; it uses keys of the associative array
			
			$body .= $grid-&gt;toHTML();	// Get the HTML of the RecordGrid
&lt;/code&gt;

Dataface_RecordGrid.html template
&lt;code&gt;
&lt;table id=&quot;{$id}&quot; class=&quot;listing {$class}&quot;&gt;
	&lt;thead&gt;
		&lt;tr&gt;
		{foreach from=$labels item=label}
		&lt;th&gt;&lt;a class=&quot;unmarked_link&quot;&gt;{$label}&lt;/a&gt;&lt;/th&gt;
		{/foreach}
		&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
		{section name=row loop=$data}
		&lt;tr class=&quot;listing {cycle values=&quot;odd,even&quot;}&quot;&gt;
			{foreach from=$columns item=col}
			&lt;td&gt;&lt;a class=&quot;unmarked_link&quot;&gt;{$data[row][$col]}&lt;/a&gt;&lt;/td&gt;
			{/foreach}
		&lt;/tr&gt;
		{/section}
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;/code&gt;

=====Screenshot: RecordGrid completly imitating ResultList=====

&lt;nowiki&gt;
&lt;img src=&quot;http://i89.photobucket.com/albums/k234/horchr/xataface/RecordGrid_colored_checkboxes_links.png?max_width=610&quot;/&gt;
&lt;/nowiki&gt;

=====Screenshot: ResultList=====

&lt;nowiki&gt;
&lt;img src=&quot;http://i89.photobucket.com/albums/k234/horchr/xataface/RecordList.png?max_width=713&quot;/&gt;
&lt;/nowiki&gt;

===Try it out===

Use the following code with static test data and any template in this article (or even without overriding it) to try it out.

&lt;code&gt;
class actions_testTableAction {

	// Will be called from Xataface, if this action is called
	function handle(&amp;$params){
		$this-&gt;app =&amp; Dataface_Application::getInstance();  // reference to Dataface_Application object

		$result_dummy = array(
			array(&apos;testID&apos; =&gt; &apos;1&apos;, &apos;name&apos; =&gt; &apos;testname&apos;, 
				&apos;description&apos; =&gt; &apos;a short description&apos;, &apos;number&apos; =&gt; &apos;258&apos;),
			array(&apos;testID&apos; =&gt; &apos;2&apos;, &apos;name&apos; =&gt; &apos;another name&apos;, 
				&apos;description&apos; =&gt; &apos;a bit longer description to this data set&apos;, &apos;number&apos; =&gt; &apos;946&apos;),
			array(&apos;testID&apos; =&gt; &apos;3&apos;, &apos;name&apos; =&gt; &apos;dummy name&apos;, 
				&apos;description&apos; =&gt; &apos;yea, a dummy data set!&apos;, &apos;number&apos; =&gt; &apos;1342&apos;),
			array(&apos;testID&apos; =&gt; &apos;4&apos;, &apos;name&apos; =&gt; &apos;not empty&apos;, 
				&apos;description&apos; =&gt; &apos;this data set isn\&apos;t empty ...&apos;, &apos;number&apos; =&gt; &apos;282&apos;),
			array(&apos;testID&apos; =&gt; &apos;5&apos;, &apos;name&apos; =&gt; &apos;your entry&apos;, 
				&apos;description&apos; =&gt; &apos;this entry is only for you&apos;, &apos;number&apos; =&gt; &apos;79&apos;),
			array(&apos;testID&apos; =&gt; &apos;6&apos;, &apos;name&apos; =&gt; &apos;no idea&apos;, 
				&apos;description&apos; =&gt; &apos;running out of ideas ...&apos;, &apos;number&apos; =&gt; &apos;203&apos;),
			array(&apos;testID&apos; =&gt; &apos;7&apos;, &apos;name&apos; =&gt; &apos;the last one&apos;, 
				&apos;description&apos; =&gt; &apos;the end&apos;, &apos;number&apos; =&gt; &apos;26841&apos;)
		);
		$body = &quot;&lt;br /&gt;&lt;br /&gt;&quot;;
		
		foreach($result_dummy as $row)	// Fetch all rows
		{
			// Maybe do something with the singe rows
			$row[&apos;&lt;input type=&quot;checkbox&quot;&gt;&apos;] = &apos;&lt;input type=&quot;checkbox&quot;&gt;&apos;;
			$data[] = $row;	// Add singe row to the data
		}

		$grid = new Dataface_RecordGrid($data,	// Create new RecordGrid with the data
			array(&apos;&lt;input type=&quot;checkbox&quot;&gt;&apos;, &apos;testID&apos;, &apos;name&apos;, &apos;description&apos;, &apos;number&apos;),	
			//Order and selection of the colums
			  null);	// No other labels defined -&gt; it uses keys of the associative array

		$body .= $grid-&gt;toHTML();	// Get the HTML of the RecordGrid

		// Shows the content (RecordGrid or error message) in the Main Template
		df_display(array(&apos;body&apos; =&gt; $body), &apos;Dataface_Main_Template.html&apos;);
	}
}
&lt;/code&gt;
</content>
	<keywords>RecordGrid, Dataface_RecordGrid, data in tabular form</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=104">
	<page_name>field__pullValue</page_name>
	<page_id>104</page_id>
	<page_title>field__pullValue delegate class method</page_title>
	<content>[[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 &apos;&apos;start_ip&apos;&apos; 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&apos;s delegate class.

&lt;code&gt;
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-&gt;getValue());
		if ( $val !== false ){
			return sprintf(&apos;%u&apos;, $val );
		}
		return null;
	}
	
	function start_ip__pullValue($record, $el){
		$val = $record-&gt;val(&apos;start_ip&apos;);
		if ( $val )
			return long2ip($val);
		return $val;
	}
}
&lt;/code&gt;

==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.
</content>
	<keywords>pushValue, pullValue</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=105">
	<page_name>field__pushValue</page_name>
	<page_id>105</page_id>
	<page_title></page_title>
	<content>[[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 &apos;&apos;start_ip&apos;&apos; 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&apos;s delegate class.

&lt;code&gt;
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-&gt;getValue());
		if ( $val !== false ){
			return sprintf(&apos;%u&apos;, $val );
		}
		return null;
	}
	
	function start_ip__pullValue($record, $el){
		$val = $record-&gt;val(&apos;start_ip&apos;);
		if ( $val )
			return long2ip($val);
		return $val;
	}
}
&lt;/code&gt;

==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.
</content>
	<keywords>pullValue, pushValue</keywords>
	<language>en</language>
	<original_page></original_page>
</wiki></record>