I am creating WordPress website, using Divi Builder for the design + some PHP for additional functionality in the back-end. Right now I am developing custom Divi modules, which purpose will be to fetch data from my MongoDB database and display it, if everything works as expected. Here is the logic:
// ... create-divi-extension code
private function get_mongodb_data() {
$uri = "...";
$client = new Client($uri);
$db = $client->selectDatabase("...");
$collection = $db->selectCollection("...");
$result = $collection->find();
$data = [];
foreach ($result as $document) {
$data[] = $document;
}
return $data;
}
public function get_content($mongodb_data) {
$content = '';
foreach ($mongodb_data as $test) {
$test_name = isset($test->test_name) ? $test->test_name : '';
$points = isset($test->points) ? $test->points : '';
$test_id = isset($test->_id) ? $test->_id : '';
$test_page_url = esc_url( 'https://test.net/tests/' . $test_id );
$content .= sprintf(
'<div>
<h1>%1$s</h1>
<h4>%2$s</h4>
<a class="go-to-test-btn" href="%3$s">%4$s</a>
</div>',
$test_name,
$points,
esc_url( $test_page_url ),
esc_html__( 'read more', '...' )
);
}
return $content;
}
I won’t share the actual website, because it is not important for my question.
So the idea is whenever I click this button <a class="go-to-test-btn" href="%3$s">%4$s</a>
, to be redirected to the particular test. Inside the functions.php
file of my WordPress website, I implemented this logic to be executed, upon getting redirected to this URL ('https://test.net/tests/' . $test_id
):
function check_mongodb_for_test($test_id) {
try {
$uri = "...";
$client = new MongoDBClient($uri);
$db = $client->selectDatabase("...");
$collection = $db->selectCollection("...");
$objectID = new MongoDBBSONObjectId(strval($test_id));
$result = $collection->findOne(['_id' => $objectID]);
return $result !== null;
} catch (Exception $e) {
error_log("Error occurred in check_mongodb_for_test: " . $e->getMessage());
return false;
}
}
add_action('template_redirect', 'custom_template_redirect');
function custom_template_redirect() {
$url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$url_parts = explode('/', trim($url_path, '/'));
$test_id = end($url_parts);
$test_exists = check_mongodb_for_test($test_id);
if ($test_exists) {
$redirect_url = add_query_arg('test_id', $test_id, get_permalink('1300'));
wp_redirect($redirect_url);
exit;
}
}
function redirect_if_test_id_is_invalid() {
if (is_page_template('test-custom-template.php')) {
if (!isset($_GET['test_id'])) {
wp_redirect(home_url('/all-tests'));
exit;
} else {
if (!check_mongodb_for_test($_GET['test_id'])) {
wp_redirect(home_url('/all-tests'));
exit;
}
}
}
}
add_action('template_redirect', 'redirect_if_test_id_is_invalid');
So I am getting the test_id
, searching for document with such ID inside and redirecting to different URL (will solve the many redirections later on), while setting the ID as a query parameter, in order for other custom modules inside this page to be able to use it for fetching other data, if that document exists inside the database.
My question is if it is safe to do those operations like this. I am basically doing some sanitization before starting to query inside the database (inside the functions.php
file), but my concern is that anyone can input anything inside the URL. So I am thinking if this is the proper way to go further. If it is not optimal and safe way, please guide me to how to to optimize and improve the security of this logic.