how to tackle a custom forms database - php

I'm currently researching a project for the place that I work in. We are trying to create a system that will allow forms to be set up dynamically from a database.
My question is what database structure would best suit something like this?
I currently have a structure of:
forms_form
forms_formfields
forms_formdata
I don't think this is the most appropriate layout for this. Basically to make is make sense I need to be able to make a form within the database that can have infinite fields all customized and have the data when submitted stored in the database.

The proposed structure looks ok to me. form -> field is clearly 1:M relation, so you'll need forms(id,...) and fields(id, form_id, type, ...). field->data is kind of 1:1, so theoretically a separate table is not needed, unless you allow one form to be used with different sets of data. If this is the case, i'd suggest datasets(id,...) and data(field_id, dataset_id, value).

Related

Concrete5: User Attributes vs Custom DB-Table, what are the Pros and Cons?

I'm developing a page with C5 needing various data to be attached to the user accounts. There are two types of users, having different data. Some of the data is multi dimensional and therefor needs custom DB tables. My question is now if it makes sense to store all data in custom DB tables or to use user attributes for the one dimensional data.
Probably there is no general answer to this, but maybe some pros and cons?
I'm often asking myself where to store data in Concrete5 and would be interested how others decide ...
Yeah. I'd definitely store as user attributes for similar reasons to the one you've already identified (visible, searchable, etc).
concrete5 is extensible, but not super extensible; you can attach data to a user using attributes, but not through some totally custom object / db table that you also expect to, e.g., show up on the user profile page.
Oftentimes in c5 (like any other framework), doing it the Right way (attribute) is more difficult (especially for the first "object", but also for each additional one) than just creating a db table and linking to a user id. But, like in all frameworks, you'll reap benefits down the road that you hadn't even considered. This is in searching, upgradability, and things that might only occur to the guy who takes over development next year.
So, with all that being said, go with attributes. And not just for the one dimensional data. You can configure the attribute controller (and the db schema behind it) to store any data you wish. Look at the Address attribute. This contains multiple fields (though it's still 1D). I think there's an opensource "multi address" attribute out there which stores 1-n addresses as a single attribute. You can do this with an additional linked table, but I've recently gotten lazy with c5 and done no-mysql by dumping json_encode()ed (multi-dimensional) arrays in the "data" field. (In this case, your attribute doesn't even need its own table -- it can use the Default table.) You can then configure the editing interface and also the display value (so, e.g., it just shows a list of each sub-object's Name property). Similarly, you can configure the text that gets indexed for searching purposes.
You asked for pros/cons. Doing this custom will be quicker and more straightforward. Extending an attribute, especially to create something complex, isn't super simple, and there isn't a lot of good documentation. Also, the attribute-editing UI (on the user dashboard page) is a bit kludgy. Yes, you get to "design" whatever you want within the "table cell", but you're still limited to making the admin click on the attribute name, using your editing interface within the cell, and then (ideally) clicking on the little disk icon. (Creating a javascript dialog might solve some issues here.)

Detecting field changes - cakePHP

What I want
I want to see which fields on a table was changed and save that name into the database under the edit column.
What I have
Currently, not much. Just the standard cakePHP baked edit view and controller. I have done it previously, but not with cakePHP. What I did was retrieve the record, and if it's different to what the user entered, save the name of the column that was edited in the edit column corresponding to the row.
My Question
Could someone tell me how I would compare user input with what is on the database?
Behaviors like the "Logable" Behavior already do that and store the information separately.
I advice you to do the same. the "changes" do not necessarily need to be put into the same table. If you feel they do, though, you could make your own "modified" Logable behavior that only creates the "diff" and stores it into a field of your choice on the same record.
PS: You might also want to take a look at the RevisionBehavior.
It also contains some diff algorithm.
Then there is the WhoDidIt behavior which stores the user that last modified the record. In the same table, though. So this combined with the above should do the trick.
Either way:
use callbacks (beforeSave/afterSave) on model itself or (cleaner) as behavior
calculate diff
store the diff in a separate table or as in your case in an extra table field.
Actually writing something up here that does the job is pretty straight-forward.
The voluntary exercise here would be to write it more "generic". Maybe you want to reuse the same functionality again for other models in the future? Copy-and-paste would be pretty bad style then. The goal here would be to create some generic piece of code you can easily reuse. If your initial code works, try to rewrite it into a generic ChangesBehavior that you can attach to as many models you like. You can take the linked examples or take a look at other behaviors out there to get an idea how to do that.
Also you can publish your behavior in github/plugins.cakephp and give the community something back again. Maybe others find it useful, too.

Template Design / Architecture

I am looking into creating something similar to a form template system on my web site.
As an example, say I want the users to be able to create form templates (similar to Wufoo, they can define any number of inputs, etc). Then from these created templates, anybody would be able to use these templates, fill them out, and therefore create a number of form instances (this would be possible for each user-defined template). Also, there would be no limit to the number of templates and instances created.
Purely from a server/persistence perspective, what is the best way of creating a system like this? Would I need to create a new database table for each created template and then insert the form instances as records into the table? How well would this scale?
This topic is very broad. As to the scalability, Wufoo (and other form creation websites) currently work. So a brief answer is, it's already being done, so scaleability shouldn't be an issue. However, random generation of multiple tables will get out of control very quickly.
If you are not at a point where you are having this problem, I would first build the system with single tables and UUIDs for the Primary Keys. This makes them moveable later on. Then, if table sizes become an issue, you can split out the tables anyway you see fit. For example, you can have all of the customes whos last name start with A in the a_forms table.
As for the structure of the tables, you would build these as a ONE-TO-MANY. One form can have many elements. The elements can all be predefined (i.e. text, text area, radio button, check box, submit button, etc.) When someone builds a form, you can serialize() the form elements and save them in the table. When the form needs to be rendered, you unserialize(), parse the elements and build the form.

User configurable forms with php and mysql

An online application we are building (php & mysql) requires users to be able to create their own forms for data capture and record this data in a database, respecting the existing ORM's.
If the forms where "hard coded" then we would simply set the db tables up to store the normalised data ourselves however as our users define the form fields contained in the forms, we're not sure what is the best way to proceed to implement this functionality.
Do we need to think about some kind of meta data or data abstraction layer for our DB? Google hasn't been too much help as we're unsure about how we need to go about this.
Any pointers in the right direction would be gratefully appreciated!
Many content management systems address this problem in different ways.
For example, in Drupal, users can create their own custom content (with custom forms) through the CCK module. The module defines different types of fields that the user can create, then generates tables with specific data types to store the data.
Some tips:
Define your field types - Think about giving the users a choice of different field types (e.g., select box, string, radio).
Create tables for user defined fields - Each field type will have a specific SQL data type. Define a table using these data types. For example, a select box might be mapped to an enum and a input text element might be mapped to a varchar column.
Add data to the new tables - use the new tables to store the data in a somewhat normalized way.
Obviously there are many different approaches, but these are just a few suggestions.
I think I've found a solution to my problem, so for all those people who come along a similar problem have a look at the following artcles -
http://www.adaniels.nl/articles/an-alternative-way-of-eav-modeling/
http://weblogs.sqlteam.com/davidm/articles/12117.aspx
Hope this helps.

MySQL Status Model -- Best Implementation?

So I'm working on a framework-esque system with one of my co-workers. Our current challenge is how to best implement statuses. Oftentimes, a status will carry with it unique data (a color for a table row, or text to be displayed to a user. etc). Currently, we have a statuses table which contains all this data. Contained in that table is a column: "css_class", which, whenever a record has that status, the specified CSS class is attached to the element (in this case a tr). Also, in order to assign another record a specific status, a foreign key is specified in that database table (in this case, a user has a specific status. So in the users table, there is a statuses_id foreign key). This implementation works alright, but there are a few problems. First, what if I need to perform a specific action in PHP if a record is in a specific status? The way we do it now is something like this:
if($user->status==0)
{
//execute some code
}
This really doesn't work well if statuses can change. Change one status, and the associated code either breaks or behaves differently than intended.
The other issue, and the main reason for posting a question is that the table contains the column "css_class". This is very versatile and allows us change the style of a specific status very quickly. But we really dislike the idea of putting code inside a database. Perhaps having CSS classes in a database isn't necessarily a bad thing, but I really don't know what the common practice is. Any ideas?
EDIT:
What I've gathered from the first few answers is that I should keep all my view stuff out of my model stuff in order to maintain an MVC framework. My argument is that if I keep the css_class name out of the database, then I'm checking the status id in the view in order to decide which class to assign it. So if I put the class in the database, I'm putting View information in the Model. If I don't put CSS classes in the database then I'm putting Model information in the View (checking which ID it belongs to). So by not muddying up the Model, I muddy up the view instead.......
The most elegant way I've seen this solved so far (and I've worked with a few MVC implementations now) is to store only the relevant data in the database. E.g. you'd store status="red" in the database, and leave it up to the view to know what to do with a red status, in terms of CSS. The problem is then solved by designing a sufficiently advanced View layer that creates reusable structures -- that way you don't need to always be updating things on a page-by-page basis when the css changes.
Passing this information up to the Model somewhat defeats the point of the content/presentation separation, because now your code needs to know to pull presentation information off the database and forward it along to the View level or, shudder, you'll be pulling that stuff from the database right in your View layer code, which makes maintenance a nightmare, as you've now lost control over the information flow.
If you want to continue your paradigm of storing this in the DB, you could make another table that maps VARCHAR names of the statuses to their corresponding INTEGER IDs.
However, if this was my framework. I would not be storing view information like this in the database. This would be handled by the V of my MVC setup.
From a data modelling point of view:
Have a different table for each "kind" of status; keep user statuses separate from page statuses (for example) - group the like entities together.
Don't put the CSS classes into the database, but use some form of status indicator - this could be an ENUM column, if you know the set of possible statuses up front. Transform this into the appropriate CSS class in the view layer. You don't want to end up in a situation where your CSS can't be changed because some data in the database prevents it.

Categories