Strategy: Unlock document when user leaves a page - php

The current app I'm building is a collaboration app that holds several users in a "team" or company that can access a set of projects. Each project has it's own documents.
I want to protect team users from running in to each other and so I have built a system where documents are locked by the first user to access them. The document is then unlocked when any of the following occur:
The user closes the document
The user signs out and destroys his/her session
The user left without signing out but the session garbage collection unlocks the document
All this works well but one thing is left to fix...
I need to know when the user leaves a project without unlocking the document (basically just leaves the page), since he can walk in to another project and edit another document.
My only option I thought of so far is by catching the http referrer in my base controller class (CodeIgniter MVC) and do a search on the url to see if it matches a project... Then unlock the document.
This is not a strong option though since the http referrer variable is unpredictable.
What would you do? (The same user being in the same document in two windows is an issue that can be ignored)

One way around it would be using the window.onUnload Javascript event to signal back to the server the page is being left. It would be best to use AJAX on the current page to communicate since most browsers will block a pop-up these days.

Keep a reference to the document they're currently editing in your session, and then when a document is open, check and see if it's different? If so, unlock the previous one?

Related

Similar way to PHP Sessions in Zoho Creator

A short tutorial in W3schools about PHP Sessions writes the following:
When you work with an application, you open it, do some changes, and then you close it. This is much like a Session. The computer knows who you are. It knows when you start the application and when you end. But on the internet there is one problem: the web server does not know who you are or what you do, because the HTTP address doesn't maintain state.
Session variables solve this problem by storing user information to be used across multiple pages (e.g. username, favorite color, etc). By default, session variables last until the user closes the browser.
So; Session variables hold information about one single user, and are available to all pages in one application.
I would like to ask you if there is something similar in Zoho Creator. The reason why I am asking is because I have an application with 3 pages (each page has an embedded form). Each page redirects to the other (1st Page -> 2nd Page -> 3rd Page) and passes data through them via openurl. The final result is an HTML Page with the data of these 3 Pages (they have a unique ID).
Let's say that I am in the second page and for some reason (electricity blackout, do another job and close the browser) I want to escape from the application and the next time to continue from the same point, is there any way to do that??
I can suggest you next way
On first page generate unique session Id for the user and pass this id as a parameter to next page in URL. You can crypt in this id pointer to record from first form for example..

How to memorize user's progress through the application?

I'm facing an architecture problem I didn't manage to solve. I'm developing a little game in PHP and Javascript, and I need to save the user's progress. Now, the problem is that PHP can't determine when the user wins the level: it's done in Javascript. Is there any way to save the user's progress when he wins a level?
For example, when the user wins level 1, he gains access to level 2. If he tries to access level 2 without having completed the previous level, he gets redirected to the last completed one. In my controller I was doing the following:
if (1 !== $id) {
if ($app['session']->get('last_level') !== ($id - 1)) {
// redirect the user
}
}
Now I need a way to store the last_level value into the session, an operation that can't be simulated by the user.
Any hints?
You're going to want to do the different last_level calculations on the server. That way the user can't hack around with the JavaScript, and submit something on a specially crafted form. So depending on what your storage system is (KV store, Database, Textfile, etc.), put that value in there, and retrieve it.
Ajax can help you out, but isn't necessary. It depends on how your game is set up. But if they complete the level, the server needs to be notified.
If a user completes a level and then stays on the same page doing additional work:
Then you'll probably want Ajax to send the new level info to the server as soon as the new level has been achieved. Thus:
Use cookies to store your php session id
From your Javascript client, use Ajax to invoke a php url on your server whenever the user wins a new level. Send the new level as a parameter. Can use POST or GET, doesn't matter.
The php program will receive the session id in the cookie, and the new level as a parameter. The php program will look up the user id from the session id, then store the new level the database.
Next time the main url of the php program is invoked, it will be able to look up the user's level.
If the user presses "Next" button to go onward to the next level:
Use Javascript, not Ajax, to change the POST parameters of the "Next" button.
You'd use POST, not GET, since seeing a url of foo.com/game?level=5 is a bit too obvious for people to cheat your game. POST will not show the level parameter in the url. More security: add a checksum parameter.
If any of the above is not clear, ask in comments or as a follow-up question.
If you're happy to take javascript's word for it that the level has been completed then just set a cookie from javascript.
an operation that can't be simulated by the user
Sorry - but if it's javascript which dtermines when they've completed the level then there's nothing to stop the user falsifying the results.

jQuery/PHP session management by URL (or just specific serialization?)

My application is JavaScript and jQuery up front, PHP in the back. I'd like to implement a URL- or parameter-based session management system so my users can save/share their results. Most of the solutions I've seen involve cookies, but I want anyone (e.g. anyone my user gives a link to) to be able to open up exactly where the user left off.
Example:
User A goes to www.my.url and interacts with the page. Variables are set (mostly via jQuery) et al. User A then decides he wants to share what he sees with user B. He clicks a button and is issued a URL.
User B gets the link from user A and goes to www.my.url?session=[randomness] or www.my.url/?[randomness] (either would be okay). User B picks up exactly where User A pressed the button to issue the link. User B continues to interact with the page.
User A goes to the same URL and picks up where he pressed the button. He then interacts with the page. User A's and user B's sessions do not share anything and the actions of one do not have any bearing on the other - each "real" user session is strictly a sandbox again after the URL is passed and delivered.
User A and B both go to www.my.url (without a session identifier) and get the 'factory' startup as User C does.
Also none of these user actions have to (or probably will) happen concurrently. I can use file-based or mySQL for session (and content) serialization. Currently using CSV for 'factory' reference data (search base) and no need to jump to a DB.
Does anyone know of a practical all-up example here? Or a set of tutorials to help me get started? Is 'session management' really what I'm asking for or is it just serialization via URL(ish)? Is there a better way to search/ask for what I need?
Thank you, any help is appreciated here as this shareable aspect will be huge for my application.

