<?xml version="1.0"?>
<record><wiki id="wiki?page_id=36">
	<page_name>about</page_name>
	<page_id>36</page_id>
	<page_title>about</page_title>
	<content>==About Xataface==

[[toc]]

Xataface is a flexible and shapable skin that sits on top of MySQL, making it accessible to every-day users. It automatically generates the appropriate forms, lists, and menus for a user to interact with the database without having to know any SQL. 

It is a full-featured Web application framework, and gives developers the flexibility to customize the features and behavior of their application via configuration files (using the simple INI-file syntax), templates, and plug-ins. A generic application with no customizations is completely functional, but the developer is free to customize things at his leisure.

===Who is Xataface for?===

Xataface is for web developers and database administrators who would like to build a front-end for their MySQL database.  However the resulting applications are targeted at non-technical users such as secretaries.

===Requirements===

====Xataface 1.1.x and below:====

* MySQL 3.23+
* PHP 4+

Some advanced features require MySQL version 4.1 or higher.

====Xataface 1.2 and higher====

* MySQL 3.23+
* PHP 5+

Some advanced features require MySQL version 5 or higher.

===At a Glance: Your first App===

# Create a directory for your app.
# Copy the &apos;&apos;xataface&apos;&apos; directory inside your application directory.
# Create a configuration file named &apos;&apos;conf.ini&apos;&apos; in your application directory with your database settings:&lt;code&gt;
[_database]
    host=localhost
    name=mydb
    user=me
    password=mypass

[_tables]
    ; A list of tables to include in your application&apos;s menu
    ; These tables must already exist in your database
    people=Profiles
    news=News Articles
&lt;/code&gt;
# Create an .htaccess file in your application directory to prevent access to 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;
# Create a PHP script in your application directory as an access point for your app.  We&apos;ll call it &apos;&apos;index.php&apos;&apos;:&lt;code style=&quot;php&quot;&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;);
    // first parameter is always the same (path to the current script)
    // 2nd parameter is relative URL to xataface directory (used for CSS files and javascripts)

// Create a new application
$app =&amp; Dataface_Application::getInstance();

// Display the application
$app-&gt;display()
&lt;/code&gt;
# You&apos;re done.  Your app is ready to use!

This is just the beginning, though.  There is no limit to the customizations you can make on your application.

Read the [http://xataface.com/documentation/tutorial/getting_started Getting Started Tutorial] for more information on developing applications with Xataface.


===Product Comparison===

Xataface fits a niche that is not well covered by existing apps/frameworks.  Xataface is &apos;&apos;&apos;NOT&apos;&apos;&apos;:

* A database administration system like PHPMyAdmin
* Simply a software library/Framework like PHPCake
* Simply a content management system like Drupal
* A code generator

Xataface is a framework, but it is not a typical framework.  Most frameworks require a substantial amount of development before you get a usable application.  Xataface, on the other hand, provides you with a fully-functional application with as little as 4 lines of PHP code.  It doesn&apos;t generate any code so it is easy to maintain your application and expand on it later.

As a development framework, Xataface most closely resembles Django, a python framework for building data-driven applications.  As an application, Xataface most closely resembles Filemaker, a popular relational database that makes it easy for the end user to create layouts and manage their data.

===Features===

====General====

* &apos;&apos;&apos;Out-of-the-box Database Front-end&apos;&apos;&apos; - With as little as 4 lines of PHP code, you can have a full-featured web application for your database.
* &apos;&apos;&apos;Simple, Intuitive User interface&apos;&apos;&apos; - Default application is consistent and simple to use.  There is a &apos;tables&apos; menu, to select a table, and each table has &quot;details&quot;, &quot;list&quot;, and &quot;find&quot; tabs.  Very easy to navigate.
* &apos;&apos;&apos;Powerful configuration options&apos;&apos;&apos; - You can configure your application details (such as widget types) using simple configuration files.
* &apos;&apos;&apos;Extendible&apos;&apos;&apos; - You can modify your application as you see fit using configuration files and PHP delegate classes.
* &apos;&apos;&apos;Hooks&apos;&apos;&apos; - By observing simple conventions you can extend Xataface&apos;s functionality with hooks, triggers, and events.  E.g. add a function that is called after a record is inserted.
* &apos;&apos;&apos;Permissions&apos;&apos;&apos; - Powerful, pluggable permissions system.
* &apos;&apos;&apos;Authentication&apos;&apos;&apos; - Provides login/logout ability.  You just specify which table your users are stored in.
* &apos;&apos;&apos;Relationships&apos;&apos;&apos; - Tell Xataface how your tables are related to one another and it will provide you with more logical functionality for managing your data.
* &apos;&apos;&apos;Themeable&apos;&apos;&apos; - Xataface uses the Smarty template engine as a base, but extends it with some powerful new features such as extendable templates and theming support.
* &apos;&apos;&apos;Modular&apos;&apos;&apos; - There are several add-on modules available to extend the features of Xataface even further, and a simple API for writing your own modules.


====Editing====

* &apos;&apos;&apos;Automatic Form Generation&apos;&apos;&apos; - Automatically generates appropriate web forms to add new records and edit existing records.
* &apos;&apos;&apos;Widgets&apos;&apos;&apos; - Support for many different widget types including text fields, text areas, checkboxes, select lists, html editors, grids, file uploads, and more.
* &apos;&apos;&apos;Configurable&apos;&apos;&apos; - Customize forms using configuration files and delegate classes.
* &apos;&apos;&apos;Personalizable&apos;&apos;&apos; - Show different forms to different users depending on their permissions and preferences.
* &apos;&apos;&apos;Add Related Records&apos;&apos;&apos; - Insert records and automatically track their relationships to other tables.
* &apos;&apos;&apos;Editable Data Grid&apos;&apos;&apos; - Manage your data like a spreadsheet using the DataGrid module.
* &apos;&apos;&apos;Copy&apos;&apos;&apos; - Copy sets of records.
* &apos;&apos;&apos;Update Found Set&apos;&apos;&apos; - Update multiple records with one swipe.
* &apos;&apos;&apos;Fine-grained Permissions&apos;&apos;&apos; - Assign editing permission based on table, record, or field. 
* &apos;&apos;&apos;File uploads&apos;&apos;&apos; - Support for file uploads with storage either in a BLOB field or on the file system.
* &apos;&apos;&apos;Delete&apos;&apos;&apos; - Delete single record or delete the current found set.

====Searching====

* &apos;&apos;&apos;Automatic Find Form&apos;&apos;&apos; - The Xataface find form allows you to search a table on any field.
* &apos;&apos;&apos;Range Searches&apos;&apos;&apos; - Search for records matching values in a certain range (e.g. find all people between the ages of 20 and 30).
* &apos;&apos;&apos;Exact Matching&apos;&apos;&apos; - Search for exact matches.
* &apos;&apos;&apos;Partial Matching&apos;&apos;&apos; - Search for fields that contain a keyword phrase.
* &apos;&apos;&apos;Multi-field search&apos;&apos;&apos; - There is always a simple search field accessible which searches all fields in the current table.  E.g. a search for &quot;Tom&quot; would match any record in the current table that contained the phrase &quot;Tom&quot; in any of its columns.
* &apos;&apos;&apos;Related Record Searches&apos;&apos;&apos; - Find records that contain related records matching a search term.  (E.g. find all people who got an &apos;A&apos; in a particular course).


====Browsing====

* &apos;&apos;&apos;Automatic Details View&apos;&apos;&apos; - Each record has user-friendly details page to browse the contents of the record.
* &apos;&apos;&apos;AJAX Record Tree&apos;&apos;&apos; - Provides optional AJAX record tree to browse the data in your database by relationships.
* &apos;&apos;&apos;Expand for More&apos;&apos;&apos; - Quickly expand a row in list view to see the full record details.
* &apos;&apos;&apos;Drag and Drop Reordering&apos;&apos;&apos; - The details view for a record can be broken up into related sections.  Users can reorder these sections via drag and drop.

====Exporting====

* &apos;&apos;&apos;RSS&apos;&apos;&apos; - Support for RSS 1.0, 2.0 and Atom feeds of any found set.
* &apos;&apos;&apos;XML&apos;&apos;&apos; - Export any found set as XML so that the data can be interchanged with other products (e.g. desktop publishing suites).
* &apos;&apos;&apos;CSV&apos;&apos;&apos; - Export any found set to CSV (comma-separated-value) to open in a spreadsheet application like Excel.
* &apos;&apos;&apos;JSON&apos;&apos;&apos; - Export any found set to JSON.  This feature makes Xataface a good choice for serving the next generation of Web 2.0 AJAX applications.

====Internationalization====

* &apos;&apos;&apos;String Internationalization&apos;&apos;&apos; - Xataface fully supports internationalizing your application.  It provides you with language files to provide translations of all of the strings and labels in your application.
* &apos;&apos;&apos;Dynamic Data Translation&apos;&apos;&apos; - Xataface even allows you to internationalize your existing database data without having to change your database structure.
* &apos;&apos;&apos;Templates&apos;&apos;&apos; - Includes a {translate} tag for Smarty templates to easily translate template text.
* &apos;&apos;&apos;In the background&apos;&apos;&apos; - You can use Xataface to internationalize any PHP/MySQL website without having to make any drastic changes to your existing code.  Just include Xataface as a library and use some of its useful internationalization functions to convert your application into multiple languages.
* &apos;&apos;&apos;Translation Form&apos;&apos;&apos; - If multiple languages are enabled, Xataface provides a simple translation form to translate content between languages.
* &apos;&apos;&apos;Translation Status Tracking&apos;&apos;&apos; - Track the status of translations to mark whether they need to be retranslated.

====Importing====

* &apos;&apos;&apos;Import Filter API&apos;&apos;&apos; - Using delegate classes, it is easy to define an import filter to import any type of data into the database.
* &apos;&apos;&apos;User Preview&apos;&apos;&apos; - User can preview imported data before confirming that he wants to import it.

====History====

* &apos;&apos;&apos;Optional History Support&apos;&apos;&apos; - If history is enabled, all changes made to any data are recorded.
* &apos;&apos;&apos;Undo/Redo Support&apos;&apos;&apos; - Easily revert to an earlier version of a record.
* &apos;&apos;&apos;View Snapshot&apos;&apos;&apos; - Browse previous versions of records.
* &apos;&apos;&apos;View Diffs&apos;&apos;&apos; - View differences/changes between versions of records, similar to a wiki.

====Caching====

* &apos;&apos;&apos;Output cache&apos;&apos;&apos; - Supports output cache that caches output of pages to improve performance dramatically for busy sites.  Cache is automatically refreshed whenever changes are made to tables that are used to generate the page.
* &apos;&apos;&apos;APC Support&apos;&apos;&apos; - If APC (Alternate PHP Cache) is installed, Xataface will automatically use it to cache table configuration information.  This tends to increase performance by about 20%.


====Security====

* &apos;&apos;&apos;Fine-grained permissions&apos;&apos;&apos; - Define permissions to the entire application, a single table, by the record, or by the field.  Each feature has an associated permission that can be allowed or disallowed on a per-user basis.
* &apos;&apos;&apos;Cascading Permissions&apos;&apos;&apos; - You can very restrictive permissions to the application as a whole and then apply more permission permissions to specific tables or fields that you want uses to be able to access.  Table permissions override application permissions.  Field permissions override field permissions.
* &apos;&apos;&apos;Role-based permissions&apos;&apos;&apos; - You can define &quot;&quot;&quot;roles&quot;&quot;&quot; which are sets of permissions that can be assigned to users.
* &apos;&apos;&apos;Extendable Permissions Model&apos;&apos;&apos; - You can easily define your own permissions and roles, extending existing roles, custom for your application.
* &apos;&apos;&apos;Built-in Authentication&apos;&apos;&apos; - It is easy to set up login/logout features for your application.  Just tell Xataface which table you store your user records in, and Xataface will do the rest.
* &apos;&apos;&apos;Password Encryption&apos;&apos;&apos; - Xataface supports and is compatible with most of the standard password encryptions including MD5, SHA1, and MySQL Password.
* &apos;&apos;&apos;Pluggable Authentication&apos;&apos;&apos; - Easy to create your own authentication plugins in case you want to implement your own custom authentication.
* &apos;&apos;&apos;CAS&apos;&apos;&apos; - Module available for the Yale CAS (Central Authentication Service).
* &apos;&apos;&apos;LDAP&apos;&apos;&apos; - LDAP authentication module available.
* &apos;&apos;&apos;HTTP&apos;&apos;&apos; - Optional HTTP login support.  Standard login uses a web-based login form, but you can also use HTTP headers for authentication.

====Relationships====

* &apos;&apos;&apos;Powerful Relationship Model&apos;&apos;&apos; - It is easy to define relationships between your tables using simple configuration files.  Syntax is simple, but the results are powerful.
* &apos;&apos;&apos;Add New Related Record&apos;&apos;&apos; - Create a new record and add it to a parent record&apos;s relationship at the same time. (E.g. create a new &quot;course&quot; record and add it to a teacher&apos;s list of taught courses).
* &apos;&apos;&apos;Add Existing Related Record&apos;&apos;&apos; - Add an existing record to a parent record&apos;s relationship. (e.g. Add an existing course record to a teacher&apos;s list of taught courses).
* &apos;&apos;&apos;Remove related record&apos;&apos;&apos; - Remove a record from a relationship. (e.g. remove a course record from a teacher&apos;s list of taught courses).

====API====

Xataface includes a powerful API to allow you to more efficiently work with your database.

* &apos;&apos;&apos;Data Objects&apos;&apos;&apos; - Provides a simple API to work with database records.  Searching, loading, saving, editing, and deleting records supported.

====Templates====

* &apos;&apos;&apos;Smarty Template Engine&apos;&apos;&apos; - Xataface uses the Smarty template engine as a base, one of the fastest PHP template engines available.
* &apos;&apos;&apos;Template Inheritance&apos;&apos;&apos; - You can create templates that inherit from other templates, and replace the content in specified &quot;slots&quot; of the original template.  This drastically increases template reuse and development productivity.
* &apos;&apos;&apos;Cascading Support&apos;&apos;&apos; - All system templates are stored in the Dataface/templates directory.  Your application can have its own templates directory where you can place templates to override system templates.  All parts of the system can be overridden without modifying the original templates themselves.

====Themes====

Xataface includes a powerful themes API.  You can create multiple looks for your application and switch between them with a simple configuration setting.

====REST Support====

Xataface&apos;s intelligent URL protocols make it a powerful platform for REST web services.  You can specify a query directly in the URL to obtain the exact found-set that you want.  This is also very useful in standard web applications because you can easily create links to desired parts of your application.  Or you can use Xataface to provide missing functionality in your existing applications and link only to the parts of your Xataface app that you need.

===History===

Xataface (formerly Dataface) was originally created by Steve Hannah in 2005 to increase productivity created data-driven applications for Simon Fraser University.  He came from faculty that used Filemaker extensively for their databases.  As a PHP developer he preferred open technologies like MySQL as they provided fewer &quot;road blocks&quot;, but it was hard to deny the benefits of filemaker when it came to providing users with an instant user interface for their databases.  It was difficult to justify spending 3 weeks building an administration console for a MySQL application when it could have been done in 3 hours had Filemaker been used.

Xataface was designed to:

# Increase developer productivity to the point where MySQL applications could be created as quickly as Filemaker applications without sacrificing usability and functionality.
# Add an abstraction over a database to make is accessible to non-technical users.  The secretary shouldn&apos;t need to know SQL in order to interact with a database.
# Test the limits of PHP and MySQL

As it was built with the intention of providing an alternative for Filemaker, many implementation details and concepts have been inspired by Filemaker.  For example, Xataface&apos;s implementation of relationships is very similar to Filemaker relationships; as are valuelists.  In addition the method of searching follows many Filemaker conventions.

The first application built with Xataface was a group content management system for the Faculty of Applied Sciences at Simon Fraser University.  This system was used by faculty to manage their research profiles and their research groups.  The database itself pre-existed the Xataface implementation.   Xataface was used to build a new administrative interface to the system.  Since then Xataface has been used to develop many systems for SFU including website content management systems, auctions, event registration systems, research databases, shopping carts, and more.

==Where to go from here==

* [http://xataface.com/documentation/tutorial/getting_started Getting Started Tutorial]
* [http://xataface.com/videos Watch Demonstration Videos of Xataface]
* Sign up for the Xataface Maillist to receive free updates and development tips.  (See sign-up form in upper left of the page).</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=6">
	<page_name>actions.ini_file</page_name>
	<page_id>6</page_id>
	<page_title>actions.ini_file</page_title>
	<content>==actions.ini file Reference==

[[toc]]

The actions.ini file stores information about the various [[action]]s that can be performed by your application.  An action may be manifested in two ways:

# As a web page
# As a menu item

And there is no reason why an action cannot serve in both capacities simultaneously.  All menu items and functions that Xataface performs are defined in the Xataface actions.ini file (in the root of the Xataface installation dirctory).  You can also create an actions.ini file in your application&apos;s root directory to override existing Xataface actions, or to create your own.  If you want to modify an existing action instead of overriding it, you can use this syntax.

&lt;code&gt;
[browse &gt; browse]
	label = Browse
&lt;/code&gt;

The &amp;gt; symbol simply means to inherit from the existing browse action.  All the attributes are the same, and we just override the label to Browse (originally was Details)

Additionally, for actions that pertain only to a single table, an actions.ini file may be placed in any [[table configuration directory]].

===Syntax===

As with the [[fields.ini file]] and the [[valuelists.ini file]], the actions.ini file uses the simple [[INI file syntax]] to define its actions.  Each action is defined in its own section, and can have a number of directives to specify the action&apos;s behavior.

Here is a snippet from the Xataface actions.ini file to give you an idea:

&lt;code&gt;
;; Show the details of the current record
[browse]
	label = Details
	category = table_tabs
	url = &quot;{$this-&gt;url(&apos;-action=view&apos;)}&quot;
	accessKey = &quot;b&quot;
	mode = browse
	permission = view
	order=0

;; Show a list of the records in the current found set
[list]
	label = List
	category = table_tabs
	url = &quot;{$this-&gt;url(&apos;-action=list&apos;)}&quot;
	accessKey = &quot;l&quot;
	mode = list
	template = Dataface_List_View.html
	permission = list
	order=0.5

;; Show a &quot;Find Record Form&quot;
[find]
	label = Find
	category = table_tabs
	url = &quot;{$this-&gt;url(&apos;-action=find&apos;)}&quot;
	accessKey = &quot;f&quot;
	mode = find
	permission = find
	template = Dataface_Find_View.html
	order=0.75
&lt;/code&gt;

This snippet shows the definition of the browse, list, and find actions - three of the most central actions in a Xataface application.  Notice how each action has its own section (according to [[INI file syntax]]) with a number of directives which specify how the action behaves.  For instance, each action has a &quot;category&quot; value of &quot;table_tabs&quot;, which tells Xataface to display the actions as part of the table tabs in the user interface.

===Directives===

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| [[action allow_override|allow_override]]
| An optional directive to indicate that this action can be overridden by more specific directives in another ini file.  Currently there is only support for a value of &quot;relationships.ini&quot; indicating that the settings can be overridden in the relationships.ini file.  In order for this to work, related=1 must also be set.
| 1.3rc4
|-
| [[action label|label]]
| The label to display if the action is used as a menu item.
| all
|-
| [[action category|category]]
| The name of the action&apos;s category which can be used to group this action together with other similar actions to be used in a menu in the user interface.
| all
|-
| [[action url|url]]
| If the action appears as a menu item, this is the URL that the menu item points to.  This may contain PHP expressions inside curly braces.
| all
|-
| [[action accessKey|accessKey]]
| The key code to automatically select this action if it is included as a menu item.  I.e. ALT+accessKey calls the action.
| all
|-
| [[action mode|mode]]
| This indicates which tab of the table tabs (find, details, list, etc...) that this action should appear to be part of when the action is viewed as a web page.  If this is left undefined, or it does not match any existing visible action in the table tabs, then no tab will appear to be selected.
| all
|-
| [[action permission|permission]]
| The name of a permission required to both see the action as part of a menu and to access the action as a web page.
| all
|-
| [[action visible|visible]]
| A boolean value indicating whether the action should be visible as a menu item.
| all
|-
| [[action condition|condition]]
| A boolean value or a PHP expression evaluating to a boolean value to indicate whether the action should be visible as a menu item.
| all
|-
| [[action url_condition|url_condition]]
| A PHP expression evaluating to a boolean value to indicate whether the URL directive should be evaluated.  This basically checks to make sure that its OK to evaluate the &quot;url&quot; expression, just in case the current state of affairs would cause it to throw a fatal error.
| all
|-
| [[action order|order]]
| A numeric value indicating the order in which the action should be displayed as part of a menu.  Low numbers result in higher placement in the menu.
| all
|-
| [[action icon|icon]]
| The path to an icon that should be used when the action appears as a menu item.
| all
|-
| [[action template|template]]
| The path to the template that should be used when the action is displayed as a web page.
| all
|-
| [[action description|description]]
| Mouseover text for the action (when displayed as a menu item).
| all
|}

===PHP Expression Context===

Notice that the [[action url|url]], [[action condition|condition]], and [[action url_condition|url_condition]] directives allow you to use a PHP expression for their values.  In order for this to be helpful, you should know a little bit about the context and environment in which these expressions will be executed.  All expressions are evaluated immediately prior to being rendered, so the same action can be displayed multiple times in the same page, but have very different resulting values for their [[action url|urls]] and [[action condition|conditions]].

These expressions are all executed within the context of the Dataface_Application::parseString() method, with the following variables loaded in the local symbol table (i.e. you can use the following variables in your expressions).

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| [[action context:site_url|$site_url]]
| The URL to the current application&apos;s directory (not including &quot;index.php&quot;)
| all
|-
| $site_href
| The URL to the current application including &quot;index.php&quot;
| all
|-
| $dataface_url
| The URL to the xataface installation directory.
| all
|-
| $table
| The name of the current table (i.e. the value of the &quot;-table&quot; request parameter&quot;
| all
|-
| $query
| An associative array of the current query variables.
| all
|-
| $app
| A reference to the current Dataface_Application object.  Alias of &quot;$this&quot;
| all
|-
| $resultSet
| A reference to the Dataface_QueryTool object for the current query.
| all
|-
| [[action context:record|$record]]
| A reference to the current Dataface_Record object.
| all
|-
| [[action context:context|$context]]
| An associative array of context variables that are passed to the action from the context in which the action is called.
| all
|}</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=183">
	<page_name>advmultiselect</page_name>
	<page_id>183</page_id>
	<page_title></page_title>
	<content></content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=14">
	<page_name>afterRegister</page_name>
	<page_id>14</page_id>
	<page_title>afterRegister</page_title>
	<content>==afterRegister() Trigger==

A trigger that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]], to be executed after the registration form is saved.  This can be used to perform some custom actions like emailing the administrator.

