How to run recaptcha 2 in html and php? - javascript

index html:
<!DOCTYPE html>
<html>
<head>
</head>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<body>
<form method="post" action="/cms/common/sendEmail" enctype="multipart/form-data" class="valida tc" id="thisForm">
<input type="hidden" name="lang" value="tch" />
<tr>
<td>
<div class="g-recaptcha" id="recaptcha" data-sitekey="sitekey"></div>
</td>
</tr>
<tr>
<td class="submitBtnWrap"><input type="submit" value="送出" class="roundBtn" /><span class="at-error"></span></td>
</tr>
</table>
</form>
</body>
</html>
recaptcha.php:
<?php
$public_key = "6Lc9oGIaAAAAAMK6Q4ZZ_qYzlvVCV1nydMLDUUoZ";
$private_key = "6Lc9oGIaAAAAAEthTaDOcm3VJ9Uldizbl6ZDKQ2_";
$url = "https://www.google.com/recaptcha/api/siteverify";
$q
=$_GET["q"];
echo $q;
if(array_key_exists('submit_form',$_POST)){
// echo "<pre>";print_r($_POST);echo"</pre>";
$response_key = $_POST['g-recaptcha-response'];
$response = file_get_contents($url.'?secret='.$private_key.'&response='.$response_key.'&remoteip='.$_SERVER['REMOTE_ADDR']);
$response = json_decode($response);
// echo "<pre>";print_r($response);echo "</pre";
if($response->success == 1)
{
echo "Your information was valid...";
}else{
echo "You are a robot and we don't like robts.";
}
}
?>
Hello, I try to add the recaptcha 2 in my web. The site side and server side are done.
But how can I send the token to google server side verification using php file as the form action cannot be edited to action="recaptcha.php".
Or is any solution like using ajax, javascript to finish server side verification?
Please help me. Thank you all.

If you can't change action="recaptcha.php", you need to use AJAX to verify the responses.
So, Your index.html should be like
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form method="post" action="/cms/common/sendEmail" enctype="multipart/form-data" class="valida tc" id="thisForm">
<input type="hidden" name="lang" value="tch" />
<tr>
<td>
<div id="recaptcha" ></div>
</td>
</tr>
<tr>
<td class="submitBtnWrap"><input type="submit" value="送出" class="roundBtn" /><span class="at-error"></span></td>
</tr>
</table>
</form>
<!-- Add jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Add recaptcha explicitly -->
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
<!-- render and verify by ajax -->
<script>
var onloadCallback = function() {
grecaptcha.render('recaptcha', {
'sitekey' : '6Lc9oGIaAAAAAMK6Q4ZZ_qYzlvVCV1nydMLDUUoZ',
'callback' : verifyCallback,
});
}
var verifyCallback = function(response) {
$.post('recaptcha.php', {'g-recaptcha-response' : response}, function(data){
alert(data);
});
};
</script>
</body>
</html>
your recaptcha.php:
<?php
$public_key = "6Lc9oGIaAAAAAMK6Q4ZZ_qYzlvVCV1nydMLDUUoZ";
$private_key = "6Lc9oGIaAAAAAEthTaDOcm3VJ9Uldizbl6ZDKQ2_";
$url = "https://www.google.com/recaptcha/api/siteverify";
if(isset($_POST['g-recaptcha-response'])){
$response_key = $_POST['g-recaptcha-response'];
$response = file_get_contents($url.'?secret='.$private_key.'&response='.$response_key.'&remoteip='.$_SERVER['REMOTE_ADDR']);
$response = json_decode($response);
if($response->success == 1)
{
echo "Your information was valid...";
}else{
echo "You are a robot and we don't like robts.";
}
}
?>

Related

jQuery PHP Post

