Trying to see form data using $_Post in backend for the named inputs but nothing (tried many different solutions)
I've put code below of the FE page to review but as far as i can see it should work.
<div class="wrap">
<h1>
Course Lesson Settings
</h1>
<p>
Use this interface to create/update course lessons.
</p>
<form method="post" enctype="multipart/form-data">
@php
wp_nonce_field('course_modules_settings_action', 'course_modules_settings_nounce');
@endphp
<table class="form-table" role="presentation">
<tbody>
<tr>
<th scope="row">Create or update a course lesson</th>
<td>
<p>
<input type="hidden" name="action" value="Upload Lesson" />
<select name="module-value">
<option value="" selected>Create a lesson</option>
@if (App::isArrayWithValue($posts))
@foreach($posts as $singlePost)
<option value="{{ $singlePost->ID }}">
{!! $singlePost->post_title !!}
</option>
@endforeach
@endif
</select>
</p>
<td>
</tr>
<tr>
<th scope="row">Lesson archive</th>
<td>
<p>
<input type="file" name="module" required/>
</p>
<p>
Select the <code>zip</code> containing the course.
</p>
<td>
</tr>
<tr>
<th scope="row"></th>
<td>
<p>
<input type="submit" name="submit" class="button button-primary" value="Upload Lesson">
</p>
<td>
</tr>
</tbody>
</table>
</form>
</div>
To see the variable in the backend
Here is the backend code which calls the view - then processes the form - Dont know the ins and outs of this project as im taking over for another person:
<?php
namespace App\CourseModule;
class CourseModuleSettings {
public function init() {
add_action('init', [$this, 'createPostType']);
add_action('admin_menu', [$this, 'addAdminMenu']);
}
public function createPostType() {
register_post_type('course-modules', [
'label' => 'Course Lessons',
'labels' => [
'name' => 'Course Lessons',
'singular_name' => 'Course Lesson',
],
'supports' => ['title'],
'taxonomies' => ['year_level', 'curriculum', 'topic'],
'hierarchical' => false,
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 25,
'menu_icon' => 'dashicons-media-archive',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'publicly_queryable' => false,
'capability_type' => 'page',
'searchable' => false,
]);
}
public function addAdminMenu() {
add_menu_page(
'Course Lessons Settings',
'Course Lessons Settings',
'manage_options',
'course-modules-settings',
[$this, 'adminPageContent'],
'dashicons-schedule',
200
);
}
public function adminPageContent() {
$this->handleAdminPageActions();
$posts = get_posts([
'post_type' => 'course-modules',
'posts_per_page' => -1,
'post_status' => 'any',
]);
echo \App\template('admin.page-course_module_settings', [
'posts' => $posts
]);
}
public function handleAdminPageActions() {
if (
(isset($_POST['action']) ||
isset($_POST['course_modules_settings_nounce'])) &&
(!wp_verify_nonce(
$_POST['course_modules_settings_nounce'],
'course_modules_settings_action'
) ||
!check_admin_referer(
'course_modules_settings_action',
'course_modules_settings_nounce'
))
) {
$this->displayNotice('Invalid nounce', 'error');
return;
}
if ($_POST['action'] === 'Upload Lesson') {
if (
isset($_POST['module-value']) &&
!empty($_FILES)
) {
// Check if the file is uploaded
$file = $_FILES['module'];
if (
!file_exists($file['tmp_name']) ||
!is_uploaded_file($file['tmp_name'])
) {
$this->displayNotice("Couldn't find the uploaded file.", 'error');
return;
}
// Validate the file
$archiveFolder = $this->validateUploadedFile($file);
if (!$archiveFolder) {
$this->displayNotice("Invalid uploaded file.", 'error');
return;
}
// Get the upload folder
$uploadFolder = $this->checkOrCreateModuleFolder();
if (!$uploadFolder) {
$this->displayNotice("Couldn't create upload folder", 'error');
die();
}
$hashFolder = null;
if (empty($_POST['module-value'])) {
// Create a new module
$hashFolder = $this->createModuleHash($uploadFolder, $file["name"]);
} else {
// Update module
$hashFolder = \get_field('module_hash', $_POST['module-value']);
}
// Create or update the post
$postId = wp_insert_post([
'ID' => $_POST['module-value'],
'post_title' => $file["name"],
'post_type' => 'course-modules',
]);
// Update the ACF fields
\update_field('module_hash', $hashFolder, $postId);
\update_field('module_url', "/wp-content/uploads/course-modules/{$hashFolder}/index.html", $postId);
$moduleFolder = sprintf('%s%s%s', $uploadFolder, DIRECTORY_SEPARATOR, $hashFolder);
// Move the file to the upload folder
$this->rcopy($archiveFolder, $moduleFolder);
$this->displayNotice("Lesson uploaded. <a href=\"/wp-admin/post.php?post={$postId}&action=edit\">Edit lesson</a>", 'success');
} else {
$this->displayNotice("Please make sure you've uploaded a file.", 'error');
return;
}
// }
}
protected function createModuleHash($uploadFolder, $fileName) {
// Create the long hash for the module folder
$attempts = 0;
$maxAttempts = 1000;
$hashFolder = null;
do {
$hashFolder = hash('sha256', "$attempts" . $fileName);
$moduleFolder = sprintf('%s%s%s', $uploadFolder, DIRECTORY_SEPARATOR, $hashFolder);
} while (
!mkdir($moduleFolder, 0700) &&
$attempts++ < $maxAttempts
);
return $hashFolder;
}
protected function checkOrCreateModuleFolder() {
$wpUploadFolder = wp_upload_dir();
if (isset($wpUploadFolder['basedir'])) {
// Check if the modules folder exists
$path = sprintf('%s%s%s', $wpUploadFolder['basedir'], DIRECTORY_SEPARATOR, 'course-modules');
if(
!file_exists($path)
) {
// Create the folder
mkdir($path, 0700);
// Add basic index.php to prevent default listing of the folder
file_put_contents(sprintf('%s%s%s', $path, DIRECTORY_SEPARATOR, 'index.php'), '');
}
return $path;
}
return null;
}
protected function validateUploadedFile($file) {
// Check the extension
$name = basename($file["name"]);
$fileMetadata = pathinfo($name);
if ($fileMetadata['extension'] === 'zip') {
// Create tmp directory
$tmpDir = $this->createTmpDir();
if (!$tmpDir) {
$this->displayNotice("Couldn't create temporary directory.", 'error');
return false;
}
$newTmpLocation = sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, $file['name']);
// Move the uploaded file
move_uploaded_file($file["tmp_name"], $newTmpLocation);
// Extract the archive and validate the files in it
// $zipFile = new \PhpZip\ZipFile();
$zip = new ZipExtract();
$res = $zip->open($newTmpLocation);
if ($res === true) {
// Extract the archive in the tmp folder
$folders = [
'assets',
'lib',
'content'
];
$files = [
'index.html',
'goodbye.html',
];
foreach ($folders as $folder) {
$extractionErrors = $zip->extractSubdirTo(
$tmpDir . DIRECTORY_SEPARATOR . $folder,
$folder . DIRECTORY_SEPARATOR,
);
if (count($extractionErrors)) {
echo "<pre>";
var_dump($extractionErrors);
echo "</pre>";
$this->displayNotice("Couldn't extract archive", 'error');
return false;
}
}
foreach ($files as $file) {
$extractionErrors = $zip->extractTo(
$tmpDir . DIRECTORY_SEPARATOR,
$file,
);
}
$zip->close();
// Check if the base files and folder for the module exist
if (
$this->testFolderStructure($tmpDir)
) {
$tmpDir = sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, 'content');
if (
$this->testFolderStructure($tmpDir)
) {
$this->displayNotice("Invalid content in extracted lesson archive. Expects: index.html, goodbye.html, lib, assets.", 'error');
echo "<pre>";
var_dump([
file_exists(sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, 'index.html')) ,
file_exists(sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, 'goodbye.html')) ,
file_exists(sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, 'lib')),
file_exists(sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, 'assets')),
sprintf('%s%s%s', $tmpDir, DIRECTORY_SEPARATOR, 'assets')
]);
echo "</pre>";
return false;
}
}
// Remove the archive
unlink($newTmpLocation);
return $tmpDir;
}
}
return false;
}
protected function testFolderStructure($directory) {
return (
!file_exists(sprintf('%s%s%s', $directory, DIRECTORY_SEPARATOR, 'index.html')) ||
!file_exists(sprintf('%s%s%s', $directory, DIRECTORY_SEPARATOR, 'goodbye.html')) ||
!file_exists(sprintf('%s%s%s', $directory, DIRECTORY_SEPARATOR, 'lib')) ||
!file_exists(sprintf('%s%s%s', $directory, DIRECTORY_SEPARATOR, 'assets'))
);
}
/**
* Code from: https://stackoverflow.com/questions/1707801/making-a-temporary-dir-for-unpacking-a-zipfile-into
*/
protected function createTmpDir($dir = null, $prefix = 'tmp_', $mode = 0700, $maxAttempts = 1000) {
/* Use the system temp dir by default. */
if (is_null($dir)) {
$dir = sys_get_temp_dir();
}
/* Trim trailing slashes from $dir. */
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
/* If we don't have permission to create a directory, fail, otherwise we will
* be stuck in an endless loop.
*/
if (!is_dir($dir) || !is_writable($dir)) {
return false;
}
/* Make sure characters in prefix are safe. */
if (strpbrk($prefix, '\\/:*?"<>|') !== false) {
return false;
}
/* Attempt to create a random directory until it works. Abort if we reach
* $maxAttempts. Something screwy could be happening with the filesystem
* and our loop could otherwise become endless.
*/
$attempts = 0;
do {
$path = sprintf('%s%s%s%s', $dir, DIRECTORY_SEPARATOR, $prefix, mt_rand(100000, mt_getrandmax()));
} while (
!mkdir($path, $mode) &&
$attempts++ < $maxAttempts
);
return $path;
}
/**
* Code from: https://stackoverflow.com/questions/9835492/move-all-files-and-folders-in-a-folder-to-another
*/
// Function to remove folders and files
protected function rrmdir($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file) {
if ($file != "." && $file != "..") {
$this->rrmdir("$dir/$file");
}
}
rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}
/**
* Code from: https://stackoverflow.com/questions/9835492/move-all-files-and-folders-in-a-folder-to-another
*/
// Function to Copy folders and files
protected function rcopy($src, $dst) {
if (file_exists ( $dst )) {
$this->rrmdir ( $dst );
}
if (is_dir ( $src )) {
mkdir ( $dst );
$files = scandir ( $src );
foreach ( $files as $file ) {
if ($file != "." && $file != "..") {
$this->rcopy( "$src/$file", "$dst/$file" );
}
}
} else if (file_exists ( $src )) {
copy ( $src, $dst );
}
}
/**
* Display an admin notice
*
* @param string $content the content of the notice
* @param string $type (Optional) the type of notice
* @return void
*/
protected function displayNotice($content, $type = 'info') {
?>
<div class="notice notice-<?= $type ?> is-dismissible">
<p><?= str_replace("\r\n", '<br/>', $content) ?></p>
</div>
<?php
}
}
(new CourseModuleSettings())->init();