Rollback and Preview in a CMS - php

I am creating a CMS and am using serialize to handle publish and rollback, which seems to work fine. Basically, The normal site tables are what gets displayed and anything not displayed is serialized in a separate table. The problem however is in making the 'Preview' functions work.
Since the front end is created using normal SQL calls, and all the pre-published/rolled back data is in a separate table it would mean updating every sql statement with some fancy code to pull the version correct to the preview. It will also get especially problematic with things like limits etc and would be a nightmare for the front end.
The only other approach I can see is a separate database/table(s) for the preview copy, but many people may be using the preview function and I am loathe to create a duplicate database for every person using preview as it will very quickly get out of hand.
Is there any way of doing this that will allow preview, and rollback preview, but will not require much from the code that displays the contents of the database and also avoid the problem of mass duplication?

I'm not sure that storing your content data in more than 1 table depending on its state is the way to go.
I would store every version of the content in the same table, having a field which purpose would be to set the state of the content (old version, current version, currently being edited, whatever you want depending on your content editing workflow). That kind of status field plus a date date, would make your content versions way easier to manage.
I used this method for various applications, and was always satisfied with how easy it was to implement rollbacks, previews and even more complex stuff (cvs-like pseudo-branches, ...).

What eWolf means is that when you have a seperate model and view you can have your model supplying different data to the view and then you don't need to copy your database, but instead simply create a standard and a preview model.
The preview model doesn't have to make queries to the database but instead delivers the data that you store in it before passing it to the view.
Consider this example:
//in the controller:
$previewPage->setTitle("foo");
...
//in the view(when previewing):
$previewPage->getTitle(); // returns whatever you stored beforehand
//in the view(regular viewing):
$livePage->getTitle(); // queries the database and returns the result
To learn more about the Model-View-Controller pattern you might want to check out this article.
I hope that helps.

If you seperate Model, View and Controller, this should be no problem: You just take the model from somewhere else in the controller and pass it on to the view.

Related

Loading/saving PHP objects to MySQL database