I got a problem maybe is simple but dont know how to load jquery_post.php when I send the data for jquery_send.php I resume I send information from jquery_send.php to jquery_post.php and I want that after send the page jquery_post.php load with the data
This is what I have in jquery_send.php:
<html>
<head>
<link href='http://fonts.googleapis.com/css?
family=Source+Sans+Pro|Open+Sans+Condensed:300|Raleway' rel='stylesheet' type='text/css'>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$("#btn").click(function(){
var vname = $("#name").val();
var vemail = $("#email").val();
if(vname=='' && vemail=='')
{
alert("Please fill out the form");
}
else if(vname=='' && vemail!==''){alert('Name field is required')}
else if(vemail=='' && vname!==''){alert('Email field is required')}
else{
$.post("jquery_post.php",
{
name:vname,
email:vemail
},
function(response,status){
alert("*----Received Data----*nnResponse : " + response+"nnStatus : " + status);
$("#form")[0].reset();
});
}
});
});
</script>
</head>
<body>
<div id="main">
<h2>jQuery Ajax $.post() Method</h2>
<hr>
<form id="form" method="post">
<div id="namediv"><label>Name</label>
<input type="text" name="name" id="name" placeholder="Name"/><br></div>
<div id="emaildiv"><label>Email</label>
<input type="text" name="email" id="email" placeholder="Email"/></div>
</form>
<button id="btn">Send Data</button>
</div>
</body>
</html>
and in jquery_post.php I have this:
<?php
if($_POST["name"])
{
$name = $_POST["name"];
$email = $_POST["email"];
echo "Welcome ". $name ."!";
?>
It works just fine, but you have a syntax error in you jquery_post.php
<?php
if($_POST["name"])
{
$name = $_POST["name"];
$email = $_POST["email"];
echo "Welcome ". $name ."!";
} // you missed this
?>
it was returning Parse error: syntax error, unexpected end of file
Please try, this may help
<html>
<head>
<link href='http://fonts.googleapis.com/css?
family=Source+Sans+Pro|Open+Sans+Condensed:300|Raleway' rel='stylesheet' type='text/css'>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script>
<script>
$(document).ready(function(){
$("#btn").click(function(){
var vname = $("#name").val();
var vemail = $("#email").val();
if(vname=='' && vemail=='')
{
alert("Please fill out the form");
}
else if(vname=='' && vemail!==''){alert('Name field is required')}
else if(vemail=='' && vname!==''){alert('Email field is required')}
else{
$.post("post.php",
{
name:vname,
email:vemail
},
function(response,status){
alert("*----Received Data----*nnResponse : " + response+"nnStatus : " + status);
$("#form")[0].reset();
window.location.href = 'post.php';
});
}
});
});
</script>
</head>
<body>
<?php session_start(); ?>
<div id="main">
<h2>jQuery Ajax $.post() Method</h2>
<hr>
<form id="form" method="post">
<div id="namediv"><label>Name</label>
<input type="text" name="name" id="name" placeholder="Name"/><br></div>
<div id="emaildiv"><label>Email</label>
<input type="text" name="email" id="email" placeholder="Email"/></div>
</form>
<button id="btn">Send Data</button>
</div>
</body>
</html>
And in jquery_post.php I have made some changes When you post data to jquery_post.php it will create a session named "user" you can retrieve name any time from the session as I did.
<?php
session_start();
if(isset($_POST["name"]))
{
$_SESSION['user'] = $_POST["name"];
$name = $_POST["name"];
$email = $_POST["email"];
}
echo "Welcome ". $_SESSION['user'] ."!";
?>

Send and receive data from PHP

I'm new to web development, especially PHP, jQuery, AJAX...
I'm trying to make the user enter a name, then the index.html sends it to a php file, the php file saves it to a file of names and changes a div element with the id of status on the website.
I can't figure out the problem, the div element's inner HTML stays "processing..."
index.html
<html>
<head>
<script>
function ajax_post(){
document.getElementById("status").innerHTML = "processing...";
$.post("server.php", { username: $("#userName").val() }, function(data) {
$("#status").html(data);
})
}
</script>
</head>
<body>
<h2>Ajax Post to PHP and Get Return Data</h2>
Username: <input id="userName" name="userName" type="text"> <br><br>
<input name="myBtn" type="submit" value="Check" onclick="ajax_post();"> <br><br>
<div id="status"></div>
</body>
</html>
server.php
<?php
if(!empty($_POST['username'])){
$data = $_POST['username'];
echo 'You are now registered,' . $data;
$fname = "save.text";
$file = fopen($fname, 'a');
fwrite($file, $data . "\n");
fclose($file);
}
?>
I'm assuming my $.post syntax is wrong, but I don't really understand it.
Try this I have executed this code and it worked for me.
Index.html
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
function ajax_post(){
document.getElementById("status").innerHTML = "processing...";
console.log($("#userName").val());
$.post("server.php", { username: $("#userName").val() }, function(data) {
$("#status").html(data);
})
}
</script>
</head>
<body>
<h2>Ajax Post to PHP and Get Return Data</h2>
Username: <input id="userName" name="userName" type="text"> <br><br>
<input name="myBtn" type="submit" value="Check" onclick="ajax_post()"> <br><br>
<div id="status"></div>
</body>
</html>
Server.php
<?php
if(!empty($_POST['username'])){
$data = $_POST['username'];
echo 'You are now registered,' . $data;
$fname = "save.text";
$file = fopen($fname, 'a');
fwrite($file, $data . "\n");
fclose($file);
}
?>

reload a div and not the whole page using jquery

im trying to reload a table whenever the user hits the save button. but the problem is that the whole page is being reloaded.plz someone help.here is my javascript code:
$(document).ready(function(){
//save button listener
$("#save").click(function(){
//receiving data entered by user from design.php
var name = $('#name').val();
var email = $('#email').val();
var telephone = $('#telephone').val();
var username = $('#username').val();
var password=$('#password').val();
$.ajax({
type:'POST',
url: 'contactData.php',
data:{"name":name,"telephone":telephone,"email":email, "username":username, "password":password},
// dataType:'json',
success: function(data) {
var result = JSON.parse(data);
$("#validate").html(result.msg);
if (result.msg="Your info has been sent")
{
$("#table").load("design.php");
return false;
}
}//end of success
});//end of ajax
});//end of listener
});//end of javascript
and this is the div that i want to reload which is in the design.php page:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Contact Info</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src='jquery1.js'></script>
<script src='jqueryTest.js'></script>
</head>
<body>
<h2>Contact Information</h2>
<p><span class="error">* required field</span></p>
Name: <input type="text" id="name" >
<span class="error">* </span>
<br><br>
Email: <input type="text" id="email" >
<span class="error">* </span>
<br><br>
Telephone: <input type="text" id="telephone" >
<span class="error">* </span>
<br><br>
UserName: <input type="text" id="username">
<span class="error">*</span>
<br><br>
Password: <input type="password" id="password">
<span class="error">*</span>
<br><br>
<input type="button" id="save" value="save" >
<div id="validate"></div>
<div id="table">
<?php
$username = "root";
$password = "";
$host = "localhost";
$connector = mysql_connect($host,$username,$password)
or die("Unable to connect");
$selected = mysql_select_db("mysql", $connector)
or die("Unable to connect");
//execute the SQL query and return records
$result = mysql_query("SELECT * FROM users ");
?>
<table border="2" style= "background-color: #99ffcc; color: #761a9b; margin: 0 auto;">
<thead>
<tr>
<th>Name</th>
<th>Telephone</th>
<th>Email</th>
<th>Username</th>
<th>Password</th>
<tbody class="container">
<?php
while( $row = mysql_fetch_assoc( $result ) )
{
echo "<tr>
<td>{$row['name']}</td>
<td>{$row['telephone']}</td>
<td>{$row['email']}</td>
<td>{$row['username']}</td>
<td>{$row['password']}</td>
</tr>\n";
}
?>
</tbody>
</tr>
</thead>
</table>
</div>
when hitting the save button the whole page is being reloaded.what is the solution for div table only to be reloaded
Have only <div id="table"> in design.php file, in your original file have the <div id="show-table"> and in the success function of ajax store the whole page as Object and append to the div dynamically like this
var Obj = load('design.php');
$('#show-table').html(Obj);
Remember the design.php file has to separate file from the file where you have written the script

can I get text from html and put it into variable in php without submitting a form?

I have a form in html:
<form>
<label><input type="hidden" name="pNameChange" value=""></label>
</form>
and I want to get the value of this input in php without submitting it in a form.
this is my javascript:
var pName= null;
$(document).ready(function(){
$('img').click(function(){
pName= $(this).attr("name");
console.log(pName);
});
});
My php:
$pName = isset($_POST['pNameChange']) ? $_POST['value'] : '';
what I want is. you click on the picture,
1.the value of the name attribute of the picture is going to be saved into the variable pName (javascript),
2.it then goes into the form and changes the value of the form to the variable pName (javascript),
3.php picks up the value of the form (which should now be equal to pName),
4.then stores it into a variable $pName (php).
5.I also want $pName (php) to be globally used throughout all the pages of the website.
edit
this is my index page:
<?php
$pName = isset($_POST['pNameChange']) ? $_POST['value'] : '';
$db_connection = mysqli_connect('localhost','root','',"project_online_planner");
if (!$db_connection){
die('Failed to connect to MySql:'.mysql_error());
}
$query="SELECT * FROM project limit 5 ";
$results = mysqli_query($db_connection,$query);
$intro=mysqli_fetch_assoc($results);
?>
<!DOCTYPE HTML>
<html>
<head>
<title>Project planner online</title>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="ppo.js"></script>
<link rel="stylesheet" href="ppo.css"/>
</head>
<body>
<div id="bgNav">
<div id="login">
Register
Log in
</div>
<nav id="nav">
Home
</nav>
</div>
<h2 class="titlePage">Home</h2>
<div id="bgTile">
<?php
while($row = mysqli_fetch_array($results))
{
$project = $row["name"];
echo nl2br("<a href='project.php'>" ."<img name=\"$project\" width='100px' alt='Procject name' height='100px' class='tile' src=". $row['image'] ."/>". "</a>");
}
?>
<div class="tile" id="tileM"><h2>Meer</h2></div>
</div>
<form>
<label><input type="hidden" name="pNameChange" value=""></label>
</form>
</body>
</html>
what I want: click on the image then you get sent to the project page where (php) $pName is equal to the value of (javascript) pName
project page:
<?php
$newRecord = null;
$pName = isset($_POST['pNameChange']) ? $_POST['value'] : '';
$db_connection = mysqli_connect('localhost','root','',"project_online_planner");
if (!$db_connection){
die('Failed to connect to MySql:'.mysql_error());
}
//insert into database
if(isset($_POST['insertComments'])){
include('connect-mysql.php');
$username = $_POST['username'];
$comment = $_POST['comment'];
$sqlinsert = "INSERT INTO user_comments (username, comment, project) VALUES ('$username', '$comment', '$pName')";
if (!mysqli_query($db_connection, $sqlinsert)){
die('error inserting new record');
}
else{
$newRecord = "1 record added";
}//end nested statement
}
//text from database
$query="SELECT * FROM user_comments where project = '$pName' ";
$results = mysqli_query($db_connection,$query);
$intro=mysqli_fetch_assoc($results);
$query2="SELECT * FROM project where name = '$pName' ";
$results2 = mysqli_query($db_connection,$query2);
$intro2=mysqli_fetch_assoc($results2);
?>
<!DOCTYPE HTML>
<html>
<head>
<title>Project planner online</title>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="ppo.js"></script>
<link rel="stylesheet" href="ppo.css"/>
</head>
<body>
<div id="intro">
</div>
<div id="bgNav">
<nav id="nav">
Home
<a class="rightNav" href="register.php">Register</a>
<a class="rightNav" href="login.php">Log in</a>
</nav>
</div>
<div id="projectTile">
<span id="statusCheck"><?php print_r($intro2["status"]); ?></span>
<h2 id="prTitle"><?php print_r($intro2["name"]); ?></h2>
<div id="prPic"><img width="300" height="200" src="<?php print_r($intro2["image"]); ?>"></div>
<div id="prDescription"><?php print_r($intro2["description"]); ?></div>
</div>
<div id="comments">
<?php
while($row = mysqli_fetch_array($results))
{
echo nl2br("<div class='profile_comments'>" . $row['username'] . "</div>");
echo nl2br("<div class='comment_comments'>" . $row['comment'] . "</div>");
}
?>
</div>
<div id="uploadComments">
<form method="post" action="project.php">
<label for="name"><input type="hidden" name="insertComments" value="true"></label>
<fieldset>
<legend>comment</legend>
<label>Name:<input type="text" id="name" name="username" value=""></label><br/>
<label>Comments: <textarea name="comment" id="comment"></textarea></label>
<input type="submit" value="Submit" id="submitComment">
</fieldset>
</form>
</div>
<?php
echo $newRecord;
?>
<form>
<label><input type="hidden" name="pNameChange" value=""></label>
</form>
</body>
</html>
HTML:
do you have more then 1 image on page? its better if you add ID in image. No need for form and hidden fields for what you want done.
make sure your img has ID like <img id="imageID"...
JavaScript:
var pName= null;
$(document).ready(function(){
$('#imageID').click(function(){
pName= $(this).attr("name");
$.post("project.php", { pNameChange: pName },
function(data) {
// do something here.
});
});
});
above code should work as expected. Now in project.php > $_POST['pNameChange'] should receive the value of pName (image's name attr).
I don't understand what you want when you said $pName available globally on all pages. Please elaborate further, may be look into storing it as cookie/session?
EDIT:
Consider using session to pName value... by simple starting/resuming session in start of file:
<?PHP
session_start();
and then...
to set/update value:
if(isset($_POST["pNameChange"]))
$_SESSION["pName"] = $_POST["pNameChange"];
and then use $_SESSION["pName"] instead of $pName on all pages.
Try Ajax method in jQuery , hope it solves your problem
https://api.jquery.com/jQuery.ajax/
or
https://api.jquery.com/jQuery.post/
Actually, you do not need AJAX for this, all your index.php does it passes the image's name to project.php so try:
In index.php:
<form name='form1' method="post" action='project.php'> <!-- form attributes given -->
<label><input type="hidden" name="pNameChange" value=""></label>
</form>
Javascript:
var pName= null;
$(document).ready(function(){
$('img').click(function(){
//onclick of image, we will save the image name into the hidden input
//and submit the form so that it goes to project.php
$('input[name="pNameChange"]').val($(this).attr("name"));
$('form1').submit()
});
});
And in your project.php:
//now project.php can get the posted value of 'pNameChange'
//There is no input field with `name`->`value`, so $_POST['value'] is invalid.
$pName = isset($_POST['pNameChange']) ? $_POST['pNameChange'] : '';
And if you need this value across multiple pages, global will not work, use sessions.
ok this "additional" answer is to focus on session only. use the codes for client-end from my previous answer and try this on server-end.
index.php Page:
<?php
session_start();
$pName = isset($_SESSION['pNameChange']) ? $_SESSION['pNameChange'] : '';
project.php Page:
<?php
session_start();
$newRecord = null;
$pName = isset($_SESSION['pNameChange']) ? $_SESSION['pNameChange'] : null;
if(is_null($pName) && isset($_POST['pNameChange'])) {
$_SESSION['pNameChange'] = $_POST['pNameChange'];
$pName = $_POST['pNameChange'];
}
hope it helps

Jquery load() puts display and opacity in element style

I have an html that, by AJAX, fetches data from a php file and shows a table with the content ofthe database.
In another file, I try to call load(initial.html) to a div and the code shows up fine, but when I hit the button to retrieve the table, the element style of the div where the tabçe will be written shows up automatically "display: none; opacity: 0". And than in that table I have a tablesorter and it doesn't work.
But if I enter the original page all works, but I can't put it work if I load the html to another file.
Anyone can help me?
Thanks very much
EDIT:
I tried other way, but now the ("#teste").on('submit') doesn't work.
and if I put the code in the main page and forget the load() it works fine. Why is that?
Thank you for the help
Here is the code:
the main page, when o click link_1 I call load() to populate the div id="principal"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> Teste </title>
</head>
<link rel="stylesheet" href="css/index.css" />
<link rel="stylesheet" href="css/procura.css" />
<link rel="stylesheet" href="css/theme.blue.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="js/procura.js"></script>
<script type="text/javascript" src="js/jquery.metadata.js"></script>
<script type="text/javascript" src="js/jquery.tablesorter.js"></script>
<script type="text/javascript" src="js/jquery.tablesorter.widgets.js"></script>
<body>
<div id="banner-image">
<img src="images/logo.jpg" />
</div>
<div id="banner-content">
<a id="link_1" href="">Procurar Colaborador</a>
<a id="link_2" href="">Confirmação de Colaboradores</a>
</div>
<div id="principal">
</div>
</body>
</html>
The Html that I call called procura.html
<form action="" id="teste" method="post" enctype="multipart/form-data">
<div id="itemRows">
<p>
<select name="tipo_procura[]" >
<option value="" selected></option>
<option value="loja_integracao">Loja de Integração</option>
<option value="nome_completo">Nome</option>
</select>
<input name="valor_procura[]" type="text" maxlength="255" size="50" />
<input onclick="addRow(this.form);" class="form_button" type="button" value="Adicionar Procura" />
</p>
</div>
<input id="submit_button" type="submit" value="Procurar" />
</form>
<div class="result" id="result">
</div>
THE JS file procura.js
$(document).ready(function() {
$("#link_1").click(function(event) {
$("#principal").load("procura.html");
event.preventDefault();
});
$('#teste').on('submit', function(event) {
$.ajax({
url : 'procura_colaborador.php',
data : $(this).serialize(),
type : 'POST',
success : function(data) {
console.log(data);
$("#result").fadeOut('slow', function() {
$(this).html(data);
}).fadeIn("slow");
}
});
event.preventDefault();
});
});
var rowNum = 0;
function addRow(frm) {
rowNum++;
var row = '<p id="rowNum' + rowNum + '"><select name="tipo_procura[]" ><option value="" selected></option><option value="loja_integracao">Loja de Integração</option><option value="nome_completo">Nome</option></select><input name="valor_procura[]" type="text" maxlength="255" size="50" /><input type="button" value="Remover Procura" class="form_button" onclick="removeRow(' + rowNum + ');"></p>';
jQuery('#itemRows').append(row);
}
function removeRow(rnum) {
jQuery('#rowNum' + rnum).remove();
}
And the PHP file
$query = "SELECT * FROM colaboradores";
$result = mysqli_query($con, $query) or die(mysqli_error($con));
echo '<table id="tabela_resultados" class="tablesorter-blue">';
echo '<thead><tr><th>Loja de Integração</th><th>Nome</th><th>Telemóvel</th><th>NIF</th><th>Data de Nascimento<th>Nacionalidade</th><th>Acção</th></tr></thead><tbody>';
while ($gear = mysqli_fetch_array($result)) {
echo "<tr><td>";
echo $gear['loja_integracao'];
echo "</td><td>";
echo $gear['nome_completo'];
echo "</td><td>";
echo $gear['num_tlm'];
echo "</td><td>";
echo $gear['num_nif'];
echo "</td><td>";
echo $gear['data_nascimento'];
echo "</td><td>";
echo $gear['nacionalidade'];
echo "</td><td><a href=''>Contrato</a></td></tr>";
}
echo '</tbody></table>';
echo '<script type="text/javascript">$("#tabela_resultados").tablesorter();</script>';
if i understand you correctly
try to change your json function to retrive html data , because you cant't retrive json when you
do echo in php file if you want to retrive your table you must add to json function , dataType: "html"
$('#teste').on('submit', function(event) {
$.ajax({
url : 'procura_colaborador.php',
data : $(this).serialize(),
type : 'POST',
dataType: "html",
success : function(data) {
console.log(data);
$("#result").fadeOut('slow', function() {
$(this).html(data);
}).fadeIn("slow");
}
});
event.preventDefault();
});
});

Categories

Resources