• Hi all,

    Can anyone please advise me how I can insert a PDF file that a user selects from a html form into a custom table in the database?

    My code so far is:
    $OrderNumber= $_POST[‘txt_OrderNumber’];
    $UploadAttachment = $_POST[‘txt_Attachment’];

    $wpdb->insert(‘wp_Attachments’,
    array(
    ‘OrderNumber’ => $NextOrderNumber,
    ‘FileContent’ => $UploadAttachment
    ),
    array(
    ‘%s’,
    ‘%s’
    )
    );

    Although I do not get any errors, the size returned in the database is 0.

    Any advice please?

Viewing 14 replies - 1 through 14 (of 14 total)
  • Moderator bcworkz

    (@bcworkz)

    This PDF file resides on the user’s computer, correct? Do you plan upload this file to your server? This page should help you. Even if you are not uploading the file, the process of obtaining the information is still the same.

    Once you get the information you want, simply expand the data and format arrays of your insert() method to load the data into the proper column.

    Thread Starter A31

    (@a31)

    Hi, thank you very much for your reply, and I do apologize for the late reply, i was out of town for a while.

    I am still not getting this thing right….

    my form code looks like this:

    <?php
    require_once(ABSPATH . WPINC . '/ms-functions.php');
    
    	$PageTitle = 'TEST_Process';
    	$page = get_page_by_title($PageTitle);
    	$myID = $page->ID;
    	$myPageRedirect = get_page_link($myID);
    
    ob_start()
    
    ?>
    <script language="javascript">
    		function Checkfiles()
    		{
    		var fup = document.getElementById('uploaded_file');
    		var fileName = fup.value;
    		var ext = fileName.substring(fileName.lastIndexOf('.') + 1);
    		if(ext == "pdf")
    		{
    		return true;
    		}
    		else
    		{
    		alert("Upload PDF Files only");
    		fup.focus();
    		document.getElementById('file').value = '';
    		return false;
    		}
    		}
    	</script>
    <div class='wrap'>
    
    <form action="<?php echo $myPageRedirect; ?>" method="post" enctype="multipart/form-data"> 
    
    	<input name="file" id="file" type="file" size="80" required="required" onchange="Checkfiles(this)"/>
    	<input type="submit" name="btn_Submit" id="btn_Submit" value="Submit" />
    
    </form>
    
    <?php

    then my processing file code lookes like this:

    <?php
    if ($_FILES["file"]["error"] > 0)
      {
      echo "Error: " . $_FILES["file"]["error"] . "<br>";
      }
    else
      {
    
    		$PreFileName = ($_FILES["file"]["name"]);
    		$FileName = str_replace(" ","", $PreFileName);
    		$FileType = ($_FILES["file"]["type"]);
    		$FileSize = intval($_FILES['file']['size']);
    		$FileLocation = $_FILES["file"]["tmp_name"];
    		$FileContent = (file_get_contents($_FILES  ['file']['tmp_name']));
    
    		echo "FileName: " . $FileName;
    		echo "<br>";
    		echo "FileType: " . $FileType;
    		echo "<br>";
    		echo "FileSize: " . $FileSize;
    		echo "<br>";
    		echo "FileLocation: " . $FileLocation;
    		echo "<br>";
    
    		$url = plugin_dir_path( __FILE__ );
    		move_uploaded_file($_FILES["file"]["tmp_name"], $url . $_FILES["file"]["name"]);
    
      }
    
    $wpdb->insert(
    	'wp_attachments',
    	array(
    		'FileName' => $FileName,
    		'FileType' => $FileType,
    		'FileSize' => $FileSize,
    		'FileContent' => $FileContent
    	)
    );
    
    ?>

    I can actually echo the file name and the other details and see it, but I now get this error when I try to inert it into the database:

    Fatal error: Call to a member function insert() on a non-object

    Can you perhaps help? I am kind of in a pickle here and can’t seem to get this sorted.

    Moderator bcworkz

    (@bcworkz)

    It appears you just forgot to declare global $wpdb; ?

    I can’t tell you how many times I’ve done this myself :/

    BTW, once you have this working properly, for security reasons you should validate and sanitize all form values before inserting into the DB. It’s also a good idea to ensure the data is coming from a valid form by placing a nonce in a hidden field and then verifying it when the form is received.

    Thread Starter A31

    (@a31)

    Hi,

    I cant believe I missed that for two hours! ??

    Thank you VERY much!

    It inserts the data into the database now.
    Do you have any suggestions on how to retrieve the data and view the pdf file again?

    Thank you very much for your help, much appreciated!

    When everything is done and working and cleaned up, I will post all the code, so that perhaps it might help someone else.

    Moderator bcworkz

    (@bcworkz)

    Why not just grab the data using $wpdb->get_row() and build a HTML link to the uploaded pdf file and output it from a template? When the link is clicked the browser figures out the rest. I’m not sure it’s a good idea to try to actually display pdf content inside theme chrome, if that’s what you’re thinking.

    Thread Starter A31

    (@a31)

    Hi,
    yes, I followed the same way I used to before using WordPress.

    <?php
    global $wpdb;
    
    $mydataset = $wpdb->get_row("SELECT * FROM esdb_attachments WHERE ID = 1119");
    
    $recordID = $mydataset->ID;
    $FileType = $mydataset->FileType;
    $FileSize = $mydataset->FileSize;
    $FileName = $mydataset->FileName;
    $FileContent = $mydataset->FileContent;
    
    // Print headers
        header("Content-Type: ". $FileType);
        header("Content-Length: ". $FileSize);
    	header("Content-Disposition: attachment; filename=". $FileName);
    
    // Print Data
        echo $FileContent;

    Usually the browser automatically asked me to save or open the file, but now it just prints garbage on the page.
    Could you perhaps shine more light on what / how you mean that I should build a HTML link?

    Thnx again for all your help!

    Thread Starter A31

    (@a31)

    o yes, and of course I get the “Headers have already been sent” error.
    But when I echo the different variables, I can see the correct info, all except $FileContent.

    Moderator bcworkz

    (@bcworkz)

    The last chance to send headers is the ‘send_headers’ action, hook into that if you want to do things that way. Check the query_vars property of the passed WP object to ensure you are doing this for the right request.

    By building a link, I meant on some template, after getting the data, do something like:
    <?php echo "<a href=\"https://mysite.com/wp-content/uploads/pdf/$FileName\">$FileName</a>"; ?>

    Thread Starter A31

    (@a31)

    Hi,
    Thank you for your response.

    I am sorry but I am not getting this right…

    I managed to send the Header through the hook, which worked great, but when I echo the $FileContent, I still end up with a bunch of garbage on the screen:

    [ Moderator note: binary PDF file header deleted, please do not post ninary gobbley gook like that here. ]

    Is there perhaps any chance that you can provide me with some code that you use so I can learn from that?
    I am not getting any closer to a solution at this stage on my own ??

    Thank you very much for your help!

    Moderator bcworkz

    (@bcworkz)

    Code that I use? I’ve given you the wrong impression. While I know a lot about the inner workings of WP and have tweaked functionality in hundreds of ways, I have no practical experience or code related to file management. I’m going totally on learned theory. Sorry to disappoint you.

    Despite having little qualifications, I think the problem now is that you are storing file content in your DB. I don’t think this is a good idea for binary data. You should only store reference information there, the file should reside on your server. Of course you would need to make every effort to ensure the file is a legitimate PDF file free of malicious content if the source is anyone that is not completely trusted.

    Thread Starter A31

    (@a31)

    Hi there,
    No problem and thank you for all the help so far, you really did help me a lot! Unfortunately because of the volumes of files that will be stored, I will have to store the pdf files in a database, for audits as well as other fields in the table used for searching the correct document.

    Perhaps you might know the following that might help solve this matter?

    In my sites before I started using WordPress, I just echo’d the variable that contained the actual pdf file content and then the browser asked me to save the file or open it.
    If I do the same now in WordPress, it only prints the ‘garbage’ onto the page and does not ask to open or save the file any more.

    Do you perhaps know why wordpress is doing this and what I should do to get the open / save dialogue box back?

    Moderator bcworkz

    (@bcworkz)

    No idea really, but a fair guess is that the binary data is getting treated as textual data somewhere, scrambling everything. Obviously, you would want to maintain binary data as binary whenever possible, but FWIW if all else fails, you could purposely convert binary to text and back using one of the algorithms intended for email transmission.

    I just had a thought and looked into the wpdb class. The problem is likely the insert() method, which unless specific measures are taken, only integer, float and string data is accepted, and if undefined, string is assumed. First off, ensure your DB table column is set for binary data. From the looks of things, you use wp_set_wpdb_vars() to add a key/value to the $field_types property, key = column name, value = format name. It’s curious there seems to be no reference to table names here, the possibility of name conflict seems rather high.

    No guarantee handling this will solve your problem, but it is one thing that does need addressing. WP was apparently never intended for handling binary data, so there is likely other traps along the way. It’s tempting to discard $wpdb and stick with pure PHP mysql functions, but there are advantages to $wpdb and everything channeled through one DB connection, in addition to error handling and caching, so don’t discard it too readily.

    Thread Starter A31

    (@a31)

    Ok, so I have done some more tests to try and isolate where the issue lies.

    Firstly I tested with my old method on another custom non-wordpress site to see if the data was correctly inserted in the databases, and yes, the insert worked perfectly I can view the pdf as normal when not using wordpress.

    The second test I did was to replace the WPDB and use the exact code I use for the non-wordpress site and see what it does, and thats where the problem kicks back. It then gives me the bunch of garbage code and does not ask me to open / save the pdf file.

    So it seems that the problem is then not with the database connection methods at all but possibly rather the way that wordpress display the content.

    Does this make any sense?
    If so, do you perhaps know of a way where I can “bypass” wordpress method of displaying pages for one specific page?

    Again thank you for helping me figure this out!

    Moderator bcworkz

    (@bcworkz)

    If you’ve completely taken $wpdb out of the equation, I can only imagine WP is sending some headers that is confusing the browser. Without $wpdb, there is no reason to involve WP at all in relation to this one page, as you suggest.

    I’m not sure how you are requesting a pdf file but your old method should be able to run parallel to WP. Do what you did before, the only difference is which DB the table resides in. The PHP page that gets the data and sends out the content should be requested directly, with the needed information about which file to send embedded as parameters. This file must not include or require any WP files, meaning you cannot call any WP functions from this page. All DB access will be via PHP mysql calls. Any other processes requiring WP need to be handled by a separate request somehow.

    It’s looking like WP simply cannot handle binary data at all and needs to be kept out of any such communications.

Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘Insert PDF File to Custom Database Table’ is closed to new replies.