• Resolved Alex Stine

    (@alexstine)


    Hello,

    I have built a custom upload form using the below code. After someone uploads a file, it should go to their respective directory. For example: /wp-content/cloud/USER_NAME/. The problem I’m having is after the form is submitted, the file is not uploaded.

    Code in my custom plugin file.

    /*File upload form*/
    function tnl_cloud_upload_form() {
    	if(is_user_logged_in() ) :
    		tnl_cloud_uploads_save(); ?>
    <button class="cloud-upload-form-toggle open" aria-expanded="false">Upload File</button>
    <div class="cloud-upload-form-wrapper" style="display:none;">
    <form action="<?php echo site_url('/cloud/'); ?>" method="post" enctype="multipart/form-data>
    <?php echo wp_nonce_field('cloud-upload-nonce', 'cloud-upload-nonce'); ?>
    <label for="cloud-upload-label">Upload File</label>
    <br />
    <input type="file" name="cloud-upload" id="cloud-upload-label"/>
    <input type="submit" value="Upload" />
    </form>
    </div>
    	<?php endif;
    }
    add_action('tnl_cloud_upload_form_hook', 'tnl_cloud_upload_form');
    
    /*Save the data*/
    function tnl_cloud_uploads_save() {
    	if(!isset($_POST['cloud-upload-nonce']) || !wp_verify_nonce($_POST['cloud-upload-nonce'], 'cloud-upload-nonce') ) {
    		return;
    	}
    	if(!current_user_can('cloud_upload_files') ) {
    		return;
    	}
    	if(!isset($_FILES['cloud-upload']) || $_FILES['cloud-upload']['error'] > 0) {
    		return 'ERROR: something went wrong. Please try again later.';
    	}
    	$current_user = wp_get_current_user();
    	$cloud_uploads_user_dir = WP_CONTENT_DIR . '/cloud/' . $current_user->user_login . '/';
    	$filename = $cloud_uploads_user_dir . basename($_FILES['cloud-upload']['name']);
    	$upload_ok = 1;
    	$filetype = pathinfo($filename,PATHINFO_EXTENSION);
    	if(file_exists($filename) ) {
    		echo 'This file already exists.';
    		$upload_ok = 0;
    	} else {
    		$upload_ok = 1;
    	}
    	if($_FILES['cloud-upload']['size'] > 500000) {
    		echo 'This file is to large.';
    		$upload_ok = 0;
    	} else {
    		$upload_ok = 1;
    	}
    	if($filetype != 'jpg' && $filetype != 'png' && $filetype != 'jpeg' && $filetype != 'gif') {
    		echo 'Invalid image format.';
    		$upload_ok = 0;
    	} else {
    		$upload_ok = 1;
    	}
    	if($upload_ok == 0) {
    		echo 'Please fix above errors and try again.';
    	} else {
    		if(move_uploaded_file($_FILES['cloud-upload']['tmp_name'], $filename) ) {
    			echo 'Error uploading the file. Please try again later.';
    		} else {
    			echo 'Upload successful.';
    		}
    	}
    }

    Source: https://www.w3schools.com/php/php_file_upload.asp

    I can see this in my server logs.

    ::1 - - [01/Jul/2017:16:10:33 -0400] "OPTIONS * HTTP/1.0" 200 126 "-" "Apache/2.4.18 (Ubuntu) (internal dummy connection)"
    MY_IP - SERVER_NAME [01/Jul/2017:16:11:01 -0400] "POST /cloud/ HTTP/1.1" 200 4556 "https://SITE_ADDRESS/cloud/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0"

    According to the logs the form is posting but it seems like the upload code is not executing. All directories for this implementation are writable by php. There is nothing produced in the debug_log from WP_DEBUG.

    I decided not to use WP core functions for this since I was not sure if I could store the media outside of /wp-content/uploads/. I needed to store it in a specific location for later plans.

    Any assistance or suggestions is appreciated.

    Thanks.

    • This topic was modified 7 years, 4 months ago by Alex Stine. Reason: Correcting visible information in logs
Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    Your form is submitting to yourdomain.tld/cloud/. That folder (if it exists) would need to have an index.php file there to handle the submit. (because no file is specified in the form action) A plugin file with no immediately executable code would not handle this. Such a file cannot use any WP functions at all. You would essentially be doing a straight, non-WP file upload handler. As long as the folders and files are properly coordinated, that is a viable approach. The key is the form submits to a PHP file handler, not where you want the upload to go. Where the upload goes is up to your PHP code. If you continue on this route, WP_DEBUG would have no bearing on error reporting because WP is not involved. You would need to check your error logs for clues.

    You do not have to continue with the non-WP approach, your assumption that WP uploads are limited to the uploads folder is incorrect when applied to custom code. For example, wp_handle_upload() takes a $_FILES element style of an argument that includes the final destination of the file. This can be anywhere on the server that is writable by PHP. There are other upload variations, but they all work off of $_FILES element style data.

    You still would need some form submit handler code to compose the $_FILES element style argument and call wp_handle_upload(). Since you would now be using WP resources, the form action URL needs to be to a location that properly initiates the WP environment. Your only choices are a WP page based on a custom template, or to request through admin-ajax.php or admin-post.php.

    FWIW, even default uploads that use wp_handle_upload() are not limited to the uploads folder because you can alter the final destination through the “wp_handle_upload” filter. But then filtering a function means it’s not really default anymore??

    Anyway, you can stay non-WP or go back to WP. Use normal PHP/WP program flow logic. The upload file location is not a consideration for how your code works. The only place the file destination is a consideration is the eventual move destination.

    Thread Starter Alex Stine

    (@alexstine)

    Hello,

    Let me try to explain a few other things so we’re both on the same page. The way the uploads system works is this. Each user registered on the site has a directory assigned to them after they register. For example.

    /wp-content/cloud/username1/
    /wp-content/cloud/username2/
    /wp-content/cloud/username3/

    I pointed the form action to domain.com/cloud/ because that is a custom page with a custom template assigned.

    If I were to continue using the same method, these are my questions.
    1. If I added my save function and then called it before the form is outputted in my custom page template, would it work?
    2. I would rather stay away from the structure of /wp-content/cloud/username/index.php since then WP users will be able to see the index.php file. If I process the form submit through the custom page template will it work?

    I know those are similar questions but just trying to understand what it would take to get this working without switching my functions around.

    Thanks.

    Moderator bcworkz

    (@bcworkz)

    If your form and form submit handler are all on a custom page template, that’s great. But you do not submit to the template file location then, you submit to the page’s permalink. WP will then load your template file and it’s code will execute. When accessed through a permalink, there is no reason to avoid WP functions. You do not need to use them if you don’t want to, but there is no reason you couldn’t.

    A good way to handle forms and submits on the same file is to have a conditional that checks if 'POST' == $_SERVER['REQUEST_METHOD']. If so, process the submitted data, otherwise output the form. Or output the form in both cases, which way is up to you.

    FWIW, forgetting that the file is a page template, your file must then be index.php with a form action URL like /wp-content/cloud/ because that is the only PHP file that the server will load if no file is specified. To use any other filename, it has to be specified in the action URL, or else the server will not load it. In the case of permalink form actions, WP works out what template files to load. The permalink is not a real path, it’s a virtual path that WP interprets into returning the appropriate content.

    Thread Starter Alex Stine

    (@alexstine)

    Hello,

    I found the problem. It was a missing

    "

    on the

    <form>

    tag. Thanks for your help.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Custom Upload Form Submission Issues’ is closed to new replies.