I am learning OOP in PHP and in an exercise, I don't know how to send form data to objects and enter the objects in an array. I was going through a lot of Youtube tutorials and forums but I couldn't find or understand much.
The exercise first asks for a class to manage the products of a supermarket whose attributes are the numeric key, the description, the price and the stock. It also asks me to define a constructor with parameters as methods.
<?php
class Product{
private $key;
private $description;
private $price;
private $stock;
public function __construct($key, $description, $price, $stock){
$this->key = $key;
$this->description = $description;
$this->price = $price;
$this->stock = $stock;
}
public function setKey($key){
$this->key = $key;
}
public function getKey(){
return $this->key;
}
public function setDescription($description){
$this->description = $description;
}
public function getDescription(){
return $this->description;
}
public function setPrice($price){
$this->price = $price;
}
public function getPrice(){
return $this->price;
}
public function setStock($stock){
$this->stock = $stock;
}
public function getStock(){
return $this->stock;
}
}
Then it asks me to use that class to declare an array of objects and control an inventory of up to 50 products using the POST method. In addition this program must have a menu with the next items: Add product, Remove product, List product, Sort product by key number and Exit.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<form method="post">
<label for="key">Enter product key</label></br>
<input type="number" name="key" id="key" required></br>
<label for="description">Enter product description</label></br>
<input type="text" name="description" id="description" required></br>
<label for="price">Enter product price</label></br>
<input type="text" name="price" id="price" required></br>
<label for="stock">Enter the stock of the product</label></br>
<input type="number" name="stock" id="stock" required></br>
<button type="submit" name="add" id="add">Add product</button>
<button type="submit" name="baja" id="baja">Remove product</button>
<button type="submit" name="list" id="list">List product</button>
<button type="submit" name="Sort" id="Sort">Sort product</button>
<button type="submit" name="exit" id="exit">Exit</button>
</form>
</body>
</html>
Here is the problem: I don't know how to insert the object in the array without deleting the previous ones and I don't know how to print all the entered objects.
<?php
if (strlen(session_id()) < 1) {
session_start();
}
include_once("product.php");
if(isset($_POST["add"])){
$_SESSION["quantity"] = $_SESSION["quantity"] +1;
$quantity = $_SESSION["quantity"];
if($quantity<=50){
$oproduct = new Product($_POST["key"], $_POST["description"], $_POST["price"],
$_POST["stock"]);
$oproduct->setKey($_POST["key"]);
$oproduct->setDescription($_POST["description"]);
$oproduct->setPrice($_POST["price"]);
$oproduct->setStock($_POST["stock"]);
$_SESSION["prod"]= $oproduct;
print_r($_SESSION["prod"]);
}
}
Dynamically append [] a new product to the array:
$_SESSION["prod"][] = $oproduct;
Or you could use key if it is unique:
$_SESSION["prod"][$_POST["key"]] = $oproduct;
Also, it looks like you have already added the info here:
$oproduct = new Product($_POST["key"], $_POST["description"], $_POST["price"], $_POST["stock"]);
So why are you doing this?
$oproduct->setKey($_POST["key"]);
$oproduct->setDescription($_POST["description"]);
$oproduct->setPrice($_POST["price"]);
$oproduct->setStock($_POST["stock"]);
Related
I must save x2 the same data fields (nif and name) at the same time in the DB.
With 1 field (nif) it works perfectly and save x2 rows in the DB with different info, so the JSON works, but adding the 2th field (name) it just save the nif value in all the fields.
I don't understand so much the JSON and his syntax logic, but I think the problem is how I wrote it in the controller.
P.D. No, I can't put EnviarCurriculumPreguntas::create x2 in a row because that's not the purpose of this code, so I'm using a JSON instead.
EnviarCurriculum.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class EnviarCurriculum extends Model
{
protected $table = 'table';
protected $primaryKey = 'ID_table';
protected $fillable = [
'nif',
'name'
];
public function getRepeatedFields()
{
return json_decode($this->nif);
return json_decode($this->name);
}
}
EnviarCurriculumController.php
namespace App\Http\Controllers\enviarCurriculum;
use App\EnviarCurriculum;
use App\Configuracion;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class EnviarCurriculumController extends Controller
{
public function index()
{
return view('enviar_curriculum', ['EnviarCurriculum' => new EnviarCurriculum()]);
}
public function create()
{
return view('enviar_curriculum', ['EnviarCurriculum' => new EnviarCurriculum()]);
}
public function store(Request $request)
{
foreach (request('nif', 'name') as $val) {
EnviarCurriculum::create(['nif' => $val, 'name' => $val]);
}
}
}
enviar_curriculum.blade.php
<!DOCTYPE html>
<html lang="es">
<head>
...
</head>
<body>
<form action="{{ route("store") }}" method="POST">
#csrf
<div>
<input type="text" name="nif[]" id="nif">
<input type="text" name="name[]" id="name">
</div>
<br>
<div>
<input type="text" name="nif[]" id="nif">
<input type="text" name="name[]" id="name">
</div>
<input type="submit" class="btn btn-primary" value="Enviar">
</form>
</body>
</html>
you can't have input having the same name without being an array
<!DOCTYPE html>
<html lang="es">
<head>
...
</head>
<body>
<form action="{{ route("store") }}" method="POST">
#csrf
<div>
<input type="text" name="nif[]" id="nif">
<input type="text" name="name[]" id="name">
</div>
<br>
<div>
<input type="text" name="nif[]" id="nif">
<input type="text" name="name[]" id="name">
</div>
<input type="submit" class="btn btn-primary" value="Enviar">
</form>
</body>
</html>
Then in your store method loop the array inputs
public function store(Request $request)
{
$nifs = $request->input('nif', []);
$names = $request->input('name', []);
foreach ($nifs as $key => $nif) {
EnviarCurriculum::create(['nif' => $nif, 'name' => $names[$key]??'']);
}
}
Then fix your getRepeatedFields() method to return both decoded fields.
public function getRepeatedFields()
{
return [
'nifs' => json_decode($this->nif),
'names' => json_decode($this->name),
];
}
<input type="text" name="nif[]" id="nif">
<input type="text" name="name[]" id="name">
in name , nif only store the last inserted item please change it as array
I am trying to make a search bar for my application.
I am using the following Mini Framework: https://github.com/panique/mini
What I want to do is have an input field where you type an username, and then a table is displayed underneath with all the information from the Database.
Environment:
PHP 7.4
Apache
CentOS 8
SQL Server 2019
My problem is, I don't know how to pass the input value to the controller and then to the model.
Let me show you what I have tried:
Account Model:
public function getUser($name)
{
$sql = "SELECT * FROM dbo.user_table WHERE Name = :name ORDER BY UserID DESC";
$query = $this->db->prepare($sql);
$query->execute(array(':name' => $name));
return $query->fetchAll();
}
Account Controller:
/**
* ACTION: getUser
*/
public function getUser()
{
if(isset($_POST['search_user'])) {
$checkUser = $this->model->getUser($_POST['username']);
}
}
My View:
<form action="<?php echo URL; ?>account/getUser" method="POST" class="mb20">
<div class="row">
<div class="input-wrap col-sm-12">
<input type="text" placeholder="Type username" name="username" autocomplete="off" />
</div>
</div></br>
<input type="submit" value="Search" name="search_user" />
</form>
I am not sure how to echo the result in the view. Maybe someone here could guide me in the correct direction.
Thanks!
Account Controller:
/**
* ACTION: getUser
*/
public function search()
{
if(isset($_POST['search_user'])) {
$checkUser = $this->model->getUser($_POST['username']);
}
require APP . 'view/search/index.php'; // your search view path
}
Search View:
<form action="<?php echo URL; ?>search" method="POST" class="mb20">
<div class="row">
<div class="input-wrap col-sm-12">
<input type="text" placeholder="Type username" name="username" autocomplete="off" />
</div>
</div></br>
<input type="submit" value="Search" name="search_user" />
</form>
<?php
if (isset($checkUser)) {
echo '<ul>';
foreach ($checkUser as $key => $value) {
echo '<li>';
echo $value->name;
echo '</li>';
}
echo '</ul>';
}
In this way, if there's the $_POST['search_user'], the function search will perform the search and put the result on the $checkUser variable. The variable will be still present on the View because you're requiring it after the $checkUser declaration. Then, the View checks if the variable is present and displays the results.
IMPORTANT
The line echo $value->name; is a dangerous behavior, because it can allow XSS, so, before rendering anything from the database, remember to escape it properly. Some ways to do it:
How to prevent XSS with HTML/PHP?
https://www.php.net/manual/pt_BR/function.strip-tags.php
I've been struggling with a problem that doesn't allow me to delete my items from Cart. Whenever I try to do that, the error occurs with name "POST parameter id is required".
On the contary, it surprisingly works with adding items to the cart. This is the script I use for showing items in the cart, and deleting:
<div class="container">
<?php
foreach(Cart::GetRooms() as $room) {
?>
<div>
<div class="media">
<img class="align-self-start mr-3" src="<?=$room->GetData()["icon_url"]?>" alt="Room icon" width="200px">
<div class="media-body">
<h5 class="mb-0"><?=$room->GetData()["title"]?></h5>
<div class="clearfix">
<p>Cena: <span class="text-success font-weight-bold"><?=$room->GetData()["price"]?> <?=SHOP_CURRENCY?></span></p>
<form method="post" action="/api/cart/removeItem.php">
<input type="hidden" name="room_id" value="<?=$room->GetData()["id"]?>" />
<button class="btn btn-primary" type="submit">X</button>
</form>
</div>
</div>
</div>
</div>
<?php
}
?>
This is the script that is supposed to remove items from the cart
<?php
require_once "../../settings.php";
$id = POST("id", true);
Cart::RemoveFromCart((int) $id);
http_response_code(302);
header("Location: /cart.php");
public static function RemoveFromCart(int $id) : bool {
$db = MysqliDb::getInstance();
$db->where("id", $id);
$db->delete("cart");
return true;
}
and this is the POST function i wrote myself in case it was needed
function POST(string $key, bool $required=false, bool $secure=true) {
if(!isset($_POST[$key])) {
if($required) {
exit("POST parameter $key is required");
}
else {
}
}
$return_val = $_POST[$key];
if($secure) {
$return_val = htmlentities($return_val);
}
return $return_val;
}
in your form you have
<input type="hidden" name="room_id" value="<?=$room->GetData()["id"]?>" />
but in your script you are looking for a id property inside the request, so you should change it either to this
<input type="hidden" name="id" value="<?=$room->GetData()["id"]?>" />
or to this:
$id = POST("room_id", true);
I have created a custom section to my WordPress theme, however, whenever the section is printed, inline style is added to hide the section. Here is the section declaration, the custom section registration, and its use:
<?php
/* Theme Test Data */
class theme_test_data extends WP_Customize_Section {
public $type = "theme_test_data";
public $test_url = "";
public $test_text = "";
public $test_link_text = "";
public function json() {
$json = parent::json();
$json['test_text'] = $this->test_text;
$json['test_link_text'] = $this->test_link_text;
$json['test_url'] = esc_url( $this->test_url );
return $json;
}
public function render_template() {?>
<li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
<form method="POST" action="{{data.test_url}}">
<input type="hidden" name="testdatainstall" value="1"/>
<?php wp_nonce_field('theme.initialize');?>
<h3 class="accordion-section-title">
<span>{{data.test_text}}</span>
<button type="submit" class="theme_customizer_doc_button btn">{{data.test_link_text}}</button>
</h3>
</form>
</li>
<?php }
}
//Theme registration
$wp_customize->register_section_type( 'theme_test_data' );
//Add section
$wp_customize->add_section(new theme_test_data($wp_customize, 'theme_test_data', array(
'title' => __('Section Title', 'theme_language'),
'test_url' => admin_url('edit.php'),
'test_text' => __('Install our test data', 'theme_language'),
'test_link_text' => __('Install', 'theme_language'),
'priority' => 1000
)));
In the HTML output however, it is rendered like this:
<li id="accordion-section-theme_test_data" class="accordion-section control-section control-section-theme_test_data" aria-owns="sub-accordion-section-theme_test_data" style="display: none;">
<form method="POST" action="{hiddenforprivacy}">
<input name="testdatainstall" value="1" type="hidden">
<input id="_wpnonce" name="_wpnonce" value="24923e18ae" type="hidden"><input name="_wp_http_referer" value="/wp/wp-admin/customize.php?return=%2Fwp%2Fwp-admin%2Fedit.php" type="hidden">
<h3 class="accordion-section-title">
<span>Install our test data</span>
<button type="submit" class="theme_customizer_doc_button btn">Install</button>
</h3>
</form>
</li>
You got any clue? I tried them all :(
The WordPress Section is composed of a HTML structure and a JavaScript section. I had not set the section as always active via JavaScript. I have done as follows:
api.sectionConstructor['theme_test_data'] = api.Section.extend( {
// No events for this type of section.
attachEvents: function () {},
// Always make the section active.
isContextuallyActive: function () {
return true;
}
} );
I'm trying to post some information from a from do so some calculations, however for some reason that data isn't posting. I do a var_dump after I get the info, and it still is blank. Any help would be great.
My Controller:
<?php
class Timevalueshow extends Controller{
function index(){
$this->load->view('Timevalueshow_view');
}
function submit(){
$years = $this->input->post('years');
$rate = $this->input->post('rate');
$principle = $this->input->post('principle');
$periods = $this->input->post('periods');
$isCont = $this->input->post('continuous');
var_dump($years);
$params = array(
'years' => $years,
'rate' => $rate,
'principle' => $principle,
'periods' => $periods,
'isCont' => $isCont
);
var_dump($params);
$this->load->library('timevalue',$params);
$this->timevalue->leprint();
}
}
?>
And the view file.
<head>
<title>Time Value of Money</title>
</head>
<body>
<div id="container">
<form method="POST" action="http://localhost:8888/CodeIgniter_1.7.2/index.php/timevalueshow/submit">
<p>Years: </p> <input id="years" type="text" />
<p>Rate: </p> <input type="text" id="rate"/>
<p>Principle: </p> <input type="text" id="principle"/>
<p>Periods: </p> <input type="text" id="periods"/>
<p>Continuous?: </p> <input type="checkbox" id="continuous"/>
<input type="submit" value="Submit"/>
</form>
</div>
</body>
You didn't submitted the form elements' name's only their id's. Edit your form so the elements contain name attributes too.