A place for users and developers of the Xataface to discuss and receive support.
by amwassil » Fri Apr 14, 2006 10:46 am
Dataface is a great backside for entering data into the mySQL database. I built a nice little demo for myself, with all the data fields, configuration, validation, etc. This works very nicely and I have populated my database with some data.
Now, how do I write a frontend so that the general public can view my data? I don't want the general public to see all the data fields. I just want them to see a table of contents showing the titles of my "articles". I want them to be able to sort the articles and view only the data that I want them to see. This is what a CMS normally provides, but how does Dataface enable me to do this?
I would guess that the frontend would consist of "queries" to the database. But I don't know how to do that. Is there a "frontend" template to start with that has some queries, etc.
Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by shannah » Fri Apr 14, 2006 12:18 pm
Hi Michael, It looks as though you have reached the outer regions of Dataface 0.5.3's target area. This release 0.5.x focused on making it easy to get the back-end up and running. I developed Dataface originally to build new back-ends for existing applications that already had front-ends. Version 0.6 will focus on evolving it into a full application framework for data-driven applications. Version 0.6 will provide a very fine-grained permissions framework that will allow you to specify permissions at a field, record, table, and action* level using ini files and delegate classes. It will also include a basic authentication framework to allow you to authenticate against users contained in a table of your choice. These two things are key to being able to offer your application up to the general public. Version 0.5.x does contain permissions handling via delegate classes but to a lesser extent, and authentication would need to be handled by you (although it isn't difficult to add your own authentication -- see http://framework.weblite.ca/forum/dataface-users/4 for some tips. One cautionary point with the 0.5.x releases is that permissions are optimistic. The means that ALL permissions are allowed unless you define permissions to disallow some actions. Also all tables are accessible, even if they are not in the menu (just add a "-table=..." the get parameters to access a table. Version 0.6 will work this way also by default, but it will allow you to set the security level to "strict" to make permissions pessimistic (so that permissions are only granted if they are explicitly granted by you). In addition, Version 0.6 adds a modular and extensible actions framework to be able to define actions in an INI file. You can provide custom templates for your actions and custom controllers too if your actions are quite complex. This will allow the framework to grow much more quickly as people can develop actions independently and the integrate them with the framework at a later time. The last key ingredient required to be able to make front-end applications is a full set of tags that can be used in templates to incorporate useful compontents into your pages. This will also be included into 0.6. For example there will be a tag for {result_list} which will include a list (as can currently be found in the "list" tab of your dataface application) in your page, or {search} which would include the little search box in the top right corner, etc... Some other features that will be included are:
- internationalization :
- Using INI files multiple languages can be defined for Dataface.
- There is a LanguageTool class that is used to translate text to the appropriate language for viewing.
- A {translate} tag will be added to be able to translate text on any template
- Database records can have translations using naming conventions on tables. e.g., the french translation for the Profiles table would be named Profiles_fr . The Profiles_fr table need contain only columns for primary keys and columns that are to be translated. Dataface handles all of the dirty work to load to proper translation when loading records.
- A translation form to translate records form one language to another.
- more parameters definable in delegate classes and ini files. All INI file parameters can be overridden by delegate class methods.
- Surrogate views (the ability to define tables based on SQL queries).
- Reports (similar to Views, but used in a different context).
I have completed many of these features in my development version, but there is still work to do with testing. And of course there will be full documentation of the features so that you can get started right away. I have exams tomorrow and on the 20th so I won't be able to work on Dataface much (or at all) until then, but I'm looking at an early may release of 0.6 beta. Best regards Steve
-
shannah
-
- Posts: 4457
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Fri Apr 14, 2006 1:18 pm
Thanks for the info. Looking forward to version 0.6!
In the meantime, I'll have to get my php programmer to help me get a frontend. I ran into a similar situation in trying to use Mambo Open Source for the project I'm working on. I was able to use Facile Forms to get the data set entered into the database. But then I couldn't figure out how to display the data on a frontend webpage. Trying to get into the guts of MOS is beyond my capabilities.
I did locate a site: visiblephp.com where the author publishes all of his php scripts and I might be able to adapt his front end. Basically, all I need to know is how to query the database to display the data I want the public to see.
Best wishes for you upcoming exams.
Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by shannah » Fri Apr 14, 2006 3:34 pm
>Basically, all I need to know is how to query the database to display the data I want the public to see. We're all coming from different backgrounds here so what is easy for one person is difficult for another (and vice versa). From my background as a PHP programmer, querying the database is the easy part.. just a select query in a mysql_query() statement, then do what you want with the results. Of course this is easy because I've been doing it every day for the past 7 years There are tools in place in the current version that will save you from doing most of the heavy lifting, but I would rather not document them until 0.6 (because once they're documented, they must be supported ). Part of the solution could be just to define a getPermissions() method in your delegate class as follows: - Code: Select all
// function to define permissions on records of this table function getPermissions(&$record){ if ( isset( $_SESSION['Username']) ){ // the user is logged in return Dataface_PermissionsTool::ALL(); } else { return Dataface_PermissionsTool::READ_ONLY(); } }
// function to define permissions on field named 'foo' function foo__permissions(&$record){ if ( isset( $_SESSION['Username']) ){ // user is logged in return Dataface_PermissionsTool::ALL(); } else { return Dataface_PermissionsTool::NO_ACCESS(); } }
Note that in the above example, $_SESSION['Username'] is assuming you have implemented your own authentication scheme and stored the Username of the logged in user in the session vars - it is not dataface specific. At least with this you would be able to discriminate who does what so you could allow outside users to access the database without being able to edit records.
-
shannah
-
- Posts: 4457
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Mon Apr 17, 2006 9:15 pm
Just wanted to let you know that I have created a functioning frontend. It is not connected to the Dataface "backend" but connects via some simple queries to the same table in the database. It works fine and allows one to display lists of entries in the database based on several different list queries and also to search the database by key words and date. I apologize that I can't give you the URL at this time, perhaps I'll be able to do so later.
I have some questions about both the Dataface backend and the frontend.
1. In "List" is it possible to rearrange the order of the data fields (ie the columns of the table)? Currently, they simply display left to right in the same order that they exist in the database. I'd like the user to be able to move those columns to arrange them in any order they please; anyway to do that?
2. I have some very nice terms defined in the table valueslist.ini. Is it possible to use those terms in my frontend? I am using php scripts to run the database queries. Is it possible to use that valueslist.ini in some way to display those terms rather than the bare mySQL field values?
Thanks again, Dataface is really great for managing the db!
Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by shannah » Mon Apr 17, 2006 10:29 pm
>1. In "List" is it possible to rearrange the order of the data fields (ie the columns of the table)? Not in this version. I'll be adding an "order" attribute to version 0.6 that allows you to specify an order. As far as the user re-ordering the columns in the interface, I'll look for a javascript library to do this. I'm sure I have seen a few in passing already. > I have some very nice terms defined in the table valueslist.ini. Is it possible to use those terms in my frontend? Yes. This is possible. Suppose you have a valuelist named 'Countries' in a table named 'Profiles'? You can access this valuelist by doing the following: - Code: Select all
// initialize dataface framework require_once '/path/to/dataface/dataface-public-api.php'; df_init(__FILE__, '/url/to/dataface');
// load the Profiles table require_once 'Dataface/Table.php'; $profilesTable =& Dataface_Table::loadTable('Profiles'); // $profilesTable is a Dataface_Table object
// now we can obtain the 'Countries' valuelist $countries =& $profilesTable->getValuelist('Countries'); // $countries is an associative array of the values // in the Countries valuelist, where the keys are the ids // and the values are the values.
// now load your Profiles from the database:
$res = mysql_query('SELECT FirstName, LastName, Country FROM Profiles', $db); echo " First Name | Last Name | Country |
---|
"; while ( $row = mysql_fetch_assoc($res) ){ echo "".$row['FirstName']." | ".$row['LastName']." | ".$countries[$row['Country']]." | "; } echo " "; ?>
The above code snippet is an example of using the Dataface API to only get the valuelist, and use the standard mysql queries for the rest of the data. It is possible, however, to use a pure Dataface solution, ranther than use mysql_query statements and manually using the valuelists. The equivalent to the above snippet using the Dataface API is as follows: - Code: Select all
// initialize dataface framework require_once '/path/to/dataface/dataface-public-api.php'; df_init(__FILE__, '/url/to/dataface');
$query = array(); $profiles =& df_get_records('Profiles', $query);
// Note that we used an empty query, but we can filter the search // by applying values to the query. // e.g., $query = array('FirstName'=>'Steve') // would return only records with first name containing 'Steve'
echo " First Name | Last Name | Country |
---|
";
while ( $profiles->hasNext() ){ $profile =& $profiles->next(); // $profile is a Dataface_Record object echo "".$profile->display('FirstName')." | ".$profile->display('LastName')." | ".$profile->display('Country')." | "; // Note that $profile->display() will automatically substitute // the valuelist values for fields that use a valuelist. // // Alternatively you could use $profile->qq('FirstName') etc... // as an alias for the display() method. // // If you don't want the valuelist value substituted, you can // use $profile->strval(), or $profile->q().
unset($profile); // important to unset $profile since it is passed by reference // so subsequent iterations don't overwrite data on other // profiles. } echo " "; ?>
One of the many advantages to using the Dataface API vs using mysql calls directly is that it allows you to work with your model at a more logical level. For example, if you have a relationship in the Profiles table called, jobs, you could obtain the jobs of a profile with the getRelatedRecords() method. e.g.: - Code: Select all
$jobs =& $profile->getRelatedRecords('Jobs'); // returns array of jobs records related to this profile. // each job is just an associative array where keys are columns, and // values are their associated values. foreach ( $jobs as $job){ echo "Job title: ".$job['JobTitle']." Job description: ".$job['JobDescription']; }
// or
$jobIterator =& $profile->getRelationshipIterator('Jobs'); // returns an iterator to iterate through the jobs. // The jobs returned are different than in getRelatedRecords() // in that each job is a Dataface_RelatedRecord object
while ( $jobIterator->hasNext() ){ $job =& $jobIterator->next(); echo "Job title: ".$job->display('JobTitle')." Job description: ".$job->display('JobDescription'); unset($job); }
// or
$jobObjects =& $profile->getRelatedRecordObjects('Jobs'); // returns array of Dataface_RelatedRecord objects that represent // the jobs related to this profile. foreach ($jobObjects as $job){ echo "Job title: ".$job->display('JobTitle')." Job description: ".$job->display('JobDescription'); }
// or implicitly get the jobs using via the profile (without explicitly // getting the related records $numJobs = $profile->numRelatedRecords('Jobs'); for ( $i=0; $i<$numJobs; $i++){ echo "Job title: ".$profile->display('Jobs.JobTitle',$i)." Job description: ".$profile->display('Jobs.JobDescription',$i); }
Hope this helps. This is a good place to start dabbling with the Dataface API. It is pretty rich and will allow you to build a pretty rich front-end, once you are familiar with it. I am happy to answer any questions or provide code samples to do whatever it is that you need to do, if you want to start working with the Dataface API. Best regards Steve
-
shannah
-
- Posts: 4457
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Tue Apr 18, 2006 9:52 am
Thanks for all the info. I decided to try first just getting the valuelist values picked up in my query. Unfortunately I must not be grokking something, because although I have the script working again, it is not picking up the values from my valuelists. Would you be able to look at my code and advise where you think I have made my error? I am running this on a shared server and no domain name, just an IP. I have had problems with other applications that insisted on having a domain and did not function with the bare IP. Could that be the problem here? getValuelist('Status'); $type =& $enhancementsTable->getValuelist('Type'); $iwsys =& $enhancementsTable->getValuelist('IWSys'); $syscat =& $enhancementsTable->getValuelist('SysCat');
// $status, $type, $iwsys and $syscat are associative arrays of the values // in the valuelists, where the keys are the ids // and the values are the values.
// now load your Enhancements from the database:
$res = mysql_query('SELECT * FROM Enhancements ORDER BY IWSys') or die(mysql_error());
while ( $row = mysql_fetch_assoc($res) ){ // Print out the contents of the entry echo "".$row['ArticleTitle']; echo " "; echo "System Affected: ".$row['IWSys']; echo " Category Affected: ".$row['SysCat']; echo " "; echo "Integrated: ".$row['Integrated']; echo " Status: ".$row['Status']; echo " Priority: ".$row['Priority']; echo " "; echo " Description: ".$row['ShortDesc']; echo " "; echo "".$row['LongDesc']; echo "
"; }
mysql_close($link); ?>
|
I don't see where the values for my $status, $type, $iwsys and $syscat are being passed to the results. I tried substituting '$status' and $status for 'Status', etc in the results display, but that didn't work either. I really appreciate your efforts and prompt replies. How do you get your nice clean blue box with your code not executing like some of mine insists on doing. I hope you see the problem despite the html. Thanks again. Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by shannah » Tue Apr 18, 2006 10:08 am
Hi Michael, You're 99% of the way there. The only thing that you have to do is substitute the values from the database for the appropriate value in the valuelist. Your database record stores only the valuelist key, but you want to display the valuelist value. So in the following case: - Code: Select all
echo "System Affected: ".$row['IWSys'];
you are actually showing the valuelist ID. All you have to do is use this ID to show the valuelist value as follows: - Code: Select all
echo "System Affected: ".$iwsys[$row['IWSys']];
Hope this helps. As far as making the code show up in a blue box, I wrap them in tags. E.g.
Some code....
Showing HTML in this forum is a huge nussance though, since the forum tries to just display the html for html tags (rather than displaying the code), so any time I wanted to put an HTML tag in, I would have to use html entities to encode the opening and closing tags: eg: <p> Paragraph text... </p>
Hope this helps.
Steve
-
shannah
-
- Posts: 4457
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Tue Apr 18, 2006 12:29 pm
Thank you very much, Steve. My valueslist values are now showing up very nicely. Exactly what I wanted!
Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Mon Apr 24, 2006 12:20 pm
I have the frontend set and functioning pretty much exactly as we want it to. However, all the files are located within a subdirectory structure within: http : / / 123 .123 .123 .123 /www /dataface
I thought it would be a good idea to get the public frontend out of that directory and into: http : / / 123 .123 .123 .123 /www /publicdirectory
I copied all my files and adjusted the links to work in the new directory structure. The page loads and the links work OK. I then tested one of my mySQL queries and I get the following error:
Warning: parse_ini_file(): Cannot open 'conf.ini' for reading in /home/name/public_html/dataface/Dataface/Application.php on line 121 Error loading config file. No tables specified.
This is a shared host. Here's the relevant coding in the mySQL query:
< ! DOCTYPE html PUBLIC " - //W3C // DTD XHTML 1.0 Transitional // EN " " http : / / www .w3 .org /TR /xhtml1 /DTD /xhtml1 - transitional .dtd " > < html xmlns = " http : / / www .w3 .org /1999 /xhtml " > < head > < title > Documentation Project< / title > < / head > < body >
< ? php / / initialize dataface framework
require_once ' .. /.. /dataface /dataface-public-api.php ' ;
df_init(__FILE__, ' http : / / 123 .123 .123 .123 / www /dataface ' ) ;
// Make a MySQL Connection $ link = mysql_connect ( " localhost " , " username " , " pwd " ) or die ( mysql_error ( ) ) ; mysql_select_db ( " dbname " ) or die ( mysql_error ( ) ) ;
// load the Enhancements table
require_once ' .. /.. /dataface /Dataface /Table.php ' ; $enhancementsTable = Dataface_Table : : loadTable ( ' Enhancements ' ) ;
I did some debugging and the error appears to occur at this line:
df_init(__FILE__, ' http : / / 123 .123 .123 .123 / www /dataface ' ) ;
Any ideas what's preventing Application.php from finding the tables? By the way, this query works fine in the other directory structure, so I have a guess the problem may be paths. But I've tried all kinds of path modifications to no avail.
Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by shannah » Mon Apr 24, 2006 12:57 pm
Hi Michael,
The public front-end depends upon the conf.ini file and the /tables directory, this is why the error is occurring. The intended way to partition a dataface application is to have the dataface directory separate from the application directory altogether. So you would have:
/www/path/to/dataface and /www/path/to/app
The app contains all of your custom stuff.. the dataface directory remains essentially untouched from the default install.
You can still use HTACCESS files to protect the back-end script while leaving the front-end pages publicly accessible.
If you want to keep your current directory structure, keep in mind that the conf.ini file and the tables directory must be in the same directory as any page that uses the dataface API. (Your front-end uses the API only to obtain the value-lists, but it still uses it). I suppose you could symbolically link the conf.ini file and the tables directory so that they "appear" to be in the same directory - but this approach seems like the first step to making the application confusing and less portable.
Hope this helps.
-Steve
-
shannah
-
- Posts: 4457
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Mon Apr 24, 2006 3:20 pm
Thanks. The query executes now, but it's not picking up my valueslist.ini values. I have a default dataface install. Here's the directory structure that works OK:
www/dataface - dataface default install
www/dataface/app/index.html, all mySQLqueries.php www/dataface/app/conf.ini www/dataface/app/tables www/dataface/app/tables/Enhancements www/dataface/app/tables/Enhancements/fields.ini, valueslist.ini
Here's the directory structure that's not picking up the valuleslist.ini:
www/app/index.html www/app/php/all mySQLqueries.php www/app/php/conf.ini www/app/php/tables www/app/php/tables/Enhancements www/app/php/tables/Enhancements/fields.ini, valueslist.ini
I realize the directory structure is different because I have put all the queries into a separate directory. I'd prefer not to, but if that's causing the problem I could put them back into the "app" directory again. The query files in each directory structure are identical except for the following
In the working structure:
require_once ' . . / dataface - public - api . php ' ; df _ init ( __ FILE __ , ' h t t p : / / www / dataface ' ) ;
require _ once ' . . / Dataface / Table . php ' ; $enhancementsTable =& Dataface _ Table : : loadTable ( ' Enhancements ' ) ;
In the nonworking structure:
require _ once ' . . / . . / dataface / dataface - public - api . php ' ; df _ init ( __ FILE __ , ' h t t p : / / www / app ' ) ;
require _ once ' . . / . . / dataface / Dataface / Table . php ' ; $enhancementsTable =& Dataface _ Table : : loadTable ( ' Enhancements ' ) ;
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by shannah » Mon Apr 24, 2006 4:31 pm
Hi Michael, As you suspected, application must be in the same directory (and the same level) as the conf.ini file and the tables directory. I suppose this difficulty could be changed in later versions but it would require some thought and testing to make change like this. Another note is that after you call df_init(__FILE__,...) it automatically adds dataface and dataface/lib to your class path. This means that you don't need to include the full path to Dataface/Table.php when you require it. you could just do - Code: Select all
require_once 'Dataface/Table.php';
In fact it would probably be better to do this as I have run into some anomalous behavior with PHP when requiring the same file but from different paths. Hope this gets you going. -Steve
-
shannah
-
- Posts: 4457
- Joined: Wed Dec 31, 1969 5:00 pm
by amwassil » Mon Apr 24, 2006 6:45 pm
Thanks again, Steve! Paths adjusted, files moved to correct directories, etc. All is working normally now.
Michael Wassil
-
amwassil
-
- Posts: 30
- Joined: Wed Dec 31, 1969 5:00 pm
by Aoirthoir » Wed Sep 20, 2006 9:39 pm
Mr. Steve,
Do the recommendations in this post still apply?
Thank you kindly.
-
Aoirthoir
-
- Posts: 420
- Joined: Wed Dec 31, 1969 5:00 pm
Return to Xataface Users
Who is online
Users browsing this forum: No registered users and 24 guests
|