===Signature===

function afterRegister( Dataface_Record &amp;$record ) : mixed

====Parameters====

{| class=&quot;listing listing2&quot;
! Name
! Description
|-
| &amp;$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {
    function afterRegister(&amp;$record){
        // mail the admin to let him know that the registration is occurring.
        mail(&apos;admin@example.com&apos;, &apos;New registration&apos;, &apos;A new user &apos;.$record-&gt;val(&apos;username&apos;).&apos; has registered);
    }
}
&lt;/code&gt;

===See Also===

* [[beforeRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=33">
	<page_name>after_action_new</page_name>
	<page_id>33</page_id>
	<page_title>after_action_new</page_title>
	<content>==after_action_new trigger==

[[toc]]

This trigger is called after the &apos;&apos;&apos;new&apos;&apos;&apos; action is successfully completed.  This trigger can be defined in the table [[Delegate class methods|delegate class]] and is often used to redirect to a particular page after a new record is submitted.  This should not be confused with the [[afterInsert]] trigger, which is executed after a record is inserted into the database (this can occur multiple times per request).  The after_action_new trigger is only executed once after the &apos;new&apos; action has been successfully completed.  i.e. a maximum of once per request.

===Signature===

&lt;code&gt;
function after_action_new($params=array()){ ... } : return void
&lt;/code&gt;

====Parameters====

This method takes a single associative array as a parameter. This array includes the following keys:

* &apos;&apos;&apos;record&apos;&apos;&apos; - The [http://dataface.weblite.ca/Dataface_Record Dataface_Record] object that was just inserted.


===Examples===

====Example 1: Redirect to the view tab for the inserted record====

&lt;code&gt;
function after_action_new($params=array()){
    $record =&amp; $params[&apos;record&apos;];
    header(&apos;Location: &apos;.$record-&gt;getURL(&apos;-action=view&apos;).&apos;&amp;--msg=&apos;.urlencode(&apos;Record successfully inserted.&apos;));
    exit;
}
&lt;/code&gt;
</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=13">
	<page_name>beforeRegister</page_name>
	<page_id>13</page_id>
	<page_title>beforeRegister</page_title>
	<content>==beforeRegister() Trigger==

A trigger that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]], to be executed before the registration form is saved.  This can be used to perform some custom actions like emailing the administrator.

===Signature===

function beforeRegister( Dataface_Record &amp;$record ) : mixed

====Parameters====

{| class=&quot;listing listing2&quot;
! Name
! Description
|-
| &amp;$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {
    function beforeRegister(&amp;$record){
        // mail the admin to let him know that the registration is occurring.
        mail(&apos;admin@example.com&apos;, &apos;New registration&apos;, &apos;A new user &apos;.$record-&gt;val(&apos;username&apos;).&apos; has registered);
    }
}
&lt;/code&gt;

===See Also===

* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=55">
	<page_name>blob</page_name>
	<page_id>55</page_id>
	<page_title>blob</page_title>
	<content></content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=11">
	<page_name>block__blockname</page_name>
	<page_id>11</page_id>
	<page_title>block__blockname</page_title>
	<content>===Available Blocks===

This is a grep to show the blocks that are defined in Xataface templates:

* Dataface_ActionsMenu.html:actions_menu_head
* Dataface_ActionsMenu.html:actions_menu_tail
* Dataface_Add_Existing_Related_Record.html:before_add_existing_related_record_form
* Dataface_Add_Existing_Related_Record.html:before_add_existing_related_`$ENV.relationship`_form
* Dataface_Add_Existing_Related_Record.html:after_add_existing_related_`$ENV.relationship`_form
* Dataface_Add_Existing_Related_Record.html:after_add_existing_related_record_form
* Dataface_Add_New_Related_Record.html:before_add_new_related_record_form
* Dataface_Add_New_Related_Record.html:before_add_new_related_`$ENV.relationship`_form
* Dataface_Add_New_Related_Record.html:after_add_new_related_`$ENV.relationship`_form
* Dataface_Add_New_Related_Record.html:after_add_new_related_record_form
* Dataface_AjaxEventDetails.html:before_event_details
* Dataface_AjaxEventDetails.html:after_event_details
* Dataface_Delete_Record.html:before_delete_record_form
* Dataface_Delete_Record.html:after_delete_record_form
* Dataface_Edit_Record.html:before_edit_record_form
* Dataface_Edit_Record.html:after_edit_record_form
* Dataface_FindForm.html:findform_before_`$element.field.name`_row
* Dataface_FindForm.html:findform_before_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_row
* Dataface_FindForm.html:before_findform_table
* Dataface_FindForm.html:findform_before_`$element.field.name`_row
* Dataface_FindForm.html:findform_before_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_widget
* Dataface_FindForm.html:findform_after_`$element.field.name`_row
* Dataface_FindForm.html:after_findform_table
* Dataface_Find_View.html:before_find_form
* Dataface_Find_View.html:after_find_form
* Dataface_Form_Section_Template.html:before_quickform_table
* Dataface_Import_RelatedRecords.html:before_import_related_records_form
* Dataface_Import_RelatedRecords.html:before_import_related_`$ENV.relationship`_form
* Dataface_Import_RelatedRecords.html:after_import_related_`$ENV.relationship`_form
* Dataface_Import_RelatedRecords.html:after_import_related_records_form
* Dataface_List_View.html:before_result_list
* Dataface_List_View.html:after_result_list
* Dataface_Login_Prompt.html:before_login_form
* Dataface_Login_Prompt.html:after_login_form
* Dataface_Main_Template.html:custom_stylesheets2
* Dataface_Main_Template.html:head
* Dataface_Main_Template.html:body_atts
* Dataface_Main_Template.html:before_body
* Dataface_Main_Template.html:before_header
* Dataface_Main_Template.html:after_header
* Dataface_Main_Template.html:before_search
* Dataface_Main_Template.html:after_search_form_submit
* Dataface_Main_Template.html:after_search
* Dataface_Main_Template.html:before_nav_menu
* Dataface_Main_Template.html:after_nav_menu
* Dataface_Main_Template.html:before_language_selector
* Dataface_Main_Template.html:after_language_selector
* Dataface_Main_Template.html:before_user_status_logged_in
* Dataface_Main_Template.html:after_user_status_logged_in
* Dataface_Main_Template.html:before_user_status_not_logged_in
* Dataface_Main_Template.html:after_user_status_not_logged_in
* Dataface_Main_Template.html:before_personal_tools
* Dataface_Main_Template.html:after_personal_tools
* Dataface_Main_Template.html:before_bread_crumbs
* Dataface_Main_Template.html:after_bread_crumbs
* Dataface_Main_Template.html:before_main_table
* Dataface_Main_Template.html:before_left_column
* Dataface_Main_Template.html:before_record_tree
* Dataface_Main_Template.html:after_record_tree
* Dataface_Main_Template.html:before_nav_menu
* Dataface_Main_Template.html:after_nav_menu
* Dataface_Main_Template.html:before_application_menu
* Dataface_Main_Template.html:after_application_menu
* Dataface_Main_Template.html:after_left_column
* Dataface_Main_Template.html:before_main_column
* Dataface_Main_Template.html:before_message
* Dataface_Main_Template.html:message
* Dataface_Main_Template.html:after_message
* Dataface_Main_Template.html:before_errors
* Dataface_Main_Template.html:error
* Dataface_Main_Template.html:after_errors
* Dataface_Main_Template.html:before_table_tabs
* Dataface_Main_Template.html:before_menus
* Dataface_Main_Template.html:after_menus
* Dataface_Main_Template.html:before_main_section
* Dataface_Main_Template.html:before_recently_viewed
* Dataface_Main_Template.html:after_recently_viewed
* Dataface_Main_Template.html:before_record_content
* Dataface_Main_Template.html:after_record_content
* Dataface_Main_Template.html:after_main_section
* Dataface_Main_Template.html:before_fineprint
* Dataface_Main_Template.html:after_fineprint
* Dataface_Main_Template.html:before_global_footer
* Dataface_Main_Template.html:after_global_footer
* Dataface_Main_Template.html:before_main_section
* Dataface_Main_Template.html:before_recently_viewed
* Dataface_Main_Template.html:after_recently_viewed
* Dataface_Main_Template.html:before_record_content
* Dataface_Main_Template.html:after_record_content
* Dataface_Main_Template.html:after_main_section
* Dataface_NavMenu.html:tables_menu_head
* Dataface_NavMenu.html:tables_menu_tail
* Dataface_NavMenu.html:tables_menu_head
* Dataface_NavMenu.html:tables_menu_tail
* Dataface_New_Record.html:before_new_record_form
* Dataface_New_Record.html:after_new_record_form
* Dataface_Record_Template.html:before_details_controller
* Dataface_Record_Template.html:after_details_controller
* Dataface_Record_Template.html:before_record_heading
* Dataface_Record_Template.html:after_record_heading
* Dataface_Record_Template.html:before_record_tabs
* Dataface_Record_Template.html:before_record_content
* Dataface_Record_Template.html:after_record_content
* Dataface_Record_Template.html:before_record_footer
* Dataface_Record_Template.html:after_record_footer
* Dataface_Registration.html:before_registration_form
* Dataface_Registration.html:after_registration_form
* Dataface_Related_Records_List.html:before_related_`$ENV.relationship`_records_list
* Dataface_Related_Records_List.html:after_related_`$ENV.relationship`_records_list
* Dataface_Remove_Related_Record.html:before_remove_related_record_form
* Dataface_Remove_Related_Record.html:before_remove_related_`$ENV.relationship`_record_form
* Dataface_Remove_Related_Record.html:after_remove_related_`$ENV.relationship`_record_form
* Dataface_Remove_Related_Record.html:after_remove_related_record_form
* Dataface_View_Record.html:before_view_tab_content
* Dataface_View_Record.html:before_record_actions
* Dataface_View_Record.html:after_record_actions
* Dataface_View_Record.html:after_view_tab_content
* Dataface_related_records_checkboxes.html:before_related_`$ENV.relationship`_records_checkboxes
* Dataface_related_records_checkboxes.html:before_related_records_checkboxes
* Dataface_related_records_checkboxes.html:after_related_records_checkboxes
* Dataface_related_records_checkboxes.html:after_related_`$ENV.relationship`_records_checkboxes
* Dataface_set_translation_status.html:before_details_controller
* Dataface_set_translation_status.html:after_details_controller

===Available Slots===

* Dataface_ActionsMenu.html:actions_menu
* Dataface_Add_Existing_Related_Record.html:add_existing_related_`$ENV.relationship`_form
* Dataface_Add_Existing_Related_Record.html:add_existing_related_record_form
* Dataface_Add_New_Related_Record.html:add_new_related_`$ENV.relationship`_form
* Dataface_Add_New_Related_Record.html:add_new_related_record_form
* Dataface_AjaxEventDetails.html:event_details
* Dataface_Delete_Record.html:delete_record_form
* Dataface_Edit_Record.html:edit_record_form
* Dataface_FindForm.html:findform_`$element.field.name`_row
* Dataface_FindForm.html:findform_`$element.field.name`_widget
* Dataface_FindForm.html:findform_`$element.field.name`_row
* Dataface_FindForm.html:findform_`$element.field.name`_widget
* Dataface_Find_View.html:find_form
* Dataface_Import_RelatedRecords.html:import_related_`$ENV.relationship`_form
* Dataface_Import_RelatedRecords.html:import_related_records_form
* Dataface_List_View.html:result_list
* Dataface_List_View_summary.html:result_list
* Dataface_Login_Prompt.html:login_form
* Dataface_Main_Template.html:doctype_tag
* Dataface_Main_Template.html:html_tag
* Dataface_Main_Template.html:html_head
* Dataface_Main_Template.html:html_title
* Dataface_Main_Template.html:dataface_stylesheets
* Dataface_Main_Template.html:custom_stylesheets
* Dataface_Main_Template.html:dataface_javascripts
* Dataface_Main_Template.html:custom_javascripts
* Dataface_Main_Template.html:head_slot
* Dataface_Main_Template.html:html_body
* Dataface_Main_Template.html:global_header
* Dataface_Main_Template.html:search_form
* Dataface_Main_Template.html:language_selector
* Dataface_Main_Template.html:user_status_logged_in
* Dataface_Main_Template.html:user_status_not_logged_in
* Dataface_Main_Template.html:personal_tools
* Dataface_Main_Template.html:bread_crumbs
* Dataface_Main_Template.html:main_table
* Dataface_Main_Template.html:left_column
* Dataface_Main_Template.html:application_menu
* Dataface_Main_Template.html:main_column
* Dataface_Main_Template.html:table_tabs
* Dataface_Main_Template.html:menus
* Dataface_Main_Template.html:main_section
* Dataface_Main_Template.html:record_content
* Dataface_Main_Template.html:fineprint
* Dataface_Main_Template.html:global_footer
* Dataface_Main_Template.html:main_section
* Dataface_Main_Template.html:record_content
* Dataface_Main_Templateold.html:doctype_tag
* Dataface_Main_Templateold.html:html_tag
* Dataface_Main_Templateold.html:html_head
* Dataface_Main_Templateold.html:html_title
* Dataface_Main_Templateold.html:dataface_stylesheets
* Dataface_Main_Templateold.html:custom_stylesheets
* Dataface_Main_Templateold.html:dataface_javascripts
* Dataface_Main_Templateold.html:custom_javascripts
* Dataface_Main_Templateold.html:head_slot
* Dataface_Main_Templateold.html:html_body
* Dataface_Main_Templateold.html:global_header
* Dataface_Main_Templateold.html:search_form
* Dataface_Main_Templateold.html:language_selector
* Dataface_Main_Templateold.html:user_status_logged_in
* Dataface_Main_Templateold.html:user_status_not_logged_in
* Dataface_Main_Templateold.html:personal_tools
* Dataface_Main_Templateold.html:bread_crumbs
* Dataface_Main_Templateold.html:main_table
* Dataface_Main_Templateold.html:left_column
* Dataface_Main_Templateold.html:application_menu
* Dataface_Main_Templateold.html:main_column
* Dataface_Main_Templateold.html:table_tabs
* Dataface_Main_Templateold.html:menus
* Dataface_Main_Templateold.html:main_section
* Dataface_Main_Templateold.html:record_content
* Dataface_Main_Templateold.html:fineprint
* Dataface_Main_Templateold.html:global_footer
* Dataface_Main_Templateold.html:main_section
* Dataface_Main_Templateold.html:record_content
* Dataface_NavMenu.html:tables_menu_options
* Dataface_NavMenu.html:tables_menu_options
* Dataface_New_Record.html:new_record_form
* Dataface_Record_Template.html:record_heading
* Dataface_Record_Template.html:record_content
* Dataface_Record_Template.html:record_footer
* Dataface_Registration.html:registration_form
* Dataface_Related_Records_List.html:before_related_list
* Dataface_Related_Records_List.html:related_`$ENV.relationship`_records_list
* Dataface_Related_Records_List.html:related_records_list
* Dataface_Related_Records_List.html:after_related_list
* Dataface_Remove_Related_Record.html:remove_related_`$ENV.relationship`_record_form
* Dataface_Remove_Related_Record.html:remove_related_record_form
* Dataface_View_Record.html:view_tab_content
* Dataface_View_Record.html:record_actions
* Dataface_View_Record.html:record_search
* Dataface_View_Record.html:`$section.name`_section_content
* Dataface_View_Record.html:record_view_main_section
* Dataface_View_Record.html:`$section.name`_section_content
* Dataface_related_records_checkboxes.html:related_`$ENV.relationship`_records_checkbox_form
* Dataface_related_records_checkboxes.html:related_records_checkbox_form
* global_header.html:site_logo

</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=43">
	<page_name>Calendar_Action</page_name>
	<page_id>43</page_id>
	<page_title>Calendar_Action</page_title>
	<content>==Calendar Action==

[[toc]]

Xataface 1.0 includes a built-in calendar action that is disabled by default.  If enabled, it allows you to view the records in any found set as a calendar of events, as follows:

&lt;nowiki&gt;
&lt;div style=&quot;text-align:center;border: 1px solid #ccc; padding: 10px&quot;&gt;
&lt;img src=&quot;http://media.weblite.ca/files/photos/Picture -4.png?max_width=500&quot;
onmouseover=&quot;this.src=&apos;http://media.weblite.ca/files/photos/Picture -4.png&apos;;&quot;
onmouseout=&quot;this.src=&apos;http://media.weblite.ca/files/photos/Picture -4.png?max_width=500&apos;;&quot;/&gt;
&lt;/div&gt;
&lt;/nowiki&gt;

===Features===

* Monthly display
* Hourly schedule for any day by clicking on it.
* Show record details instantly by clicking on it in the calendar.
* Recognizes dates, start and end times for records when interpreted as calendar events.
* Respects searches (i.e. you can filter the records and the calendar will only show those records in the found set).

===Requirements===

Your table records should contain at least dates in order for them to be interpreted as events that can be placed in a calendar.

===Setting up the Calendar===

Suppose I have a table called &apos;&apos;Lessons&apos;&apos; that stores information about scheduled music lessons.  If I want to add the calendar to this table, then I would add an &apos;&apos;[[actions.ini file]]&apos;&apos; to the &apos;&apos;tables/Lessons&apos;&apos; directory with the following contents:&lt;code&gt;
[calendar &gt; calendar]
    condition=&quot;true&quot;
&lt;/code&gt;
This overrides the calendar action which is disabled by default, and enables it for the &apos;&apos;Lessons&apos;&apos; table.

Next I need to inform Xataface which fields store the event dates and times so that the records can be laid out in the calendar appropriately.  (Note that if you skip this step, Xataface will make a best guess based on column types and names - but it is better to specify these explicitly).

In the &apos;&apos;Lessons&apos;&apos; table I have the following fields that are relevant here:

* &apos;&apos;lesson_date&apos;&apos; - A date field containing the date and start time of the event.
* &apos;&apos;start_time&apos;&apos; - A time field with the start time of the lesson.

We can tell Xataface to treat these fields accordingly by adding the following directives to the appropriate field sections of the [[fields.ini file]] for the &apos;&apos;Lessons&apos;&apos; table:

* &apos;&apos;event.date=1&apos;&apos; - Specifies that the field stores the date of the event.
* &apos;&apos;event.start=1&apos;&apos; - Specifies that the field stores the start time of the event.

So in our case we&apos;ll modify the [[fields.ini file]] as follows:

&lt;code&gt;
[lesson_date]
    event.date=1

[start_time]
    event.start=1
&lt;/code&gt;

Now if we load up our application, we should now see a &apos;&apos;calendar&apos;&apos; tab along side &apos;&apos;list&apos;&apos;, &apos;&apos;details&apos;&apos;, and &apos;&apos;find&apos;&apos; for the &apos;&apos;Lessons&apos;&apos; table.  Click on this tab to see your records displayed in a calendar.

===Using a datetime field to store both date and start time===

You can also use a single field to store both the date and start time for an event.  In this case you just provide the &apos;&apos;event.date&apos;&apos; and &apos;&apos;event.start&apos;&apos; directives for the same field.  For example if the &apos;&apos;lesson_date&apos;&apos; was a datetime field that marked the date and time of the lesson, we would modify our [[fields.ini]] file as follows:

&lt;code&gt;
[lesson_date]
    event.date=1
    event.start=1
&lt;/code&gt;

===Available Fields===

The Calendar action will look for the following pieces of information in your records:

{| class=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| event.date
| Indicates that the field contains the date of the event.
| 1.0
|-
| event.start
| Indicates that the field contains the start time of the event.
| 1.0
|-
| event.end
| Indicates that the field contains the end time of the event.
| 1.0
|-
| event.location
| Indicates that the field contains the location of the event.
| 1.0
|-
| event.category
| Indicates that the field contains the category of the event.
| 1.0
|}</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=69">
	<page_name>checkbox</page_name>
	<page_id>69</page_id>
	<page_title>checkbox</page_title>
	<content>==The checkbox widget==

In the [[fields.ini file]] you can specify a field to be edited using a checkbox widget by setting [[widget:type]] to [[checkbox]].  A checkbox widget can function in 2 different ways depending on the parameters that you assign to the field.

[[toc]]

===Example 1: A TinyInt (boolean) field===

Suppose our table has a tinyint field named &quot;Active&quot; which specifies whether the record is currently in use.  This field will store a value of either 0 or 1.  So we configure this field in our [[fields.ini]] file to use a checkbox widget as follows:

&lt;code&gt;
[Active]
  widget:type=checkbox
&lt;/code&gt;

Results:

[[Image:http://media.weblite.ca/files/photos/Picture%2024.png?max_width=640]]

===Example 2: A repeating field (multiple checkboxes for one field===

Checkboxes can store multiple values in a single field by setting the [[vocabulary]] directive and applying it to a varchar or text field.  In this case there will be one value saved per line.  

In this example, suppose we have a varchar field named &apos;&apos;&apos;categories&apos;&apos;&apos; which uses the &apos;&apos;&apos;categories&apos;&apos;&apos; [[valuelist]] to specify the different categories that can be checked at any given time.  Our [[valuelists.ini file]] might look like:
&lt;code&gt;
[categories]
    __sql__ = &quot;select id,name from categories&quot;
&lt;/code&gt;

And our [[fields.ini file]] looks like:
&lt;code&gt;
[categories]
    widget:type=checkbox
    vocabulary=categories
&lt;/code&gt;
* Note that you don&apos;t need to name the field the same as the valuelist.  It just worked out this way.

Now if we save a record with categories 1, 3, and 5 checked, then the categories column of our row in the database will store something like:
&lt;code&gt;
1
3
5
&lt;/code&gt;
i.e. one category id per line.  Note that using this method, your database will not be normalized because you are storing multiple values in a single field.  However in many applications this is sufficient.

Results:

[[Image:http://media.weblite.ca/files/photos/Picture%2025.png?max_width=640]]

===Example 3: Using a &quot;Categories&quot; relationship===

&quot;&quot;&quot;(Note: This example requires Xataface version 1.2 or higher)&quot;&quot;&quot;

Example 2 above shows how we can easily add and remove a record from multiple categories using checkboxes.  However it required multiple pieces of information to be stored in a single database field which may or may not be advantageous for your database design.  If you&apos;re looking for a more normalized database schema you would probably design your database as follows for this case:

# Books table - Stores all of the books.
# Categories table - Stores all of the categories
# Book_Categories table - Stores mapping of books to categories.

With out table structure we will first want to define a relationship from Books to Categories to reflect the connection between books and categories.  The [[relationships.ini file]] for this might look like:

&lt;code&gt;
[categories]
    Books.Book_ID=&quot;$Book_ID&quot;
    Book_Categories.Category_ID=Categories.Category_ID
&lt;/code&gt;

And our [[fields.ini file]] for the Books table might look like:
&lt;code&gt;
[categories]
    widget:type=checkbox
    transient=1
    relationship=categories
&lt;/code&gt;
* Note that there is no need for our field to be named the same as our relationship.  It just turned out this way.  Also note that we used the transient=1 flag here because the Books table no longer has a categories field in the database.  This field is defined purely for the benefit of the edit form so that we will get a checkbox group to select the book&apos;s categories.

Results:
[[Image:http://media.weblite.ca/files/photos/Picture%2025.png?max_width=640]]

==Related Parameters==

# [[vocabulary]] - Assigns a valuelist to be used as the options for this checkbox group.
# [[repeat]] - A boolean value indicating whether this field should be treated as a &apos;repeating field&apos;.  A repeating field is one with multiple checkboxes.  By default the checkbox widget operates as a single checkbox that controls a boolean value.
# [[relationship]] - (Only applicable to [[transient]] fields).  If the [[relationship]] directive is set then this field can be used to add/remove records from a relationship.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=178">
	<page_name>Clean_the_html_for_the_export</page_name>
	<page_id>178</page_id>
	<page_title>Clean the HTML to export data</page_title>
	<content>==Clean HTML tags and entities to export your data==
#Override the display() of the field to strip the tags... but this would affect all parts of the application where the HTML fields are displayed.
#Create a grafted field, then override its display to show the stripped contents of the HTML area field.

e.g. in the fields.ini:

&lt;code&gt; 
    __sql__ = &quot;select t.*, null as stripped_field from mytable t&quot;
    [original_field]
       widget:type=htmlarea
       visibility:csv=hidden

    [stripped_field]
        visibility:csv = visible
        visibility:list=hidden
        visibility:browse=hidden
        visibility:find=hidden

&lt;/code&gt; 


Then in the delegate class:


&lt;code&gt; 
    function stripped_field__display($record){
        return html_entity_decode(strip_tags($record-&gt;val(&apos;original_field&apos;)), ENT_QUOTES, &apos;UTF-8&apos;);
    }
&lt;/code&gt; </content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=182">
	<page_name>column:legend</page_name>
	<page_id>182</page_id>
	<page_title></page_title>
	<content></content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=25">
	<page_name>conf.ini_file</page_name>
	<page_id>25</page_id>
	<page_title>conf.ini_file</page_title>
	<content>==conf.ini File==

[[toc]]

The conf.ini file is where most of the application-level configuration information is stored for a Xataface application.  It contains information such as:

* database connection information
* which tables should appear in the tables menu.
* [[preferences|preference settings]]
* [[authentication]] settings
* which add-on [[modules]] are to be used
* output caching settings
* history/undo settings
* other misc settings.

Every conf.ini file must contain at least the following sections:


{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| _database
| Contains database connection info.
| all
|-
| _tables
| Contains a list of tables that are to be included in the navigation menu of the application.
| all
|}


The following optional sections may also be included:

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Version
|-
| [http://xataface.com/documentation/how-to/disallow_tables _allowed_tables]
| Specifies tables that should be explicitly allowed to override disallowed tables listed or matched in the [http://xataface.com/documentation/how-to/disallow_tables _disallowed_tables] section.
| 0.7
|-
| [[_auth]]
| Contains information about [[authentication]].
| 0.6
|-
| [http://xataface.com/documentation/how-to/disallow_tables _disallowed_tables]
| A list of tables or patterns that match tables that should be blocked from being accessed directly through the application.  By default any table beginning with an underscore, &apos;dataface_&apos;, or ending in &apos;__history&apos; are blocked.  This prevents unintended access to some of the automatically created tables in Xataface.
| 0.7
|-
| _feed
| Configuration options for [[Introduction_to_RSS_Feeds_in_Xataface|RSS feeds]] that are generated by the application.
| 1.0
|-
| _history
| Settings pertaining to the [http://xataface.com/documentation/how-to/history-howto history feature] (e.g. whether it has been enabled).
| 0.7
|-
| _index
| Settings for the full site search indexing.
| 1.0
|-
| _modules
| A list of [[modules]] that are enabled for this application.
| 1.0
|-
| [[_output_cache]]
| Output cache settings.  Using output caching can dramatically improve performance for busier sites.
| 0.8
|-
| _themes
| A list of the themes that are to be applied to the application.
| 0.8
|}

===Stand-alone Attributes===

Stand-alone attributes for an INI file must appear at the beginning of the INI file (before any of the sections).  The conf.ini may contain the following stand-alone attributes.

{| class=&quot;listing listing2&quot;
|-
! Name
! Description
! Values
! Version
|-
| cache_queries
| Enables query caching.  Enabling this feature can yield drastic performance improvements especially on busy sites with large databases.
| boolean (0 or 1)
| 1.2

|-
| cache_queries_log
| Enables logging of query caching to the file /tmp/querylog.log so that you can tell whether your queries are being cached, and which ones are being cached.
| boolean (0 or 1)
| 1.2

|-
| default_action
| The default action to be performed if it is not explicitly specified in the query (e.g. &apos;list&apos;, &apos;find&apos;, &apos;edit&apos;).  Default is &apos;list&apos;.
| string
| 0.6
|-
| debug
| If this is set to 1, then the application will run in debug mode which displays the available slots and blocks on the screen, along with some other debug information.
| 0 or 1 (default is 0)
| 0.6

|-
| default_browse_action
| The default action to perform in the details tab.  E.g. When you click on the &quot;details&quot; tab there are a number of sub-tabs including &apos;view&apos;, &apos;edit&apos;, etc... .   The default value for this directive is &apos;view&apos;.  If you want to go directly to the edit form when clicking on a record in list view, you would set &apos;&apos;default_browse_action&apos;&apos; to &apos;edit&apos;.
| string
| 0.6
|-
| default_language
| The default language to use.  This is the 2-digit ISO language code.  If this value is not specified it defaults to the first language listed in the &apos;&apos;[languages]&apos;&apos; section.
| string (2-digit ISO language code)
| 0.6
|-
| default_limit
| The default limit (i.e. the number of records to show per page) if none is explicitly specified in the query.  Default is 30.
| int
| 0.6
|-
| default_table
| The default table to show if none is specified by the query.  If you do not define this value, then the first table in the &apos;&apos;[_tables]&apos;&apos; section is used.
| string
|0.6
|-
| disable_session_ip_check
| Default behaviour automatically tracks the IP address of the user when they log in.  If a request is made for a session from a different IP then the session is automatically destroyed and the user is logged out.
| boolean
| 1.3rc4

|-
| title
| A title for the application (appears in the browser title bar).
| string
| 0.6
|-
| usage_mode
| The usage mode of the application.  If this value is set to &apos;&apos;edit&apos;&apos;, then ajax inline editing is enabled (i.e. you can click on any value in the application to edit it inline.
| &apos;view&apos; or &apos;edit&apos;
| 0.6
|}

===Example 1: A simple conf.ini file===

&lt;code&gt;
[_database]
	host=&quot;localhost&quot;
	name=&quot;mydb&quot;
	user=&quot;mydbuser&quot;
	password=&quot;foo&quot;
	
[_tables]
webpage_sites=&quot;Websites&quot;
translations = &quot;Translations&quot;
packages=&quot;Packages&quot;
users=Users
proof_jobs=&quot;Jobs&quot;
webpage_status=&quot;Webpages Status&quot;

&lt;/code&gt;

===Example 2: A more complex conf.ini file===

&lt;code&gt;
;debug=1
;default_action=home
;google_translate_url=&quot;http://weblite-dns2.com/proxy.php&quot;
google_translate_url=&quot;http://ec2-75-101-244-123.compute-1.amazonaws.com/proxy.php&quot;
title=&quot;Web Lite Translate&quot;
default_price_per_word=0.15

;;Configuration settings for application
title=&quot;translation_weblite_ca&quot;
scriptUrl=&quot;http://translation.weblite.ca/index.php&quot;
multilingual_content=1


[_database]
	host=&quot;localhost&quot;
	name=&quot;mydb&quot;
	user=&quot;mydbuser&quot;
	password=&quot;foo&quot;
	
[_tables]
    webpage_sites=&quot;Websites&quot;
    translations = &quot;Translations&quot;
    packages=&quot;Packages&quot;
    users=Users
    proof_jobs=&quot;Jobs&quot;
    webpage_status=&quot;Webpages Status&quot;


[_auth]
	users_table=users
	username_column=username
	password_column=password
	secret_code=&quot;ljkasdfjkldsafliasdoiudsfoi&quot;
	allow_register=1
	session_timeout=999999999
	
[_modules]
	modules_ShoppingCart=&quot;modules/ShoppingCart/ShoppingCart.php&quot;

[ShoppingCart_taxes]
	;; This section is necessary to declare that we have NO taxes.
	
[metatags]
	keywords = &quot;translation, translate&quot;
	description = &quot;Good translation service&quot;
	
;[_output_cache]
;	enabled=1

[_mail]
	func=mail2
	
&lt;/code&gt;

</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=82">
	<page_name>Creating_Printable_Reports</page_name>
	<page_id>82</page_id>
	<page_title>Creating a Custom Printable Report</page_title>
	<content>==Creating a Printable Report==

[[toc]]

It is often useful to provide your users with a printable report that is generated from your database.  Although Xataface doesn&apos;t include an explicit reporting module to allow the end users to create their own reports, you (the developer) can still quite easily produce a report by creating a custom action.  

This report will be subject to the user&apos;s sorting and searching preferences.  E.g. if the user searches for only books about &quot;frogs&quot;, then when he clicks on your printable report it will only display those records that match the query (i.e. only books about frogs).

===Requirements for our report===

# Report will be run against the &quot;products&quot; table (using the WebAuction application).
# Report should be accessible by clicking an icon in the top right of the list view (i.e. the resultlist actions).
# Report should display the product ID, product name, photo, and description.  One product per page.


===Adding the Icon to our Application===

We&apos;ll start out by finding an appropriate icon to use for our action.  There are loads of free icons that you can download (please observe and respect the license agreement of any icon library that you use).  Two good free icon libraries include:

# [http://www.famfamfam.com/lab/icons/silk/ FamFamFam Silk Icons]
# [http://tango.freedesktop.org/Tango_Icon_Library Tango Icon Library]

Once you have found the icon you want to use, just upload it somewhere inside your application&apos;s directory.  It might be a good idea to create a directory to store your images if you haven&apos;t already.  An appropriate name might by &apos;&apos;images&apos;&apos;.  For this example, we&apos;ll use the [[Image:http://dev.weblite.ca/phpimageserver/photos/icons/printer.png]] icon from the FamFamFam icon library.  So we upload this icon to
 %APPLICATION_PATH%/images/printer.png

Next we need to create an entry in our application&apos;s [[actions.ini file]] so that Xataface knows about our action, and where we want its icon to be displayed.  We&apos;ll start out with a basic definition that just specifies the icon for the action, and the &apos;&apos;category&apos;&apos; of the action.

&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
&lt;/code&gt;

The &apos;&apos;result_list_actions&apos;&apos; category setting means that the icon for our action will be included along with the result list actions, which are located in the top right corner in the list tab.  Now if we reload our application and look at the &quot;list&quot; tab, you&apos;ll see that the icon group in the top right now includes our icon:

[[Image:http://media.weblite.ca/files/photos/Picture%20-5.png?max_width=640]]

If you don&apos;t see this icon, but see the text &quot;printable_report&quot; instead, then you have entered an incorrect path to the icon in the &apos;&apos;icon&apos;&apos; directive.  If you don&apos;t see an icon at all or any text, then your &apos;&apos;category&apos;&apos; directive may be incorrect.  Check that it is exactly &quot;result_list_actions&quot;.

If you mouse over your icon you&apos;ll see the text that you specified as your &apos;&apos;description&apos;&apos; directive for the action:

[[Image:http://media.weblite.ca/files/photos/Picture%20-6.png?max_width=640]]

You&apos;ll notice, if you try to click on your icon, that nothing happens.  This is because we haven&apos;t yet specified a URL for your action.  We&apos;ll wait to specify our URL, until we&apos;ve built the back-end of our action (i.e. the actual report).

===Creating the Actual Report===

Most reports involve the following pieces:

# Fetch the found set of records from the database.
# Loop through the found set and output some information about each record.
# Optionally use a template to integrate the report into your application&apos;s look and feel.

All reports will be placed in the framework of a custom Xataface action.  In our case we add a file to our application &apos;&apos;actions&apos;&apos; directory named after our action:
 %APPLICATION_PATH%/actions/printable_report.php

with the following contents:

&lt;code&gt;
&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	echo &quot;Hello world!!!&quot;;
    }
}
&lt;/code&gt;

Please note the following about this snippet:

# The action was placed in a file &apos;&apos;actions/printable_report.php&apos;&apos; because the action is named &apos;&apos;printable_report&apos;&apos; (referring to our definition in the &apos;&apos;[[actions.ini file]]&apos;&apos;.  If the action was named &apos;&apos;foo&apos;&apos;, then we would place our action in file &apos;&apos;actions/foo.php&apos;&apos;.
# The &apos;&apos;printable_report.php&apos;&apos; file contains a single class named &apos;&apos;actions_printable_report&apos;&apos; after the name of the action.
# The action class contains a single method &apos;&apos;handle&apos;&apos; which handles the request for the action (i.e. outputs the report the way we like).  This method must exist and me named exactly &apos;&apos;handle&apos;&apos;.
# The &apos;&apos;handle&apos;&apos; method takes a single &apos;&apos;&amp;$params&apos;&apos; parameter which contains some parameters that may be passed to the action.  We won&apos;t be dealing with these in this example.


Before proceeding, let&apos;s try accessing our action just to make sure that we&apos;re on the right track.  Point your browser to 
 http://example.com/yourapplication/index.php?-action=printable_report

Note that you don&apos;t point our web browser directly to your action php file (in the &apos;&apos;actions&apos;&apos; directory.  Rather you point it to your application&apos;s entry point (index.php file), and specify the action via the &apos;&apos;-action&apos;&apos; GET parameter.  Your web browser should display something like:

[[Image:http://media.weblite.ca/files/photos/Picture%204.png?max_width=640]]

If you get a blank white screen, then you should check your error log to see where the error is occuring.  See [[Troubleshooting]] for general Xataface troubleshooting strategies in this case.

Now that we have all of the formalities out of the way, we can proceed to meat of our report.

====Retrieving the Found Set====

Let&apos;s build onto our action now.  First we will load the found set of records as follows:

&lt;code&gt;
&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	$app =&amp; Dataface_Application::getInstance();
    	$query =&amp; $app-&gt;getQuery();
    	
    	if ( $query[&apos;-table&apos;] != &apos;products&apos; ){
    		return PEAR::raiseError(&apos;This action can only be called on the Products table.&apos;);
    	}
    	
    	$products = df_get_records_array(&apos;products&apos;, $query);
    	
    }
}
&lt;/code&gt;

Things to note in this snippet:

# We start be loading a reference to the &apos;&apos;Dataface_Application&apos;&apos; object.
# We then use the &apos;&apos;Dataface_Application&apos;&apos; object to load the current query.  This is essentially an associative array of all of the GET parameters, but with some guaranteed attributes such as &apos;&apos;-table&apos;&apos; and &apos;&apos;-action&apos;&apos;.
# In our particular action we are designing it to only work for the &apos;&apos;products&apos;&apos; table so we do a check on the query parameters to make sure that this is the case.  If someone tries to run this action from outside the products table (e.g. if -action=foo) then an error will be displayed.
# We use the df_get_records_array() function to return all matching records on the products table.  It returns an array of [[Dataface_Record]] objects.


====Overriding -skip and -limit====

Xataface allows the user to specify the number of records to display and the position in the found set to start from by adding the &apos;&apos;-skip&apos;&apos; and &apos;&apos;-limit&apos;&apos; GET parameters to a request.  If these are omitted, then default values of 0 and 30 are used respectively.  You may notice that if you click &quot;Next&quot; in list view, you see &apos;-skip&apos; and &apos;-limit&apos; parameters automatically added to the URL.

&apos;&apos;df_get_records_array&apos;&apos; respects the -limit and -skip parameters that are specified in the query.  I.e. if -skip and -limit are omitted it will return only the first 30 records from the found set.  If -skip=1 and -limit=10 then it will return 10 records starting from the 2nd record (2nd becuase -skip=0 would point to the first record).  This may be desired behavior for your report, but in some reports you may want to print off the entire found set.  If this is the case, you will want to explicitly set the -skip and -limit parameters in the &apos;&apos;$query&apos;&apos; array before passing it to &apos;&apos;df_get_records_array&apos;&apos;.  E.g.:

&lt;code&gt;
$query =&amp; $app-&gt;getQuery();
$query[&apos;-skip&apos;] = 0;
$query[&apos;-limit&apos;] = 10000;
$products = df_get_records_array(&apos;products&apos;, $query);
&lt;/code&gt;


====Looping through and Printing Product Info====

Now comes the fun part.  We&apos;re just going to loop through our found set and print off the product information:

&lt;code&gt;


foreach ($products as $p){
	

	echo &apos;&lt;table&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Product ID&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_id&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Product Name&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_name&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_description&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;tr&gt;&lt;th&gt;Photo&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_image&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
		.&apos;&lt;/table&gt;&apos;;
}

&lt;/code&gt;


The entire action at this point will look like:

&lt;code&gt;

&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	$app =&amp; Dataface_Application::getInstance();
    	$query =&amp; $app-&gt;getQuery();
    	$query[&apos;-skip&apos;] = 0;
		$query[&apos;-limit&apos;] = 10000;
		
    	if ( $query[&apos;-table&apos;] != &apos;products&apos; ){
    		return PEAR::raiseError(&apos;This action can only be called on the Products table.&apos;);
    	}
    	
    	$products = df_get_records_array(&apos;products&apos;, $query);
    	foreach ($products as $p){
	

			echo &apos;&lt;table&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product ID&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_id&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product Name&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_name&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_description&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Photo&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_image&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;/table&gt;&apos;;
		}
    	
    }
}
&lt;/code&gt;

Now we refresh our action in the web browser, or point the browser again to:
 http://example.com/yourapplication/index.php?-action=printable_report&amp;-table=products
 
It should display something like:

[[Image:http://media.weblite.ca/files/photos/Picture%205.png?max_width=640]]

If you get a blank white screen, please check out the [[Troubleshooting]] section for general Xataface troubleshooting strategies.

====Adding a Little Style====

It is a good idea to at least provide the proper HTML HEAD and BODY tags for your report.  And to help make things a little nicer looking we&apos;re going to add some CSS styles to:

# Make the table field labels vertically aligned to the top.
# Change the font to helvetica.

This is easy to do with simple echo statements:

&lt;code&gt;
echo &apos;&lt;html&gt;&lt;head&gt;&apos;
	.&apos;&lt;title&gt;Printable Report&lt;/title&gt;&apos;
	.&apos;&lt;style type=&quot;text/css&quot;&gt;&apos;
	.&apos;	th { vertical-align: top}&apos;
	.&apos;&lt;/style&gt;&apos;
	.&apos;&lt;/head&gt;&apos;
	.&apos;&lt;body&gt;&apos;;
	
	//...
	


&lt;/code&gt;

So our finished action looks like:


&lt;code&gt;
&lt;?php
class actions_printable_report {
    function handle(&amp;$params){
    	$app =&amp; Dataface_Application::getInstance();
    	$query =&amp; $app-&gt;getQuery();
    	$query[&apos;-skip&apos;] = 0;
		$query[&apos;-limit&apos;] = 10000;
		
    	if ( $query[&apos;-table&apos;] != &apos;products&apos; ){
    		return PEAR::raiseError(&apos;This action can only be called on the Products table.&apos;);
    	}
    	
    	$products = df_get_records_array(&apos;products&apos;, $query);
    	
    	
    	
    	echo &apos;&lt;html&gt;&lt;head&gt;&apos;
			.&apos;&lt;title&gt;Printable Report&lt;/title&gt;&apos;
			.&apos;&lt;style type=&quot;text/css&quot;&gt;&apos;
			.&apos;	th { vertical-align: top}&apos;
			.&apos;&lt;/style&gt;&apos;
			.&apos;&lt;/head&gt;&apos;
			.&apos;&lt;body&gt;&apos;;
    	foreach ($products as $p){
	

			echo &apos;&lt;table&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product ID&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_id&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Product Name&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_name&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Description&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_description&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;tr&gt;&lt;th&gt;Photo&lt;/th&gt;&lt;td&gt;&apos;.$p-&gt;htmlValue(&apos;product_image&apos;).&apos;&lt;/td&gt;&lt;/tr&gt;&apos;
				.&apos;&lt;/table&gt;&apos;;
		}
		
		echo &apos;&lt;/body&gt;&lt;/html&gt;&apos;;
    	
    }
}
&lt;/code&gt;



===Connecting the Icon to the Action===

FInally it is time to connect our Icon to our Action.  We do this by adding a &apos;&apos;url&apos;&apos; directive for the action in the &apos;&apos;[[actions.ini file]]&apos;&apos;:


&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
    url=&quot;{$app-&gt;url(&apos;-action=printable_report&apos;)}&quot;
&lt;/code&gt;

Explanation of the &apos;&apos;url&apos;&apos; directive in this snippet:

* The &apos;&apos;url&apos;&apos; method of the &apos;&apos;[[Dataface_Application]]&apos;&apos; object is used to generate a URL with the user&apos;s current query settings, but with the &apos;&apos;-action&apos;&apos; parameter set to &apos;&apos;printable_report&apos;&apos;.

Now if we reload our application, go to the list tab of the &apos;&apos;products&apos;&apos; table and click on our icon, it should take us to our action:

[[Image:http://media.weblite.ca/files/photos/Picture%207.png?max_width=640]]

===Trying out the action on different found sets with different sort orders===

One of the cool things about this action is that it is tied directly into the Xataface find settings so that th user is able to search for a subset of products and run our report on only those products that were found.  The user can also perform a sort on any column and this sort will be respected by our report.

===Hiding Icon from Other Tables===

Since our action is only intended to operate on the &apos;&apos;products&apos;&apos; table it probably isn&apos;t a good idea to make the icon visible for every other table.  For example, if you go to the list view of the &apos;&apos;users&apos;&apos; table, you&apos;ll see the printer icon in the top right just like it appears for the &apos;&apos;products&apos;&apos; table.  Clicking on it should display our error:

[[Image:http://media.weblite.ca/files/photos/Picture%206.png?max_width=640]]

We will use a &apos;&apos;condition&apos;&apos; directive for our action to hide it from tables other than the &apos;&apos;products&apos;&apos; table as follows:

 condition=&quot;$query[&apos;-table&apos;] == &apos;products&apos;&quot;
 
So our action will now look like:

&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
    url=&quot;{$app-&gt;url(&apos;-action=printable_report&apos;)}&quot;
    condition=&quot;$query[&apos;-table&apos;] == &apos;products&apos;&quot;
&lt;/code&gt;

Now if you reload the list for the &apos;&apos;users&apos;&apos; table you&apos;ll notice that the printer icon is now gone.  But returning to the &apos;&apos;products&apos;&apos; table shows our action still alive and well.

===Locking Down our Action with Permissions===

In our case we don&apos;t want our action to be accessible to all users.  Only administrators.  Xataface permissions and all its possibilities are beyond the scope of this tutorial, but we still want to demonstrate how to lock down this action.  The WebAuction application into which this action is being installed defines a permission called &apos;&apos;reports&apos;&apos; which only administrators have.  We will use this permission to limit access to this action as follows in the actions.ini file:
 permission=reports

So the actions.ini file will now look like:
&lt;code&gt;
[printable_report]
    icon=&quot;{$site_url}/images/printer.png&quot;
    category=result_list_actions
    description=&quot;See this product list in a printable format&quot;
    url=&quot;{$app-&gt;url(&apos;-action=printable_report&apos;)}&quot;
    condition=&quot;$query[&apos;-table&apos;] == &apos;products&apos;&quot;
    permission=reports
&lt;/code&gt;

Now only administrators will see our icon, and if non-administrators attempt to access out action by typing in its URL directly, they will receive an &quot;Access Denied&quot; message.

</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=62">
	<page_name>Customizing_the_look_and_feel_of_a_row_or_a_cell</page_name>
	<page_id>62</page_id>
	<page_title>Customizing_the_look_and_feel_of_a_row_or_a_cell</page_title>
	<content>==How to customize the look and feel of elements in the list view==

===Create a method in a delegate class===

In the delegate class, the method &apos;&apos;css__tableRowClass&apos;&apos; is implemented, like in this example :

&lt;code&gt;class tables_journal_interventions {
function css__tableRowClass(&amp;$record){
    if ( !$record-&gt;val(&apos;fermeture&apos;)){
        return &apos;intervention_close&apos;;
    }
    else return &apos;&apos;;
} 
}
&lt;/code&gt;

Here the function tests a condition : is there a value in the field &apos;&apos;fermeture&apos;&apos; ?

===Add the class in a CSS stylesheet===

Now the class is created in a CSS stylesheet.

&lt;code&gt;td.intervention_close {
        background-color: #FFE6E6 !important;
    } &lt;/code&gt;

This is a class for each cell, the &lt;td&gt; tag. The &apos;&apos;!important&apos;&apos;  attribute is added to be sure that this information has precedence over all the others. It is better to add this class in a [http://xataface.com/documentation/how-to/custom_javascripts custom CSS stylesheet].

===Remarks===

Beware that some versions of IE don&apos;t respect the background-color property on the &lt;tr&gt; tag, so it is probably better to write:

&lt;code&gt;

    tr.intervention_close td {
        background-color: #FFE6E6;
    }&lt;/code&gt;

i.e. to apply the background color to the individual cells. </content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=32">
	<page_name>DataGrid</page_name>
	<page_id>32</page_id>
	<page_title>DataGrid</page_title>
	<content>==Xataface DataGrid Module==

Created by Steve Hannah, [http://weblite.ca Web Lite Solutions Corp.]

===Synopsis===

The Xataface DataGrid module uses the Ext DataGrid component (http://extjs.com) to add an editable grid component to your Xataface application.

[[toc collapse=0]]

===Requirements===

* PHP 4.3+
* MySQL 4.1+
* Xataface 0.8+

===License===

This module is distributed with ExtJS 2.2, which is distributed under the GPL v 3 (http://extjs.com/products/license.php).

In order to be compatible with the ExtJS license, this module is also distributed under the terms of the GPL v3 (http://www.gnu.org/copyleft/gpl.html).

===Demo Video===

&lt;nowiki&gt;
&lt;embed src=&quot;http://media.weblite.ca/lib/flvplayer.swf&quot; width=&quot;640&quot; height=&quot;500&quot; bgcolor=&quot;#FFFFFF&quot; type=&quot;application/x-shockwave-flash&quot; pluginspage=&quot;http://www.macromedia.com/go/getflashplayer&quot; flashvars=&quot;file=http%3A%2F%2Fs3.amazonaws.com%2Fweblite_media%2FDataGrid-640x480.flv&amp;image=http%3A%2F%2Fmedia.weblite.ca%2Ffiles%2Fphotos%2FDataGrid-640x480.flv.jpg&amp;showdigits=true&amp;autostart=false&quot; /&gt;
&lt;/nowiki&gt;

===Screenshots===

Click on image to enlarge

&lt;nowiki&gt;
&lt;script language=&quot;javascript&quot; type=&quot;text/javascript&quot; src=&quot;http://media.weblite.ca/index.php?-action=gallery&amp;-table=files&amp;categories=8&amp;-cursor=0&amp;-skip=0&amp;-limit=30&amp;-mode=list&amp;-photo_max_width=640&amp;--format=js&quot;&gt;&lt;/script&gt;

&lt;div style=&quot;clear:both&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/nowiki&gt;


===Demo===

# LibrarianDB Demo: http://demo.weblite.ca/apps/librariandb/index.php?-table=books&amp;-action=DataGrid_view , &apos;&apos;&apos;Log in with username &quot;admin&quot; and password &quot;password&quot;&apos;&apos;&apos;

===Download===

* [https://sourceforge.net/project/platformdownload.php?group_id=250381 DataGrid-0.2]
* SVN Repository: http://weblite.ca/svn/dataface/modules/DataGrid

===Installation===

# Download and extract the DataGrid directory into your xataface/modules directory.
# Add the following line to the [_modules] section of your application&apos;s [[conf.ini file]]:&lt;code&gt;
modules_DataGrid=modules/DataGrid/DataGrid.php
&lt;/code&gt;
# Ensure that your [[permissions]] are set up appropriately to allow your users to access the grid action (see next section).

===Setting Up Permissions===

This module defines the following [[permissions]]:

* DataGrid:view_grid  	- Permission to view the data grid for a table.
* DataGrid:create_grid	- Permission to create a new data grid
* DataGrid:edit_grid		- Permission to edit an existing data grid
* DataGrid:update			- Permission to update records via the grid
* DataGrid:manage_grids	- Permission to access the datagrid control panel

In order for a user to access/use the grid he must be granted at least the Datagrid:view_grid and DataGrid:update [[permissions]].  Both of these [[permissions]] are included in the following system roles by default:

* EDIT
* EDIT AND DELETE
* DELETE
* ADMIN
* MANAGER

And of course these [[permissions]] are included with the call to Dataface_PermissionsTool::ALL() .

If you have assigned your own custom roles and want to enable access to the grid, you can simply add the following to your role definition in your [[permissions.ini file]]:
&lt;code&gt;
[MY ROLE]
    DataGrid:view_grid=1
    DataGrid:update=1
&lt;/code&gt;

If you want to explicitly disable the grid for a role, you can extend the role and deny those same [[permissions]]:
&lt;code&gt;
[MY ROLE extends MY ROLE]
	DataGrid:view_grid=0
	DataGrid:update=0
&lt;/code&gt;

	
===Usage===

Once installed, log in as a user that has permission to access the grid. You should notice a new tab along with &quot;details&quot;, &quot;list&quot;, and &quot;find&quot;, called &quot;grid&quot;. Click on the &quot;grid&quot; tab to access the grid.

You can double click on any field to edit it.  Modified fields will be marked in red, and automatically saved every 5 seconds - after the changes are saved the field is no longer marked in red.

===Limitations===

Currently only fields with the following widget types are available to be edited in the grid:

# text
# textarea
# select
# date/datetime/time

Other types of fields will simply not be included in the grid.

===Support/Questions===

Visit the Xataface forum at http://xataface.com/forum
	

</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=39">
	<page_name>Drag_and_Drop_Reordering_of_Relationships</page_name>
	<page_id>39</page_id>
	<page_title>Drag_and_Drop_Reordering_of_Relationships</page_title>
	<content>==Drag and Drop Reordering of Related Records in Xataface==

One powerful aspect of Xataface is its abstraction of relationships between tables.  Once you define a relationship users can browse related records, add new and existing related records, and delete related records to or from the relationship.  For example, suppose you have a &apos;&apos;people&apos;&apos; table and a &apos;&apos;publications&apos;&apos;, you could define a relationship from &apos;&apos;people&apos;&apos; to &apos;&apos;publications&apos;&apos; to identify publications that belong to a particular person.  The table&apos;s might look something like:

===people table===

{| class=&quot;listing listing2&quot;
! person_id
! person_name
|-
| 1
| John Smith
|-
| 2
| Ben Stein
|-
| 3
| Harley Davidson
|-
| 4
| Trevor Linden
|}


===publications table===

{| class=&quot;listing listing2&quot;
! publication_id
! owner_id
! pub_title
|-
| 1
| 2
| Introduction to widgetry
|-
| 2
| 2
| Intermediate Widgetry
|-
| 3
| 2
| Advanced Widgetry
|-
| 4
| 3
| How to play the violin
|}


See http://xataface.com/documentation/tutorial/getting_started/relationships for an introduction to relationships in Xataface, and how to define them.

Our relationship definition in the  &apos;&apos;people&apos;&apos; table&apos;s [[relationships.ini file]] might look something like:

&lt;code&gt;
[my_pubications]
    publications.owner_id=&quot;$person_id&quot;
&lt;/code&gt;

This indicates that any publication whose &apos;&apos;owner_id&apos;&apos; column matches the current &apos;&apos;people&apos;&apos; record&apos;s &apos;&apos;person_id&apos;&apos; field is considered part of the relationship.  Using our example data above, this would mean that Ben Stein&apos;s &apos;&apos;my_publications&apos;&apos; relationship would contain 3 records: &quot;Introduction to Widgetry&quot;, &quot;Intermediate Widgetry&quot;, and &quot;Advanced Widgetry&quot;.  In our Xataface application this means that in the &quot;Details&quot; tab for the &quot;Ben Stein&quot; record, we would see a sub-tab &apos;&apos;My Publications&apos;&apos; which would contain a list of Ben Stein&apos;s publications.

===Adding Publication Order===

Now that we have our relationship, what if Ben Stein wants his publications to appear in a particular order whenever they are displayed to the user.  Xataface allows us to specify an &quot;order&quot; column for our relationship, which will cause the related records to be orderable by drag and drop (if the user has appropriate permissions).

# Add a field to the &apos;&apos;publications&apos;&apos; table named &quot;pub_order&quot;
# Change the relationship definition in the people table&apos;s [[relationships.ini file]] to tell Xataface to use the pub_order field for sorting:&lt;code&gt;
[my_pubications]
    publications.owner_id=&quot;$person_id&quot;
    metafields:order=&quot;pub_order&quot;
&lt;/code&gt;

Now load up your application and navigate to the &quot;My Publications&quot; tab for the &quot;Ben Stein&quot; record. Now you&apos;re able to drag and drop rows in your application to reorder them.

===Permission to Reorder Records===

Only users who have been assigned the &apos;&apos;reorder_related_records&apos;&apos; permission for a record&apos;s relationship are allowed to reorder records of that relationship.  By default the &apos;&apos;EDIT&apos;&apos; role contains this permission, as does any role that permits the user to edit the parent record of the relationship.  The &apos;&apos;READ ONLY&apos;&apos; role does not contain this permission.  If you want to explicitly deny this permission for all relationships in a record, you can simply set this permission to 0 in the associated role within your application&apos;s [[permissions.ini file]]:

&lt;code&gt;
[MY ROLE]
     reorder_related_records=0
&lt;/code&gt;

For more information about permssions see:

* [[permissions.ini file|The Permissions.ini file reference]]
* [http://xataface.com/documentation/tutorial/getting_started/permissions Introduction to Permissions]

===Loading Related Records using the Xataface API===

The ordering that is set via this drag and drop method is also honoured by the Xataface API when fetching related records.  You can load related records using the [http://dataface.weblite.ca/getRelatedRecordObjects getRelatedRecordObjects] method of the [http://dataface.weblite.ca/Dataface_Record Dataface_Record] class. E.g.

&lt;code&gt;
$benStein = df_get_record(&apos;people&apos;, array(&apos;person_id&apos;=&gt;2));
$pubs = $benStein-&gt;getRelatedRecordObjects(&apos;my_publications&apos;);
foreach ($pubs as $pub){
    echo $pub-&gt;val(&apos;pub_title&apos;).&apos;&lt;br/&gt;&apos;;
}
&lt;/code&gt;
This will list up to the first 30 publications of Ben stein in the order prescribed by our drag and drop ordering scheme.
</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=90">
	<page_name>Dynamic_select_boxes</page_name>
	<page_id>90</page_id>
	<page_title></page_title>
	<content>==Dynamic select boxes==

To create two select boxes whose one is dependent (slave) of the other (master), we need to use some javascript with Jason.

Create the valuelists.ini:
&lt;code&gt;

;valuelist for the slave
[slaves_list]
__sql__ = &quot;select slave_id, slave_name, master_id from slaves&quot;

; valuelist for the masters
[masters_list]
__sql__ = &quot;select master_id,master_name from masters&quot;
&lt;/code&gt;

fields.ini:
&lt;code&gt;
[master]
vocabulary=masters_list

[slave]
vocabulary=slaves_list
&lt;/code&gt;

delegate class in the table directory :
&lt;code&gt;
...
function block__after_new_record_form(){
echo &lt;&lt;&lt;END
&lt;script language=&quot;javascript&quot;&gt;&lt;!--
var slave_field= document.getElementById(&apos;slave&apos;);
var master_field = document.getElementById(&apos;master&apos;);
END;
// Let&apos;s get all the slaves available.
$app =&amp; Dataface_Application::getInstance();
$query =&amp; $app-&gt;getQuery();
$table =&amp; Dataface_Table::loadTable($query[&apos;-table&apos;]);
$slaves = $table-&gt;getValuelist(&apos;slaves_list&apos;);
$slave_masters = $table-&gt;getValuelist(&apos;slaves_list__meta&apos;);
// Note that the slaves_list__meta valuelist is automatically created
// because we had three columns in the slaves valuelist.
// The first and third columns effectively create a 2nd valuelist
// named &apos;slaves_list__meta&apos;

// $slaves is an array with keys slave_id and values slave_name
// slave_masters is an array with keys slave_id and values master_id

import(&apos;Services/JSON.php&apos;);
$json =&amp; new Services_JSON(); // A JSON encoder to allow us to easily
// convert PHP arrays to javascript arrays.
echo &apos;
var slaves_options = &apos;.$json-&gt;encode($slaves).&apos;;
var slaves_master = &apos;.$json-&gt;encode($slave_masters).&apos;;
&apos;;

echo &lt;&lt;&lt;END
master_field.onchange = function(){
var selected_master = master_field.options[master_field.selectedIndex].value;
slave_field.options.length = 0;
var index = 0;
for ( slave_id in slaves_options){
if ( selected_master == slaves_master[slave_id] ){
slave_field.options[index++] = new Option(slaves_options[slave_id], slave_id);
}
}
};
//--&gt;&lt;/script&gt;
END;
}

// Also place this javascript after an edit record form...
function block__after_edit_record_form(){
return $this-&gt;block__after_new_record_form();
}


&lt;/code&gt; 

The 2.0 version has a [http://xataface.com/dox/modules/depselect/latest| depselect module] to produce cascading dynamic select boxes very simply.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=29">
	<page_name>encryption</page_name>
	<page_id>29</page_id>
	<page_title>encryption</page_title>
	<content>==encryption [[fields.ini file]] directive==

The &apos;&apos;&apos;encryption&apos;&apos;&apos; directive is meant to be used on password fields only.  It specifies that a certain type of encryption is to be used in the storing of values in this field.  For example, many PHP/MySQL applications use MD5 encryption to store their passwords.  If you want your Xataface application to be able to use the same users tables, then you&apos;ll need to specify the &apos;&apos;&apos;encryption&apos;&apos;&apos; directive for the password field.

===Possible Values===

{| class=&quot;listing listing2&quot;
|-
! Value
! Meaning
! Version
|-
| md5
| MD5 encryption
| 0.6
|-
| sha1
| SHA1 encryption
| 1.0
|-
| encrypt
| MySQL encrypt function
| 1.0
|-
| password
| MySQL password encryption
| 1.0
|}


===E.g. in the users table [[fields.ini file]]===

&lt;code&gt;
[password]
   encryption=md5
&lt;/code&gt;
    </content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=51">
	<page_name>fieldgroup_template</page_name>
	<page_id>51</page_id>
	<page_title>fieldgroup_template</page_title>
	<content>==Using a custom template for a field group on the edit form==

[[toc]]

Xataface allows you to partition your fields into &apos;&apos;groups&apos;&apos; so that similar fields are grouped together on the edit form.  The default layout of the fields remains simply vertical, but you can customize this layout (on a per-group basis) by creating a custom template and then assigning this template to the field group with the &apos;&apos;template&apos;&apos; directive.


===Example===

For example, in your [[fields.ini file]] if you wanted to group your address fields together you might have:
&lt;code&gt;
[fieldgroup:address]
    label=&quot;Address Information&quot;
    template=&quot;AddressInformationGroup.html&quot;

[address_1]
    group=address

[city]
    group=address

[state]
    group=address
&lt;/code&gt;

Then you would add the a template named &apos;&apos;AddressInformationGroup.html&apos;&apos; to your application&apos;s &apos;&apos;templates&apos;&apos; directory to display how the fields are laid out:
&lt;code&gt;
&lt;table width=&quot;100%&quot;&gt;
    &lt;tr&gt;&lt;th&gt;Address 1:&lt;/th&gt;
    &lt;td&gt;{$elements.address_1.html}&lt;/td&gt;

    &lt;th&gt;City:&lt;/th&gt;
    &lt;td&gt;{$elements.city.html}&lt;/td&gt;

    &lt;th&gt;State:&lt;/th&gt;
    &lt;td&gt;{$elements.state.html}&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/code&gt;
This would display all of the fields in this group in a single row (horizontally) instead of vertically.

Note that this is an over-simplified example that doesn&apos;t take account for display error messages, required notices, grouped fields, and other information that you can obtain from the {$elements} array.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=53">
	<page_name>fieldname__permissions</page_name>
	<page_id>53</page_id>
	<page_title>fieldname__permissions</page_title>
	<content>==fieldname__permissions() method==

[[toc]]

The fieldname__permissions() methods will allow you to define custom permissions on a particular field in the [[delegate class]].  For example to specify permissions on a field named &apos;&apos;foo&apos;&apos; you would define the &apos;&apos;foo__permissions()&apos;&apos; method, and to define permissions on a field named &apos;&apos;role&apos;&apos; you would define the &apos;&apos;role__permissions()&apos;&apos; method.


==Example #1==

(Note this example needs to be refined to be more clear)

&lt;code&gt;
function approval_level__permissions(&amp;$record){
	return array(&apos;edit&apos;=&gt;0); //this is will merge with what the permissions for the normal record
}
&lt;/code&gt;

Here we are targeting the &apos;&apos;approval_level&apos;&apos; field of the [[delegate class]].  The permissions method takes a return value an array of permissions.  So for example:

&lt;code&gt;
$permissions[&apos;new&apos;] = 0;
$permissions[&apos;edit&apos;] = 0;
&lt;/code&gt;

Would be an example of an array of permissions which the key being the permission name and the value being a boolean to specify whether they have (1) or don&apos;t (0) have permissions to that field.  We don&apos;t have to specify a complete array of permissions (ie. permission of edit, new, readonly, etc, etc), but rather only the ones we want specifically.  The reason being that the permissions array in the return value gets merged with the permissions that this record normally gets from the record permissions.

So if the record normally gives the permissions new=0, edit=1.  Then the return value from approval_level will merge with the original permissions to produce an array like this:

&lt;code&gt;
$permissions[&apos;new&apos;] = 0;
$permissions[&apos;edit&apos;] = 1;
&lt;/code&gt;

=== Also See: ===

* [[How_to_granulate_permissions_on_each_field]]
* [[__field__permissions]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=89">
	<page_name>file</page_name>
	<page_id>89</page_id>
	<page_title></page_title>
	<content>==Dynamic select boxes==

To create two select boxes whose one is dependent (slave) of the other (master), we need to use some javascript with Jason.

Create the valuelists.ini:
&lt;code&gt;

;valuelist for the slave
[slaves_list]
__sql__ = &quot;select slave_id, slave_name, master_id from slaves&quot;

; valuelist for the masters
[masters_list]
__sql__ = &quot;select master_id,master_name from masters&quot;
&lt;/code&gt;

fields.ini:
&lt;code&gt;
[master]
vocabulary=masters_list

[slave]
vocabulary=slaves_list
&lt;/code&gt;

delegate class in the table directory :
&lt;code&gt;
...
function block__after_new_record_form(){
echo &lt;&lt;&lt;END
&lt;script language=&quot;javascript&quot;&gt;&lt;!--
var slave_field= document.getElementById(&apos;slave&apos;);
var master_field = document.getElementById(&apos;master&apos;);
END;
// Let&apos;s get all the slaves available.
$app =&amp; Dataface_Application::getInstance();
$query =&amp; $app-&gt;getQuery();
$table =&amp; Dataface_Table::loadTable($query[&apos;-table&apos;]);
$slaves = $table-&gt;getValuelist(&apos;slaves_list&apos;);
$slave_masters = $table-&gt;getValuelist(&apos;slaves_list__meta&apos;);
// Note that the slaves_list__meta valuelist is automatically created
// because we had three columns in the slaves valuelist.
// The first and third columns effectively create a 2nd valuelist
// named &apos;slaves_list__meta&apos;

// $slaves is an array with keys slave_id and values slave_name
// slave_masters is an array with keys slave_id and values master_id

import(&apos;Services/JSON.php&apos;);
$json =&amp; new Services_JSON(); // A JSON encoder to allow us to easily
// convert PHP arrays to javascript arrays.
echo &apos;
var slaves_options = &apos;.$json-&gt;encode($slaves).&apos;;
var slaves_master = &apos;.$json-&gt;encode($slave_masters).&apos;;
&apos;;

echo &lt;&lt;&lt;END
master_field.onchange = function(){
var selected_master = master_field.options[master_field.selectedIndex].value;
slave_field.options.length = 0;
var index = 0;
for ( slave_id in slaves_options){
if ( selected_master == slaves_master[slave_id] ){
slave_field.options[index++] = new Option(slaves_options[slave_id], slave_id);
}
}
};
//--&gt;&lt;/script&gt;
END;
}

// Also place this javascript after an edit record form...
function block__after_edit_record_form(){
return $this-&gt;block__after_new_record_form();
}


&lt;/code&gt; </content>
	<keywords></keywords>
	<language>en</language>
	<original_page></original_page>
</wiki>
<wiki id="wiki?page_id=27">
	<page_name>filter</page_name>
	<page_id>27</page_id>
	<page_title>filter</page_title>
	<content>==The filter attribute of the [[fields.ini file]]==

The filter attribute with a value of 1 specifies that a field should be used as a filter field in list view.  In list view, any filter fields will provide a select list with all of the possible values in that field.  Selecting one of the items in this list will filter the results to only show records of that value.

===Example 1: Year, Make, Model===

The Fuel Economy Database has three fields with filter=1 : Year, Make, and Model.  I.e., in their fields.ini file we have something like:

&lt;code&gt;
[Year]
    filter=1

[Make]
    filter=1

[Model]
    filter=1
&lt;/code&gt;

This causes 3 select lists to appear in list view.  See the application [http://fueleconomydb.com/index.php?-action=list here] and notice the select lists for Year, Make, and Model just above the list of results.

If you are filtering on a field where an ID is stored in the DB but you are using a vocabulary to associate it with a value, then it will still be sorted on the ID.

If you want to sort on value then you should add a [[Grafted fields|grafted field]] with the value using the __sql__ directive of the fields.ini file, then use that grafted field as your filter field, like the following:

&lt;code&gt;
__sql__ = &quot;select a.*, b.foo_name from a left join b on a.foo_id=b.foo_id&quot;

[foo_name]
filter=1
&lt;/code&gt;
</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=42">
	<page_name>getFeed</page_name>
	<page_id>42</page_id>
	<page_title>getFeed</page_title>
	<content>==getFeed() Delegate Class Method==

[[toc]]

===Synopsis:===

The getFeed() method of a table [[Delegate class methods|delegate class]] or [[Application Delegate Class|application delegate class]] returns an associative array of parameters to configure the [[Introduction_to_RSS_Feeds_in_Xataface|RSS feed]] for a particular table .  An RSS feed consists of the following components:

# &apos;&apos;&apos;title&apos;&apos;&apos; - The title of the RSS feed as it should appear in the subscribers&apos; feed list.
# &apos;&apos;&apos;description&apos;&apos;&apos; - Describes the RSS feed.
# &apos;&apos;&apos;link&apos;&apos;&apos; - A link to the RSS feed
# &apos;&apos;&apos;syndicationURL&apos;&apos;&apos; - The URL to this RSS feed&apos;s site.

===Parameters===

# &apos;&apos;&apos;array&apos;&apos;&apos; $query - The HTTP query.  Contains information like the current table, current action, and search parameters.  This allows you to customize your RSS feed depending on the user&apos;s query parameters.

===Return Value===

The getFeed() method returns an associative array with the components of the RSS feed.  This array does not need to contain all possible keys, or even any keys.  Any keys that are omitted will simply use default values in the RSS feed.  The array may contain the following keys:

{| class=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| title
| The title for the RSS feed.  If this omitted, it will try to use the &apos;&apos;title&apos;&apos; directive of the &apos;&apos;[_feed]&apos;&apos; section of the [[conf.ini file]].  Failing that, it will try to generate an appropriate title for the feed depending on the current query.
| 1.0
|-
| description
| A Description for this RSS feed.  If this is omitted, it will try to use the &apos;&apos;description&apos;&apos; directive of the &apos;&apos;[_feed]&apos;&apos; section of the [[conf.ini file]].
| 1.0
|-
| link
| A link to the source page of the RSS feed.  If this is omitted, it will try to use the &apos;&apos;link&apos;&apos; directive of the &apos;&apos;[_feed]&apos;&apos; section of the [[conf.ini file]].
| 1.0
|-
| syndicationURL
| A link to the source page of the RSS feed.  If this is omitted, it will try to use the &apos;&apos;syndicationURL&apos;&apos; directive of the &apos;&apos;[_feed]&apos;&apos; section of the [[conf.ini file]].
| 1.0
|}

===Example===

&lt;code&gt;
function getFeed(&amp;$query){
    return array(
        &apos;title&apos; =&gt; &quot;RSS feed for the &quot;.$query[&apos;-table&apos;].&quot; table.&quot;,
        &apos;description&apos; =&gt; &quot;News and updates for automobiles&quot;,
        &apos;link&apos; =&gt; df_absolute_url(DATAFACE_SITE_HREF),
        &apos;syndicationURL&apos; =&gt; df_absolute_url(DATAFACE_SITE_HREF)
    );
}

&lt;/code&gt;

&apos;&apos;&apos;Note that RSS feeds will work perfectly well without defining this method.  This just allows you to customize one or more parameters of the RSS feed&apos;&apos;&apos;.

===See Also:===

* &apos;&apos;&apos;[[getFeedItem]]&apos;&apos;&apos; - A delegate class method available to both the [[Delegate class methods|table delegate classes]] to configure parameters for the particular items of the RSS feed.
* &apos;&apos;&apos;[[getRelatedFeed]]&apos;&apos;&apos; - A [[Delegate class methods|delegate class method]] available to both the [[Application Delegate Class|application delegate class]] and the [[Delegate class methods|table delegate classes]] to configure the [[Introduction to RSS Feeds in Xataface|RSS feed]] for a related records list.
* &apos;&apos;&apos;[[getRSSDescription]]&apos;&apos;&apos; - A delegate class method to override the description that appears for a particular record in an RSS feed.  (The same as the &apos;&apos;description&apos;&apos; parameter of the [[getFeedItem]] method.
* &apos;&apos;&apos;[[Introduction to RSS Feeds in Xataface]]&apos;&apos;&apos; - An overview of Xataface&apos;s RSS feed support.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=41">
	<page_name>getFeedItem</page_name>
	<page_id>41</page_id>
	<page_title>getFeedItem</page_title>
	<content>==getFeedItem() Delegate Class Method==

[[toc]]

===Synopsis:===

The getFeedItem() method of a table [[Delegate class methods|delegate class]] returns an associative array of parameters for a record as it should appear as part of an [[Introduction_to_RSS_Feeds_in_Xataface|RSS feed]].  An RSS feed item consists of the following components:

# &apos;&apos;&apos;title&apos;&apos;&apos; - The title of the record as it appears in the RSS feed.
# &apos;&apos;&apos;description&apos;&apos;&apos; - The description of the record for the RSS feed.  This is really the body of the RSS feed item.
# &apos;&apos;&apos;link&apos;&apos;&apos; - The linkback URL if users want to know more about the record.
# &apos;&apos;&apos;date&apos;&apos;&apos; - The date that the record was posted/modified.
# &apos;&apos;&apos;author&apos;&apos;&apos; - The name of the person who posted this record.
# &apos;&apos;&apos;source&apos;&apos;&apos; - URL to the site where record originated from.

===Parameters===

# &apos;&apos;&apos;Dataface_Record&apos;&apos;&apos; &amp;$record - The record that is being represented in an RSS feed.

===Return Value===

The getFeedItem() method returns an associative array with the components of the RSS feed.  This array does not need to contain all possible keys, or even any keys.  Any keys that are omitted will simply use default values in the RSS feed.  The array may contain the following keys:

{| class=&quot;listing listing2&quot;
! Name
! Description
! Version
|-
| title
| The record title as it appears in RSS feeds.  If this is omitted, the RSS feed will simply use the output of [http://dataface.weblite.ca/Dataface_Record Dataface_Record&apos;s] [http://dataface.weblite.ca/getTitle getTitle()] method.
| 1.0
|-
| description
| The record description.  This is used in the main body of the RSS feed.   If this is omitted, the RSS feed will use an HTML table that shows all of the field data in the record.  This value can also be overridden using the [[getRSSDescription]] method of the delegate class.
| 1.0
|-
| link
| The URL to this record.  If this is omitted it just points to the &apos;&apos;view&apos;&apos; tab for this record.  However you can direct it anywhere you like.  When the user clicks on the &quot;More Info&quot; link in his RSS reader it will direct him to this link.
| 1.0
|-
| date
| The date that this record was posted or last modified.  This is the date that an RSS reader will use to decide if it has already loaded the record yet.  If this is omitted it will try the [http://dataface.weblite.ca/Dataface_Record Dataface_Record&apos;s] [http://dataface.weblite.ca/getLastModified getLastModified()] method to obtain the last modified date of the record.  Failing that, it will use [http://dataface.weblite.ca/Dataface_Record Dataface_Record&apos;s] [http://dataface.weblite.ca/getCreated getCreated()] method to try to obtain the creation date of the record.  This date should be a unix timestamp.
| 1.0
|-
| author
| The name of the user who posted this record.  If this is omitted, then it will try to use [http://dataface.weblite.ca/Dataface_Record Dataface_Record&apos;s] [http://dataface.weblite.ca/getCreator getCreator()] method.  Failing that, it will use the value of the &apos;&apos;default_author&apos;&apos; parameter in the &apos;&apos;[_feed]&apos;&apos; section of the [[conf.ini file]].  If that is not defined, then it simply uses the string &quot;Site Administrator&quot;.
| 1.0
|-
| source
| The source URL where the feed is to have originated.  If none is specified, then it will use the value of the &apos;&apos;source&apos;&apos; parameter in the &apos;&apos;[_feed]&apos;&apos; section of the [[conf.ini file]].  Failing that, it will simply use the URL to the application.

Note that you can alternatively define this value using the [[getFeedSource]] method.
| 1.0
|}

===Example===

&lt;code&gt;
function getFeedItem(&amp;$record){
    return array(
        &apos;title&apos; =&gt; &quot;News Item: &quot;.$record-&gt;getTitle(),
        &apos;description&apos; =&gt; $record-&gt;display(&apos;News Body&apos;),
        &apos;link&apos; =&gt; $record-&gt;getPublicLink(),
        &apos;date&apos; =&gt; strtotime($record-&gt;val(&apos;last_modified&apos;)),
        &apos;author&apos; =&gt; $record-&gt;val(&apos;posted_by&apos;),
        &apos;source&apos; =&gt; &apos;http://www.example.com&apos;
    );
}

&lt;/code&gt;

&apos;&apos;&apos;Note that RSS feeds will work perfectly well without defining this method.  This just allows you to customize one or more parameters of the RSS feed&apos;&apos;&apos;.

===See Also:===

* &apos;&apos;&apos;[[getFeed]]&apos;&apos;&apos; - A delegate class method available to both the [[Application Delegate Class]] and the [[Delegate class methods|table delegate classes]] to configure the RSS feed as a whole (not just for an individual item in the RSS feed.
* &apos;&apos;&apos;[[getRelatedFeed]]&apos;&apos;&apos; - A [[Delegate class methods|delegate class method]] available to both the [[Application Delegate Class|application delegate class]] and the [[Delegate class methods|table delegate classes]] to configure the [[Introduction to RSS Feeds in Xataface|RSS feed]] for a related records list.
* &apos;&apos;&apos;[[getRSSDescription]]&apos;&apos;&apos; - A delegate class method to override the description that appears for a particular record in an RSS feed.  (The same as the &apos;&apos;description&apos;&apos; parameter of the [[getFeedItem]] method.
* &apos;&apos;&apos;[[Introduction to RSS Feeds in Xataface]]&apos;&apos;&apos; - An overview of Xataface&apos;s RSS feed support.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=17">
	<page_name>getRegistrationActivationEmailInfo</page_name>
	<page_id>17</page_id>
	<page_title>getRegistrationActivationEmailInfo</page_title>
	<content>==getRegistrationActivationEmailInfo() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the default information that is used to send the registration activation email (the email that the user receives when they register).

This should return an associative array with the keys:

* subject - The subject of the activation email.
* message - The message body of the activation email.
* parameters - The parameters to be used in the mail() function for the activation email.
* headers - The headers to use in the mail() function for the activation email.


===Signature===

function getRegistrationActivationEmailInfo( Dataface_Record &amp;$record, string $activationURL ) : array

====Parameters====

{| class=&quot;listing listing2&quot;
! Name
! Description
|-
| &amp;$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&amp;$record, $activationURL){
        return array(
            &apos;subject&apos; =&gt; &apos;Welcome to the site.. Activation required&apos;,
            &apos;message&apos; =&gt; &apos;Thanks for registering.  Visit &apos;.$activationURL.&apos; to activate your account&apos;,
            &apos;headers&apos; =&gt; &apos;From: webmaster@example.com&apos; . &quot;\r\n&quot; .
                          &apos;Reply-To: webmaster@example.com&apos; . &quot;\r\n&quot; .
                          &apos;X-Mailer: PHP/&apos; . phpversion()
             );
            
        
       
    }
}
&lt;/code&gt;

===Example 2: Only override the subject===

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&amp;$record, $activationURL){
        return array(
            &apos;subject&apos; =&gt; &apos;Welcome to the site.. Activation required&apos;
             );
            
        
       
    }
}
&lt;/code&gt;


===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=19">
	<page_name>getRegistrationActivationEmailMessage</page_name>
	<page_id>19</page_id>
	<page_title>getRegistrationActivationEmailMessage</page_title>
	<content>==getRegistrationActivationEmailSubject() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the default registration activation email message body (the email that the user receives when they register).


===Signature===

function getRegistrationActivationEmailSubject( Dataface_Record &amp;$record, string $activationURL ) : string

====Parameters====

{| class=&quot;listing listing2&quot;
! Name
! Description
|-
| &amp;$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&amp;$record, $activationURL){
        return &apos;Thanks for registering.  Please visit &apos;.$activationURL.&apos; to activate.&apos;;   
    }
}
&lt;/code&gt;


===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailSubject]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=18">
	<page_name>getRegistrationActivationEmailSubject</page_name>
	<page_id>18</page_id>
	<page_title>getRegistrationActivationEmailSubject</page_title>
	<content>==getRegistrationActivationEmailSubject() Hook==

A hook that can be implemented in the [[Application Delegate Class]] or the [[Table Delegate Class]] to override the default registration activation email subject line (the email that the user receives when they register).


===Signature===

function getRegistrationActivationEmailSubject( Dataface_Record &amp;$record, string $activationURL ) : string

====Parameters====

{| class=&quot;listing listing2&quot;
! Name
! Description
|-
| &amp;$record
| A Dataface_Record object encapsulating the record that is being inserted in the users table for this registration.
|-
| $activationURL
| The URL where the user can go to activate their account.
|-
| returns
| Mixed. If this method returns a PEAR_Error object, then registration will fail with an error.
|}

===Example===

&lt;code&gt;
&lt;?php
class conf_ApplicationDelegate {

    function getRegistrationActivationEmailInfo(&amp;$record, $activationURL){
        reeturn &apos;Welcome to the site.. Activation required&apos;;   
    }
}
&lt;/code&gt;


===See Also===
* [[beforeRegister]]
* [[afterRegister]]
* [[validateRegistrationForm]]
* [[sendRegistrationActivationEmail]]
* [[getRegistrationActivationEmailInfo]]
* [[getRegistrationActivationEmailMessage]]
* [[getRegistrationActivationEmailParameters]]
* [[getRegistrationActivationEmailHeaders]]</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=67">
	<page_name>grid</page_name>
	<page_id>67</page_id>
	<page_title>grid</page_title>
	<content>==widget:type = grid==

Suppose we have two tables, tbl_organisation and tbl_individuals, in the edit view for a record in the organisations table (tbl_organisations) we also want to be able to view and edit the individuals within this organisation we can use widget:type=grid

In the /tables/tbl_organisation/fields.ini we create a transient field by adding:

&lt;code&gt;
[Individuals]
widget:label = &quot;Individuals&quot;
transient=1
relationship=individuals
widget:type=grid
widget:columns=&quot;ind_firstname,ind_lastname,ind_tel&quot;
&lt;/code&gt;

The above assumes we have a relationship entry in our /tables/tbl_organisation/relationships.ini that looks like this:

&lt;code&gt;
[individuals]
__sql__ = &quot;SELECT * FROM tbl_individual WHERE org_id=&apos;$org_id&apos;&quot;
&lt;/code&gt;

The fields.ini will show the three columns shown in widget:columns from the table tbl_individual

Correct permissions need to be set to enable editing and deletion etc of these records.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki>
<wiki id="wiki?page_id=28">
	<page_name>group</page_name>
	<page_id>28</page_id>
	<page_title>group</page_title>
	<content>==group directive in [[fields.ini file]]==

The group directive allows you to declare that certain fields of your table should be grouped together on the edit form and the view tab (and other logical places).  For example, fields like address, city, state, country, postal_code would likely be grouped together as address_info.  Grouping the fields together will make the fields appear in a section of their own in the view tab and the edit form.

E.g.  In your fields.ini file:

&lt;code&gt;
[address]
   group=address_info

[city]
    group=address_info

[state]
    group=address_info

[country]
    group=address_info

[postal_code]
    group=address_info

&lt;/code&gt;


===Configuring the Group as a Whole===

You can also configure your group in the fields.ini file by adding a &apos;&apos;&apos;fieldgroup:NAME&apos;&apos;&apos; section, where &apos;&apos;&apos;NAME&apos;&apos;&apos; is the name of the group.  E.g.
&lt;code&gt;
[fieldgroup:address_info]
    label=&quot;Address Information&quot;
    description = &quot;Please enter your address information below&quot;
&lt;/code&gt;

====See also:====

* [[fields.ini file]] - Scroll down to the &apos;&apos;&apos;Field Groups&apos;&apos;&apos; section.</content>
	<keywords></keywords>
	<language>en</language>
	<original_page>0</original_page>
</wiki></record>