I have an object for a „listing“, which has attributes like id, name, description, etc. which can be loaded via load($id) method.
It has some advanced attributes, too. For example multiple products (which is a separate object). To improve performance, I load them when you try to access them with listing->getProducts().
Now I want a save method in listing, to save the values back to the MySQL db. But I‘m not sure how to do that product saving in a clean way.
The best way would be adding a save method to products object and call it from the listing object, but that only saves the values. How do I handle added/removed products? That has to be done by the listing object I think. But how do I know if all products were removed or if they weren't even loaded (because they didn’t get accessed)?
All ways, like storing a boolean loaded products seem like a stupid solution. Do you have a good idea how to handle that? I‘m not inexperienced in coding but I want to improve my structure since I always end in a lot of code mess if projects get bigger.
I assume we are talking about adding, editing, and deleting products in your database. So you are probably going to need an 'insert' method and a 'delete' method (invoked from your list view). as well as the 'save' (update) method.
But the problem, or so I understand, is that you don't know which of these to use on a particular product line.
If you are just allowing the user to type willy nilly into input fields, so that you can't tell whether this is an edit, an insert, or a delete (or indeed which product you are editing or deleting, if you allow /every/ field to be changed) then you are making your life really complicated - is this necessary, from a business requirement/UI design perspective?
Consider something like listing the existing information read only and providing edit/insert/delete buttons.
I think I found a more or less good way on my own.
For the first problem (where to save what):
Storing of basic attributes of listing in the listing->save() method,
calling listing->products[]->save() to store products details,
syncing the listing<->product associations in listing->save().
Second problem (Deleting products, just because they didn't got load):
That was pretty easy, listing->products = null -> not loaded, listing->products = array() -> loaded, but empty. (I should got this earlier, haha)

Are PHP Models ( MVC ) Specifically Designated for DB Interaction Only?

I am currently working on a personal project. The entire site is dynamic so I am requesting all sorts of information from the database on all pages. I noticed that I was duplicating specific code to display the data to the pages. A few examples would be applying htmlspecialchars to the data or iterating through to set image paths, etc.
What i am wondering is if this is a bad decision to make so I can course correct early on. Most internet resources have said that the controller manipulates while the model fetches, updates, inserts, etc. into db. BUT it just makes sense at least for me anyway to manipulate the output data via model since all pages will use it in the same way.
No. A model merely represents data, whether that came from a database, an XML file, a web service/API, or even just an array.
If you find yourself doing the same thing over, then it’s time to re-factor and DRY your code out. For things like sanitising data, you would normally have a presenter that takes your model, and returns it data sanitised however you wish. That way the model has its single responsibility (represent data), and your present had a single responsibility of transforming data.

To what extent is duplicate code OK in a model with CodeIgniter?

This is a long running question that gets me every time I am developing.
I suppose it is not specific to CodeIgniter, but as I am using it, I will consider it in my example.
Firstly, which is better:
function add_entry($data_array)
{
//code to add entry
}
function edit_entry($data_array)
{
//code to update entry
}
OR
function save_changes($what,$data_array)
{
//if what == update update
//otherwise insert
}
Both produce the same action, but does it really matter which one you use?
Getting onto more complicated things.
I have a page where I need to get ONE entry from the database.
I also have a page where I need to get all the entries from the same database ordered by a user specified column.
My resultant method is a function similar to
function($data_array,$order_by='',$limit='')
{
//get where $data_array
//if order_by!='' add order by
//if limit !='' add limit
}
As I develop my application and realise new places where I need 'similar' database functionality I am what feels like hacking previous methods so they work with all my case scenarios. The methods end up containing lots of conditional statements, and getting quite complex with in some cases 4 or 5 input parameters.
Have I missed the point? I don't want duplicate code, and when for the most part the functions are very similar I feel like this 'hacking' methodology works best.
Could someone advise?
Finally my admin functionality is part of the same application in an admin controller. I have an admin model which contains specific methods for admin db interaction. I however use some model functionality from 'user' models.
FOr example if on an admin page I need to get details of a db entry I may load the user model to access this function. There is nothing wrong/insecure about this..? right?
In addition to that within my admin model itself I need to get data about a user database entry so I call my user model directly from my admin model. This is strictly OK, but why? If i need data and there is already a method in my user model which gets it.. it seems a little pointless to rewrite the code in the admin model BUT each time that function is called does it load the whole user model again?
Thanks a lot all.
In order, add edit in the model vs save. Personally I have a save built in MY_Model that chooses whether it is a save or an edit depending on the existence of a primary key in the data being passed, so obviously I prefer that method it means a lot less duplication of code since I can use the save for any table without having functions in the model at all.
As to the second question I think it depends on situation. I also have a number of functions that have a ton of conditionals on them depending on where they're used and for what. In some cases I'm finding this makes the legibility of the code a little rough. If you're running them all through if statements it also could be impacting performance. DRY is a concept, not a rule and like other design concepts there are times when they just don't make sense, it's like database normalization, it's my personal opinion it's VERY easy to over normalize a database and destroy performance and usability.
Finally, using user functions in the admin code. I don't see an issue here at all, the reverse probably isn't true, but rewriting a function just because it's an "admin" function, when it's identical to a user function is utterly pointless. So you're correct there, it's a waste of time and space.

how to pass a list of values to a method, Codeigniter style

What's a good way to pass a list of items 2-3 items to a method in my controller?
I was thinking of just using the URL.... like so:
http://myserver/myapp/mycontroller/mymethod/parm1/parm2/listitem1/listitem2/listitem3
Is there a better way to do this? This data is not coming from a form, but rather from a database query and I'm building a hyperlink with it.
I guess the only part that bothers me is that I won't know in advance how many items I have when i'm parsing this url.
Its possible that I'll get none, or all 3 or some value in between. So the method that then has to parse this url will just keep looping until uri->segment() returns false, indicating that it's hit the first empty uri segment.
Any suggestions would be appreciated.
Thanks
EDIT 1:
Just in case it wasn't clear, my model is getting the data from the database and will also build the list.
The question is really about parsing an undetermined number of uri segments.
Just wondering if there's a better way to do this.
Thanks!
EDIT 2
Here's some more information to help you understand my MVC app. I don't think my issue is the way I've organized my code as far as who is doing what.. But just in case it helps...
I have methodA in my model that queries database and passes back to my controller listitem1, listitem2 and listitem2.
The controller then builds a string that represents a URL like:
http://myserver/myapp/mycontroller/methodB/parm1/parm2/listitem1/listitem2/listitem3
Then the view display a hyperlink using the url above.
When the user clicks on this hyperlink, it calls methodB.
In methodB, I since I don't know the number of items, I will just loop through all segments until I hit my first false.
As far as why I need to do this / what I'm doing... here's some background info:
I'm query a database for a list of ports on a switch that are considered trunks - ones that should not be modified.
this is what method A does.
methodB run a command against a switch and it returns a bunch of data back. the view that displays the data from methodB will allow the end user to make further changes to the switch. before I display the data from methodB, i want to filter out the list of ports I got from methodA so they cannot be tampered with.
Hope this helps.
Edit 3
I need both methodA and methodB because they serve two different purposes. methodA displays summary data about ports from my database. Think of methodA as a function that shows documentation about the switch. The view for methodA in turn, provides "live" links to communicate with the actual switch - this is where methodB comes in. methodB is triggered by one of those live links and it goes and gets a list of ports - similar to methodA - except that it represents what actual, and it doesn't include user defined information about the port.
I guess I can have methodB communicate with my database and filter its data before it displays, but if i want to treat these two functions as separate APIs... aka - one set of functions get data out of the database, the other set is a tool to communicate with switches... - then i don't think i want one talking directly to the other. I would like the GUI to tie them together. In fact, i have created two separate models and controllers for what I'll call the database interface, and then the switch interface.
So far, i think the forms idea is the most elegant solution.
Thanks everyone, for reading.
place number of listitems as parametr 3
../mymethod/parm1/parm2/numberofitems/listitem1/listitem2/listitem3
and put 1, 2, or 3 as needed. In case when 0 put nothing - null, however make sure that controller would know what to do if null happend - do not expect items.
If the data is coming from a query it should be within a model in CodeIgniter if you wish for your application to truly MVC compliant. This might mean a restructuring of your application, which may be difficult but it would really benefit you in the future to create a model for all your database queries.
You can read up on codeigniter models here:
http://codeigniter.com/user_guide/general/models.html
And you can read up on the database class here: http://codeigniter.com/user_guide/database/index.html
I really suggest you do this.
If your data is already coming from a model you can call it by including the model:
$this->load->model('model_name');
$response = $this->model_name->model_function(parameters);
Edit: This would also solve the issue of an unknown number of list items as you can simply parse the response returned from the model function instead of trying to figure out a uri hack.
After reading all of the other answers + edits over, that's definitely not the way you want to do it.
Unless I'm misunderstanding your comments, here's the issue: The list of ports is domain data stored on your server. So why then, are you going to pull that data out, send it to the presentation layer, and show it to the user who will send it right back to the application? Skip the middle-man and have "MethodB" get that data.
Your "MethodB" should get this information itself before processing what it needs to do - domain data stays in the domain layer, and the view never sees any of that information directly (the user would see a link directly to "MethodB")
Alternatively, you could do this all in one query if your DB schema is conducive to such a join.

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