First of all, I'm using KohanaPHP Framework.
I've impletemented SWFUpload successfully, working quite nice. I'm having only one issue.
The main problem is I need to allow users to upload attachments before submitting form. So I decided to use Session var to store attachments array. Unfortunately, it is working inly if I use HTML upload (based on iframe), but not when I use SWFUpload.
I tried to Google for that, but without any working solution. Any ideas?
Update & Solution
Basically, I didn't know there's an issue with Flash and sessions. Providing the same session id didn't helped me because I got unlogged. Anyway I got a solution for people with the same issue.
I created an unique ID of an item. I upload files to temporary directory, then... I'm scanning this directory and I'm adding uploaded filenames to session.
Tom
What you need to is pass the session id to SWFUpload by hand. In a nutshell, you do this in your template:
<script type="text/javascript">
var PHPSESSID = <?php echo json_encode(session_id()); ?>;
</script>
Then you do this with your SWFUpload code:
var settings = {
post_params: {"PHPSESSID" : PHPSESSID},
/* the rest of the settings */
};
And finally, in your application code, before you call session_start, you need to do this (usually just in your index.php or whatever bootstrap you use):
// Restore session that came from SWFUpload
if(isset($_REQUEST['PHPSESSID']))
session_id($_REQUEST['PHPSESSID']);
After this session_start() will use the correct session even for SWFUpload requests.
Related
I have a download.php page which will be invoked everytime a user clicks "Download" button on my page. The file is around 1 GB. However, the current page got blocked before the file is completely downloaded. Is there a way I can make this an async task so that the user can still use the website while the file is being downloaded to his computer.
Thanks.
If you are using sessions, then before you begin any long running process you should call session_write_close() or you will get blocking site-wide. From the docs there:
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time.
So, if you have a long running script that called session_start() and did not call session_write_close() then the result is, any page that needs to access a session now has to wait for the long running script to finish execution before it can begin. Thus, site-wide blocking.
This may or may not solve your issue, because I'm not sure what you mean by "blocking" in your question.
First Create your download links like this :-
<a class="download" href="/myfiles/video/file.pdf"> Dow
nload file.pdf
then in Jquery :
$(document).ready(function(){
$(document).on('.download', 'click', function(){
var href = $(this).href;
$('<iframe />', { src : href }).appendTo('body');
return false; // prevent from default action, can be done with e.preventDefault() also
}) // __download
}); // __ document ready
This technique use by many big sites like facebook, github etc, and it will not block current page, everything will be working like before but browser will show file save dialog to download file, I did not test this code so there may be some syntex error, Thanks :)
So in my HTML markup I have an image tag like this one:
<img src="image_generation.php" alt="template" id="image" />
And the 'src' attribute links to a PHP script that generates an image using a couple of variables defined there which are mostly randomly generated.
Now, what I want to be able to do is to access those random variables in the page which includes the image generation script. I suppose I could send cookies and access them after the image tag as they technically should be readily available to the including file. I don't want to send too much information, just a couple (10-20) variables. Not sure if in that case sessions would be a better choice, as I would have to send several cookies. Sessions also pose a problem as the including script gets the old session and I would have to refresh the page to obtain the values of the previously generated image. I suppose I could also set up a DB and access the DB in the including script, but the variables are temporary and I would have to delete them and that seems like a lot of fuss to me.
The image generation script finishes with:
header('Content-type: image/png');
imagepng($image);
imagedestroy($image);
And nothing can be sent to the browser before the header call or else the image won't be displayed. If I use cookies or sessions, the image_generation.php would have to send both the image and set the cookie(s)/session.
None of the options (cookies, sessions or DB) really convince me, as there are problems with each in this particular situation. Can you think of a way to solve this? Thanks.
MAJOR EDIT #1:
Including script gets session of previously generated image without refreshing / Setting cookie(s) and/or a session in included script before / after sending image without output buffering does not pose a problem.
You can use a $_SESSION, but to make the session available in the same script that included the <img> tag (which would have executed before the image script), you would need to make AJAX calls via JavaScript. An AJAX handler that runs at window.onload should have access to the $_SESSION created by the image script, since the image should have fully loaded when it executes.
Example PHP handler getsession.php:
header('Content-type: application/json');
// Simply part of the session into JSON
// Obviously you would want to limit this to only the variables
// that should be sent back, so you don't expose the session on the client side!
echo json_encode(array($_SESSION['var1'],$_SESSION['var2']));
exit();
Example AJAX call (using jQuery since it will be easy to get started with)
// Variable to hold the object returned by PHP
var imgPHPSession;
$(window).load(function() {
$.ajax({
url: 'getsession.php',
dataType: 'json',
success: function(data) {
imgPHPSession = data;
}
});
});
Update:
It can be done entirely in PHP, but would require changing your design a bit such that the variables necessary to generate the image are created in $_SESSION by the main script. They are then available in $_SESSION to image_generation.php to be used as needed, but are already known to the main script.
Update 2:
Since the image vars contain info about how it was created, if the image is not too large, you can actually create it in the main script and store it to disk. The image_generation.php script can still be used as the <img src>, but its purpose would then be to retrieve the correct image from disk and serve it back to the browser and delete it from disk when no longer needed. The $_SESSION is then available to both the main and image scripts.
You can pass you parameters to src attribute, for example:
<img src="image_generation.php/user/1/name/tom/param1/variable2"
or
<img src="image_generation.php?user=1&name=tom
this solution lets you forget about session, cookies - it's stateless
Php can do smart tricks with buffer by ob_* function, so at the beginning of your script you can call ob_start() to buffer every php output, it lets you avoid all 'Header already send' errors.
Your image_generation.php does not need to send any cookie. This script will receive cookie with sessionid (browser attach cookie information to every request to the server) what makes possible identify user session on php side - after that you have access to every session parameters.
I am using Codeigniter with the TankAuth library installed and trying to upload to index.php/requests/doUpload from swfupload but can't access the page as authenticated. I have read many posts around the net about similar problem and tried to set $config['sess_match_useragent'] = FALSE; but still no difference. I have ended up skipping the login check in my controller for testing purposes. But now I need to access tankAuth library from my controller to get the current logged in user ID. It is requested in my application and cannot skip it, I really need to pass the logged in user id to that doUpload model. I have setup controller like this:
function doUploadFileFn() {
if (!$this->tank_auth->is_logged_in()) {
return;
} else {
$user_id = $this->tank_auth->get_user_id();
$this->load->model('requests/doUploadFile');
$this->doUploadFile->uploadData($user_id);
}
}
Now, it does not pass the is_logged_in() check, as I learned from other posts, CI deletes the session but I have setup the config not to match the user agent but still not working.
Is there any solution to this out there ?
Following the tutorial in the CI forums I was able to achieve what you are asking for.
1) Put this in the SWFUpload JS config:
post_params: {"<?php echo $this->config->item('sess_cookie_name'); ?>" :"<?php echo $this->session->get_cookie_data(); ?>"},
2) And place the MY_Session.php file in your application/libraries/ folder.
3) The new library should be loaded the moment the view is loaded if not (for some reason) then load your library in the controller.
P.S: You need to set:
$config['sess_match_useragent'] = FALSE;
Otherwise a new session will be created for a useragent Shockwave Flash
EDIT: Okay, based on your comment..you really need to set your post_params setting to your current session so it can be sent when the flash post to your controller, now in your case the best thing I could think of is the below:
Your externalUntouchableJsFile.js:
// JS scripts...
...
var swfu = new SWFUpload({
...
...
post_params: GLOBAL_VAR,
...
});
...
// rest of your JS
And in your PHP view and before loading this JS file have something like:
<script>
var GLOBAL_VAR = {};
<?php if(session_is_there) { ?>
GLOBAL_VAR = {"<?php echo $this->config->item('sess_cookie_name'); ?>" :"<?php echo $this->session->get_cookie_data(); ?>"}
<?php } ?>
</script>
<script type="text/javascript" src="<?php echo base_url() ?>path/to/js/externalUntouchableJsFile.js"></script>
EDIT 2: Since you are using an external js file, you may forget to define the global variable so use:
post_params: (typeof GLOBAL_VAR === 'undefined') ? {}:GLOBAL_VAR,
It bears mentioning that the Flash file should be served from the same domain as your CI site or one won't be able to read the other's cookies. Also make sure that the login cookie path is set to the root path. If SWFUpload can not read the login cookie, it can not send it either.
Flash has limited access to session cookies, as documented here in the SWFUpload forum. Is it possible that you've set the auto login to avoid setting an expiration (in config/tank_auth.php), thereby making it a session cookie? If that is the case, then the SWFUpload SWF may not be able to access or send the autologin cookie value, depending on the version of Flash player on the computer. Double-check your cookie expiration values using a debug tool like Firebug to see if this is the case. If the upload works when you check a "remember" me box but not otherwise, that would indicate a session cookie problem.
To force the SWF to pass the TankAuth cookie value on file uploads, you could first overload the cookie helper get_cookie function to look in either the $_COOKIE array or the $_POST array for values. Then, it appears that with SWFUpload v2 you can send additional POST values along with the upload, and this would be the way to send the autologin key, which would then allow your controller to get the user_id. But before hacking the Cookie helper, make sure your moving parts are working first, as described in the first paragraph.
I have managed to apply a rough fix for this by passing the logged user ID in the URL, and getting it from Javascript with URL functions. It's the best method I can rely to right now, it doesn't bother me too much that the user ID is visible because I'm using a managed iframe to display that specific part of the app and the app is for internal company use only.
Thanks for your answers.
I am using PHP and jQuery for an uploader. I am having a huge problem though and would like some input as to how best handle these two together.
I am using a PHP session variable that I am using to change the filename after the jquery uploader has finished. The jquery "url" is pointing to a PHP function that handles the actual upload. When I use the jquery uploader to upload an image, the session variable is never available. I'm assuming because the uploader itself is not using a session.
How can I resolve this issue? I need to have that session variable to change the filename.
EDIT: I am using jqUploader
Here is the code
function jqUploadPhoto( ){
$picSize = '50550500';
$picDir = '/photos';
$temp = $_FILES['uploadfile']['name'];
... substr()... convert old name to new name
$file = $_SESSION['name'].$ext; // This is set and can be echoed when this func is used from a browser. Not available in JQ
if (move_uploaded_file($_FILES['uploadfile']['tmp_name'], $file) == false){ // This dies because the filename isn't available.
echo 'NOTOK';
}
}
I had this issue with Uploadify.
The problem
Your browser makes a request to your site, the session is started and a cookie containing your session ID is set.
You then make an upload using Flash, note that Flash is not your browser and it acts as a new request. So a new session id is created and a new cookie is created, giving you two different sessions.
The solution
I got around this by setting the session id in the page, eg. in a hidden input and appening this session id to the request when Flash makes the upload. You need to detect this session id when you upload and set it using session_id() - http://php.net/manual/en/function.session-id.php . This will then replicate the session that the browser created.
Hope that helps.
I have a flash upload script, that uses a .php file as the processor. I need the processor file to set a cookie with a gallery ID that was created by php script, and pass it on to the confirmation page. Except when Flash runs the php file... it doesnt set the cookie. It does set the session variable, which was good enough, but now Im using lighttpd for the site (including the confirmation page) and apache for the actual uploader processor script (because lighttps sucks at uploading large files), so the session vars don't get transferred between the 2 server software.
How can I transfer a variable from the php processor (running on apache) to a confirmation page running lighttpd?
Well I would assume that it doesn't set a cookie as it was called by a flash script not a browser, and cookies are stored by the browser.
The only ways I can think of are a mysql database, or simply a text file.
Just thought of a second solution which is probably less efficient than Nico's but may be better suited to you. If the cookie being sent to Flash isn't being sent to the browser also, you could use Flash's ExternalInterface class to pass the contents of the cookie to a javascript function which would set the cookie in the browser. Or you could call a javascript function which will make an AJAX call to fetch the contents of the cookie.
Not sure if we're doing the same thing, but I had a similar problem, not being able to set a cookie from a php script run through flash. However I later realized it failed because I was missing arguments.
flash.swf:
sendToURL('script.php?val=dataFromFlash');
script.php:
//setcookie('flashData', $_GET['val']); //this did not work
setcookie('flashData', $_GET['val'], '0', '/'); //this worked
The PHP manual says that only the name argument is required, but I had to specify the expire and date arguments to get this to work. Perhaps this is because, as Nico's answer indicates, it is not sent through a browser? Anyway, hope this helps.
here find best solution for store all upload images data in flex with php script
$array = array();
$array["large_filename"] = $image_file_name;
$array["large_path"] = DIR_WS_IMAGES_TEMPIMAGES . $image_file_name;
$setcookie = serialize($array); setcookie( "ImageCookie",
$setcookie, time()+(60*60*24*15) );