User Friendly Video Review with Locking

We have a jquery/php/mysql system that allows a user to log in and review videos built by a system for online viewing. When a user begins reviewing a video, the video is marked as such. But now we've cornered ourselves into the classic browser-based application problem of the user navigating away or closing the browser without completing review. That video would then enter a state of limbo of constantly being reviewed, but never completed, and never re-entering the queue.
Options we have are:
Build a service (which we already have others) to find review sessions that are outside a duration boundary and reset them back into the queue.
Reset review sessions outside a duration boundary when that user logs in. Essentially, if a user locks out a video for review, it'll be unlocked the next time they log in.
A suggestion made to me was to use the php/apache session length and on expiration, reset any pending review jobs. I don't even know where to look to implement this as this is one project on a shared server, so it shouldn't be an apache config, but the reset mechanism would need to know the database credentials to be able to reset it...
The worst solution everyone hates is preventing the user from navigating away with javascript, asking "Are you sure?!"
This system is used by a few hired reviewers, so I'm not exactly dealing with the public here, but I can't prevent users from sharing logins for speedier review, which would knock out the 2nd option above because it would unlock a video being reviewed by someone else using the same login.
There are two good options that won't tax your server. Either:
Run a cron-job every hour looking for review sessions that are outside of the duration boundary. This has the advantage of being transparent to the end user. But it's possible to kill an active session if you're not careful (Suppose the user is operating in multiple tabs).
Prevent users from navigating away with JS. Honestly, this is what I would do since the user is reviewing the video (if they were just viewing it, that would be bad, but since they know they are supposed to be acting, it's ok). Just say If you leave now, the review will be canceled, are you sure?.
Honestly, I'd do option #2. SO uses it, and it works well here. It wouldn't be for every page, just those where there's an active review going on...
When a single video is reviewed on a single page by one person. You can capture the JavaScript unload event which will be fired when the page unloads and the client is leaving the page. Than you can change the state of that video or even show a dialog and let the user decide.
Maybe a ping-pong system may help. In the back you make AJAX calls binded to a video by an ident. When that activity stops, the users stopped. A background process can look for latest ping and when that is, for instance, a hour ago, change it's state.
Your first option is your best bet. You can have a javascript timer on the page updating the lastestActivity record for the video while the browser window is open So you won't get into the corner of a review that takes too long and the unlocker releases the lock prematurely.
Option 2 is problematic for several reasons, some have already been mentioned but taking into account that a reviewer might not log in for a few days (vacation?) will unlock a video for too long unnecessarily.
Option 4 (Javascript onBeforeUnload) Won't cover you in the common cases of a browser crash, OS crash or a power failure. but it is something you can implement in addition.

How can I add a parameter to the manifest file HTML5 for offline mode?

I have a web application and I want to make it run offline as well. In this application I just have a form and I am using PHP for submitting it. I am using a manifest.php file like the one described in http://building-iphone-apps.labs.oreilly.com/ch06.html .
The problem is that I need somehow to add the parameters from the form in the manifest, for caching the right file, for example the file welcome.php?name=aaaa and not the welcome.php . So I need to use a GET for the name in the manifest.php. But if I understood well the manifest file is created in the beginning before the form is submitted so the value on "name" is empty.
Is there a way to add these parameters in my manifest file for running the application offline as well?
Thanks
The only way you can do that is to list the files with their parameters in the manifest, so you would have to know all the possible parameters in advance and then use your manifest.php to spit them out, ending up with a manifest file that looks something like this:
CACHE MANIFEST
welcome.php?name=aaaa
welcome.php?name=aaab
welcome.php?name=aaac
...thousands more lines...
welcome.php?name=zzzz
NETWORK:
welcome.php
However, I strongly recommend you don't do it this way if (as it looks like) you want to present a personalised welcome page to the user. With this approach every user will download every welcome page, even though they only need to see one of them.
There are two approaches I think will work better:
1: Deliver personalised pages
If only thing which changes is this page, force the user to logon before accessing the welcome.php page, then use a session variable instead of a query parameter to deliver the personalised page. You then just need to specify welcome.php in your manifest and every user will cache one personalised version.
2: Write a full offline app
If your web app is going to have user specific data at every step you need to break down what are the common application components and what is the user data, and serve them separately. If your app is going to do anything offline it's going to be doing it with JavaScript, you should therefore use JavaScript to update the page in the browser rather than generating entire pages on the server side with PHP.
Most of your PHP pages are basically going to be templates which you will load with user data through JavaScript (you can still populate them the 'old' way for users who don't have offline capability in the browser). You will have at least one PHP page which delivers data in response to AJAX requests. For this approach you're going to need to learn about Local Storage and the various JavaScript APIs for managing the cache and detecting offline state. Once the user decides to install the offline version of your web app you download all of that user's data and put it in Local Storage, then use that data to update each page as it loads when the user is offline. Any changes made then need to be synced back to the server when the user is back online.
Due to applciation cache is loaded after the page it references to. You have to reload the cache by applicatonCache.update() when the parameters are available.
The trick to inject the parameters into the the manifest is to set cookies before invoking update(). Your serverside script gets the cookies and can generate the appropriate manifest content.

Categories