SitePoint Sponsor

User Tag List

Results 1 to 17 of 17
  1. #1
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Make downloadable products available automatically

    Without going into great detail, customers will use my web site to process documents. Once processed I'd like to make a document available only to the particular customer who provided it, as a monthly paid subscriber.

    Is there any way to make downloadable files available to customers, through a program automatically and securely?

    In other words, Customer A's document is processed and is sent to a folder only he can access via an automatically emailed link.

    Customer B's document is processed and is sent to a folder only she can access via an aoutmatically emailed link.

    etc.

    Any assistance will be appreciated.

  2. #2
    SitePoint Wizard cmuench's Avatar
    Join Date
    Jul 2005
    Location
    At my computer
    Posts
    2,251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it would be easier to control access to documents via a database and then only show documents that are associated with that user.

  3. #3
    SitePoint Evangelist
    Join Date
    Apr 2006
    Location
    Halifax, Canada
    Posts
    498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could store the documents in a folder that is not public, and write a PHP script to load the files and pass them to the browser after verifying the user's credentials. If you are using large files or expect a lot of traffic, this isn't the most desirable way to do things, but on a smaller site it should work fine. If you are by any chance using lighttpd, use the mod_secdownload module. I'm not sure if there is an Apache equivalent.
    Paul Butler.org
    JSSpamBlock - Reduce WordPress spam.

  4. #4
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks

    Thank you for your reply.

    The files aren't large, but there may be a good amount of traffic.

    It's probably good advice, but I really don't know about lightpd or passing the file to the browser.

    I'd appreciate clarification, additional info or different suggestions. Thanks.

  5. #5
    SitePoint Zealot
    Join Date
    Mar 2007
    Posts
    192
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by paulgb View Post
    You could store the documents in a folder that is not public, and write a PHP script to load the files and pass them to the browser after verifying the user's credentials. If you are using large files or expect a lot of traffic, this isn't the most desirable way to do things, but on a smaller site it should work fine. If you are by any chance using lighttpd, use the mod_secdownload module. I'm not sure if there is an Apache equivalent.
    what would be the most desirable way to do things?

  6. #6
    SitePoint Guru
    Join Date
    Nov 2004
    Location
    calif
    Posts
    723
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not a programmer, but,

    Maybe a script could be written to automatically create a customer subfolder (in a non-public folder) each time a customer registers.

    And possibly a line of code could be created for your web site to forward the unique customer's processed document file, to his unique subfolder, at which time he's emailed, with a link to the newly arrived file.

  7. #7
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    writing a script

    Thanks for that idea.

    Any php experts know how to do the following?


    "a script could be written to automatically create a customer subfolder (in a non-public folder) each time a customer registers.

    And possibly a line of code could be created for your web site to forward the unique customer's processed document file, to his unique subfolder, at which time he's emailed, with a link to the newly arrived file."

    All help is appreciated...

  8. #8
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Create the directory when signing up (makes sure to have write permisions):
    PHP Code:
    mkdir('/home/mysite/files/'.$username);

    //...
    //add the user to database
    //... 
    Upload user files to that directory and to download use readfile:

    PHP Code:
    //file.php?id=123

    $id=(id)$_GET['id'];

    //check the permissions and output the file
    //...

    $filename='/home/mysite/files/'.$username.'/'.$file;
    header("Content-Type: application/download");
    header("Content-Disposition: attachment; $filename");
    header("Content-Length: ".filesize($filename));
    readfile($filename); 
    Saul

  9. #9
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks, but I have questions...

    Thanks a lot for posting that code: mkdir('/home/mysite/files/'.$username);
    I really appreciate it.

    I hope you don't mind me asking for some clarification.

    How would I use this code to 'create the directory when signing-up" in a non public folder?

    Would it be:

    mkdir('/home/files/'.$username); ?


    And the other code that you posted:
    //file.php?id=123

    $id=(id)$_GET['id'];

    //check the permissions and output the file
    //...

    $filename='/home/mysite/files/'.$username.'/'.$file;
    header("Content-Type: application/download");
    header("Content-Disposition: attachment; $filename");
    header("Content-Length: ".filesize($filename));
    readfile($filename);


    Does this force a download once a file arrives into the directory, or does it send a link for the download? Either way, does this code specify where to send the download or link?

    Thanks again lots and lots

  10. #10
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by alex111 View Post
    Thanks a lot for posting that code: mkdir('/home/mysite/files/'.$username);
    I really appreciate it.

    I hope you don't mind me asking for some clarification.

    How would I use this code to 'create the directory when signing-up" in a non public folder?

    Would it be:

    mkdir('/home/files/'.$username); ?
    The path is an absolute path to that directory. In the example, your public directory would be /home/mysite/public_html. You could also use a relative path, ex. ../files (given that the running script is in the public_html)

    And the other code that you posted:
    //file.php?id=123

    $id=(id)$_GET['id'];

    //check the permissions and output the file
    //...

    $filename='/home/mysite/files/'.$username.'/'.$file;
    header("Content-Type: application/download");
    header("Content-Disposition: attachment; $filename");
    header("Content-Length: ".filesize($filename));
    readfile($filename);


    Does this force a download once a file arrives into the directory, or does it send a link for the download? Either way, does this code specify where to send the download or link?

    Thanks again lots and lots
    file.php?id=123 is a link to download the file. Obviously you'd need some kind of authentication, otherwise it's easy for anyone to "figure out" the link and download the files. Or you can generate a token to use instead of the id, so that it's virtually impossible to "guess" the link.
    Saul

  11. #11
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks

    Thanks you've been exteremely helpful. Much thanks.

    I'd like to ask you, or anyone else who'd like to reply,

    I would like to test this and add this code to the registration page of CubeCart, ecommerce package. When I open up the Registration Page the browser shows:

    http://www.webssite.com/catalog/cart...tjYXRJZD02Mg==

    So, I'm not sure of a couple of things. First what page(file) would I add the code: mkdir('/home/mysite/files/'.$username); to?

    And, about where on the page would I add it?

    And, once it's added, will it create a sub-folder, named after the username, upon a completed registration when the customer selects Submit?

    Thanks again.

  12. #12
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I'm not familiar with CubeCart, but you should look for the place the user is added to the database. You should find the username variable there too.
    Saul

  13. #13
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks again

    thanks again

  14. #14
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    custom coding

    Quote Originally Posted by php_daemon View Post
    I'm not familiar with CubeCart, but you should look for the place the user is added to the database. You should find the username variable there too.
    I asked in another forum about this whole request and one reply i receivbed was:

    "mkdir will definitely work but you will need to do some custom coding to make the permission work per user".

    Since you've been so helpful I thought I'd ask for your feedback on what particular "coding to make permission work per user" might require.

    thanks again.

  15. #15
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    If you create the directory outside the webserver root, it will not be accessible for public. That means there must be a script to give the access to those files. In that script you can and have to handle user permissions, i.e. authenticate user requests. The snippet with readfile() above is the basic idea.
    Saul

  16. #16
    Non-Member
    Join Date
    Apr 2007
    Posts
    224
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    The registration page file.

    Thnaks for all of your help.

    earlier you stated:
    "I'm not familiar with CubeCart, but you should look for the place the user is added to the database. You should find the username variable there too."

    I've been told that reg.inc.php is the "place".

    If you'd be interested in helping me further, I've posted that file's php, to ask where I might add your code:

    mkdir('/home/mysite/files/'.$username);

    Thank you.

    <?php
    /*
    +-------------------------------------------------------------------------

    +--------------------------------------------------------------------------
    | reg.inc.php
    | ========================================
    | Customer Registration
    +--------------------------------------------------------------------------
    */

    if (eregi(".inc.php",$HTTP_SERVER_VARS['PHP_SELF']) || eregi(".inc.php",$_SERVER['PHP_SELF'])) {
    echo "<html>\r\n<head>\r\n<title>Forbidden 403</title>\r\n</head>\r\n<body><h3>Forbidden 403</h3>\r\nThe document you are requesting is forbidden.\r\n</body>\r\n</html>";
    exit;
    }

    if($ccUserData[0]['customer_id']>0){

    header("Location: cart.php?act=step1");

    }
    if(isset($_POST['email'])){

    $emailArray = $db->select("SELECT customer_id, type FROM ".$glob['dbprefix']."CubeCart_customer WHERE email=".$db->mySQLSafe($_POST['email']));

    if(empty($_POST['firstName']) || empty($_POST['lastName']) || empty($_POST['email']) || empty($_POST['phone']) || empty($_POST['add_1']) || empty($_POST['town']) || empty($_POST['county']) || empty($_POST['postcode']) || empty($_POST['country']) || empty($_POST['password']) || empty($_POST['passwordConf'])){

    $errorMsg = $lang['front']['reg']['fill_required'];

    } elseif($_POST['password'] !== $_POST['passwordConf']) {

    $errorMsg = $lang['front']['reg']['pass_not_match'];

    } elseif(validateEmail($_POST['email'])==FALSE) {

    $errorMsg = $lang['front']['reg']['enter_valid_email'];

    } elseif(!ereg("[0-9]",$_POST['phone'])) {

    $errorMsg = $lang['front']['reg']['enter_valid_tel'];

    } elseif(!empty($_POST['mobile']) && !ereg("[0-9]",$_POST['mobile'])) {

    $errorMsg = $lang['front']['reg']['enter_valid_tel'];

    } elseif($emailArray == TRUE && $emailArray[0]['type']==1) {

    $errorMsg = $lang['front']['reg']['email_in_use'];

    } else {

    $record["email"] = $db->mySQLSafe($_POST['email']);
    $record["password"] = $db->mySQLSafe(md5($_POST['password']));
    $record["title"] = $db->mySQLSafe($_POST['title']);
    $record["firstName"] = $db->mySQLSafe($_POST['firstName']);
    $record["lastName"] = $db->mySQLSafe($_POST['lastName']);
    $record["add_1"] = $db->mySQLSafe($_POST['add_1']);
    $record["add_2"] = $db->mySQLSafe($_POST['add_2']);
    $record["town"] = $db->mySQLSafe($_POST['town']);
    $record["county"] = $db->mySQLSafe($_POST['county']);
    $record["postcode"] = $db->mySQLSafe($_POST['postcode']);
    $record["country"] = $db->mySQLSafe($_POST['country']);
    $record["phone"] = $db->mySQLSafe($_POST['phone']);
    $record["mobile"] = $db->mySQLSafe($_POST['mobile']);
    $record["regTime"] = $db->mySQLSafe(time());
    $record["ipAddress"] = $db->mySQLSafe($_SERVER['REMOTE_ADDR']);

    if(isset($_POST['optIn1st'])){

    $record["optIn1st"] = $db->mySQLSafe($_POST['optIn1st']);

    }

    $record["type"] = 1;
    $record["htmlEmail"] = $db->mySQLSafe($_POST['htmlEmail']);

    // look up users zone
    $zoneId = $db->select("SELECT * FROM ".$glob['dbprefix']."CubeCart_iso_counties WHERE (abbrev LIKE ".$db->mySQLSafe($_POST['county'])." OR name LIKE ".$db->mySQLSafe($_POST['county']).")");

    if($zoneId[0]['id']>0){

    $record["zoneId"] = $zoneId[0]['id'];

    }


    if($emailArray == TRUE && $emailArray['type']==0){
    // update

    $where = "customer_id = ".$db->mySQLSafe($emailArray[0]['customer_id']);

    $update = $db->update($glob['dbprefix']."CubeCart_customer", $record, $where);

    $sessData['customer_id'] = $emailArray[0]['customer_id'];
    $update = $db->update($glob['dbprefix']."CubeCart_sessions", $sessData,"sessId=".$db->mySQLSafe($_SESSION['ccUser']));

    } else {

    $insert = $db->insert($glob['dbprefix']."CubeCart_customer", $record);

    $sessData['customer_id'] = $db->insertid();
    $update = $db->update($glob['dbprefix']."CubeCart_sessions", $sessData,"sessId=".$db->mySQLSafe($_SESSION['ccUser']));

    $redir = treatGet(base64_decode($_GET['redir']));

    require_once("classes/cart.php");
    $cart = new cart();
    $basket = $cart->cartContents($ccUserData[0]['basket']);

    if(is_array($basket['conts']) && !empty($basket['conts'])) {

    header("Location: cart.php?act=step1");
    exit;

    } elseif(isset($_GET['redir']) && !empty($_GET['redir']) && !eregi("logout|login|forgotPass|changePass",$redir)) {

    header("Location: ".str_replace("amp;","",$redir));
    exit;

    } else {

    header("Location: index.php");
    exit;

    }

    }

    }

    }

    $reg = new XTemplate ("skins/".$config['skinDir']."/styleTemplates/content/reg.tpl");

    if(isset($errorMsg)){

    $reg->assign("VAL_ERROR",$errorMsg);
    $reg->parse("reg.error");

    } else {

    $reg->assign("LANG_REGISTER_DESC",$lang['front']['reg']['note_required']);
    $reg->parse("reg.no_error");

    }

    $reg->assign("LANG_REGISTER",$lang['front']['reg']['express_reg']);
    $reg->assign("LANG_REGISTER_SUBMIT",$lang['front']['reg']['submit_and_cont']);

    if(isset($_GET['redir']) && !empty($_GET['redir'])) {
    $reg->assign("VAL_ACTION","cart.php?act=reg&amp;redir=".treatGet($_GET['redir']));
    } else {
    $reg->assign("VAL_ACTION","cart.php?act=reg");
    }

    $reg->assign("LANG_PERSONAL_DETAILS",$lang['front']['reg']['personal_details']);
    $reg->assign("LANG_ADDRESS",$lang['front']['reg']['address']);
    $reg->assign("LANG_TITLE",$lang['front']['reg']['title']);
    $reg->assign("LANG_TITLE_DESC",$lang['front']['reg']['title_desc']);
    $reg->assign("LANG_FIRST_NAME",$lang['front']['reg']['first_name']);
    $reg->assign("LANG_ADDRESS_FORM",$lang['front']['reg']['address2']);
    $reg->assign("LANG_LAST_NAME",$lang['front']['reg']['last_name']);
    $reg->assign("LANG_EMAIL_ADDRESS",$lang['front']['reg']['email_address']);
    $reg->assign("LANG_TOWN",$lang['front']['reg']['town']);
    $reg->assign("LANG_TELEPHONE",$lang['front']['reg']['phone']);
    $reg->assign("LANG_COUNTY",$lang['front']['reg']['county']);
    $reg->assign("LANG_MOBILE",$lang['front']['reg']['mobile']);
    $reg->assign("LANG_COUNTRY",$lang['front']['reg']['country']);
    $reg->assign("LANG_POSTCODE",$lang['front']['reg']['postcode']);
    $reg->assign("LANG_SECURITY_DETAILS",$lang['front']['reg']['security_details']);
    $reg->assign("LANG_CHOOSE_PASSWORD",$lang['front']['reg']['choose_pass']);
    $reg->assign("LANG_CONFIRM_PASSWORD",$lang['front']['reg']['conf_pass']);
    $reg->assign("LANG_PRIVACY_SETTINGS",$lang['front']['reg']['privacy_settings']);
    $reg->assign("LANG_RECIEVE_EMAILS",$lang['front']['reg']['receive_emails']);
    $reg->assign("LANG_EMAIL_FORMAT",$lang['front']['reg']['email_format']);
    $reg->assign("LANG_HTML_FORMAT",$lang['front']['reg']['styled_html']);
    $reg->assign("LANG_PLAIN_TEXT",$lang['front']['reg']['plain_text']);
    $reg->assign("LANG_TANDCS",$lang['front']['reg']['tandcs']);
    $reg->assign("LANG_PLEASE_READ",$lang['front']['reg']['please_read']);

    $countries = $db->select("SELECT id, printable_name FROM ".$glob['dbprefix']."CubeCart_iso_countries");

    for($i=0; $i<count($countries); $i++){

    $reg->assign("VAL_COUNTRY_ID",$countries[$i]['id']);

    $countryName = "";
    $countryName = $countries[$i]['printable_name'];

    if(strlen($countryName)>20){

    $countryName = substr($countryName,0,20)."&hellip;";

    }

    $reg->assign("VAL_COUNTRY_NAME",$countryName);

    if(isset($_POST['country']) && $_POST['country'] == $countries[$i]['id']){

    $reg->assign("VAL_COUNTRY_SELECTED","selected='selected'");

    } elseif(!isset($_POST['country']) && ($countries[$i]['id']==$config['siteCountry'])) {

    $reg->assign("VAL_COUNTRY_SELECTED","selected='selected'");

    } else {
    $reg->assign("VAL_COUNTRY_SELECTED","");
    }
    $reg->parse("reg.repeat_countries");

    }


    if(isset($_POST['title'])){

    $reg->assign("VAL_TITLE",treatGet($_POST['title']));
    $reg->assign("VAL_FIRST_NAME",treatGet($_POST['firstName']));
    $reg->assign("VAL_LAST_NAME",treatGet($_POST['lastName']));
    $reg->assign("VAL_EMAIL",treatGet($_POST['email']));
    $reg->assign("VAL_PHONE",treatGet($_POST['phone']));
    $reg->assign("VAL_MOBILE",treatGet($_POST['mobile']));
    $reg->assign("VAL_ADD_1",treatGet($_POST['add_1']));
    $reg->assign("VAL_ADD_2",treatGet($_POST['add_2']));
    $reg->assign("VAL_TOWN",treatGet($_POST['town']));
    $reg->assign("VAL_COUNTY",treatGet($_POST['county']));
    $reg->assign("VAL_POSTCODE",treatGet($_POST['postcode']));

    if($_POST['password'] == $_POST['passwordConf']){

    $reg->assign("VAL_PASSWORD",treatGet($_POST['password']));
    $reg->assign("VAL_PASSWORD_CONF",treatGet($_POST['passwordConf']));

    }

    if(isset($_POST['optIn1st']) && $_POST['optIn1st']==1) {
    $reg->assign("VAL_OPTIN1ST_CHECKED","checked='checked'");
    }

    if($_POST['htmlEmail']==0){
    $reg->assign("VAL_HTMLEMAIL_SELECTED","selected='selected'");
    }
    }

    $reg->parse("reg");
    $page_content = $reg->text("reg");
    ?>

  17. #17
    ✯✯✯ silver trophybronze trophy php_daemon's Avatar
    Join Date
    Mar 2006
    Posts
    5,284
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I think this is the place:
    PHP Code:
    } else {

    $insert $db->insert($glob['dbprefix']."CubeCart_customer"$record);

    $sessData['customer_id'] = $db->insertid();
    $update $db->update($glob['dbprefix']."CubeCart_sessions"$sessData,"sessId=".$db->mySQLSafe($_SESSION['ccUser']));

    mkdir('/home/mysite/files/'.$sessData['customer_id']);

    $redir treatGet(base64_decode($_GET['redir']));

    require_once(
    "classes/cart.php");
    $cart = new cart();
    $basket $cart->cartContents($ccUserData[0]['basket']);

    if(
    is_array($basket['conts']) && !empty($basket['conts'])) {

    header("Location: cart.php?act=step1");
    exit; 
    Note that /home/mysite/files/ is a dummy path, you should find out the real or use a relative path. Also make sure to set the write permissions to the target directory.
    Saul


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •