I have a generic update query in a file, I know it is being called by the my projectscontroller but I do not know whether the issue is between the form and controller, form and function or function and controller.
My code is supposed to work where from the Project list form is populated with records with edit and delete buttons (this works),when the EDIT button is chosen the Editproject form will populate with the data in that line (this works). After editing the info displayed in the form the user presses save which calls the EDIT function in the project controller which in turn calls the save function then the update function and thus updates the database (this doesnt work). I am not sure where the error is as no error is occuring and i know the code is entering the EDIT function of the controller because after it does it opens the list again.
I am sure the error is some stupid typo i made somewhere, and if your wondering the save function can go to update or insert functions but the insert works perfectly fine.
This is why I'm 80% sure it has something to do with the update function itself or the way im passing the info to the update function.
Any help would be greatly appreciated, my project table create is at the end and like I said, I'm sure its as simple as a typo somewhere I am overlooking (it always is with me).
Update function (and save)
private function update($fields) {
$query = ' UPDATE `' . $this->table .'` SET ';
foreach ($fields as $key => $value) {
$query .= '`' . $key . '` = :' . $key . ',';
}
$query = rtrim($query, ',');
$query .= ' WHERE `' . $this->primaryKey . '` = :primaryKey';
//Set the :primaryKey variable
$fields['primaryKey'] = $fields['id'];
$fields = $this->processDates($fields);
$this->query($query, $fields);
}
public function save($record) {
try {
if ($record[$this->primaryKey] == '') {
$record[$this->primaryKey] = null;
}
$this->insert($record);
}
catch (PDOException $e) {
$this->update($record);
}
}
Project Controller
<?php
class ProjectController {
private $employeesTable;
private $projectsTable;
public function __construct(DatabaseTable $projectsTable, DatabaseTable $employeesTable) {
$this->projectsTable = $projectsTable;
$this->employeesTable = $employeesTable;
}
public function list() {
$result = $this->projectsTable->findAll();
$projects = array();
foreach ($result as $project) {
$projects[] = [
'IDP' => $project['IDP'],
'ProjectID' => $project['ProjectID'],
'ProjectName' => $project['ProjectName'],
'ProjectDes' => $project['ProjectDes'],
'ProjectStartDate' => $project['ProjectStartDate'],
'ProjectEndDate' => $project['ProjectEndDate'],
'ProjectStatus' => $project['ProjectStatus']
];
}
$title = 'Project list';
$totalProjects = $this->projectsTable->total();
return ['template' => 'projects.html.php',
'title' => $title,
'variables' => [
'totalProjects' => $totalProjects,
'projects' => $projects
]
];
}
public function home() {
$title = 'Colpitts Design';
return ['template' => 'home.html.php', 'title' => $title];
}
public function delete() {
$this->projectsTable->delete($_POST['id']);
header('location: index.php?action=list');
}
public function edit() {
if (isset($_POST['project'])) {
$project = $_POST['project'];
$project['projectstartdate'] = new DateTime();
$project['projectenddate'] = null;
$this->projectsTable->save($project);
header('location: index.php?action=list');
} else {
if (isset($_GET['id'])) {
$projects = $this->projectsTable->findById($_GET['id']);
}
$title = 'Edit Projects';
return ['template' => 'editproject.html.php',
'title' => $title,
'variables' => [
'project' => $projects ?? null
]
];
}
}
}
editproject form
<form action="" method="post">
<input type="hidden" name="project[IDP]" value="<?=$project['IDP'] ?? ''?>">
<label for="ProjectID">Type the Project id here:</label>
<textarea id="ProjectID" name="project[ProjectID]" rows="3" cols="40"><?=$project['ProjectID'] ?? ''?></textarea>
<label for="ProjectStatus">Type the Project status here:</label>
<textarea id="ProjectStatus" name="project[ProjectStatus]" rows="3" cols="40"><?=$project['ProjectStatus'] ?? ''?></textarea>
<label for="ProjectName">Type the Project name here:</label>
<textarea id="ProjectName" name="project[ProjectName]" rows="3" cols="40"><?=$project['ProjectName'] ?? ''?></textarea>
<label for="ProjectDes">Type the Project description here:</label>
<textarea id="ProjectDes" name="project[ProjectDes]" rows="3" cols="40"><?=$project['ProjectDes'] ?? ''?></textarea>
<input type="submit" name="submit" value="Save">
projectlist form
<p><?=$totalProjects?> projects are listed in the DanClock Database.</p>
<?php foreach($projects as $project): ?>
<blockquote>
<p>
<?=htmlspecialchars($project['ProjectID'], ENT_QUOTES, 'UTF-8')?>
<?=htmlspecialchars($project['ProjectDes'], ENT_QUOTES, 'UTF-8')?>
<?=htmlspecialchars($project['ProjectStartDate'], ENT_QUOTES, 'UTF-8')?>
<?=htmlspecialchars($project['ProjectStatus'], ENT_QUOTES, 'UTF-8')?>
Edit
<form action="index.php?action=delete" method="post">
<input type="hidden" name="id" value="<?=$project['IDP']?>">
<input type="submit" value="Delete">
</form>
</p>
</blockquote>
<?php endforeach; ?>
Projects table
CREATE TABLE `Projects` (
`IDP` int(11) NOT NULL AUTO_INCREMENT,
`ProjectID` int(11) NOT NULL,
`ProjectName` varchar(50) NOT NULL,
`ProjectDes` text,
`ProjectStartDate` Datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ProjectEndDate` Datetime,
`ProjectStatus` varchar(50) NOT NULL DEFAULT 'Active',
PRIMARY KEY (IDP)
) ENGINE=InnoDB;
I figured out the issue, as i thought it was my update function. It wasnt as "generic" as I thought it was, or it was almost.
this line:
//Set the :primaryKey variable
$fields['primaryKey'] = $fields['id'];
should be:
//Set the :primaryKey variable
$fields['primaryKey'] = $fields[$this->primaryKey];
Somethhing small that I didnt notice, now to continue on with everything else ><
Related
I try to insert my checkbox data in CodeIgniter. but data did not inserted in the database.
here is my view file:
<input type="checkbox" name="feature[]" value="WIFI" >
<input type="checkbox" name="feature[]" value="TV">
I am trying to use implode to convert the array into the string, but then I don't how to add in $data array, so they inserted in together
here is my controller:
public function save()
{
$this->load->model('Partner_model');
$feature = $this->input->post('feature');
$fea=array(
'feature'=>json_encode(implode(",",$feature))
);
$user_data= array(
'pname' => $this->input->post('pname'),
'type' => $this->input->post('type'),
'address' => $this->input->post('address'),
'about' => $this->input->post('about'),
'city' => $this->input->post('city'),
'code' => $this->input->post('code')
);
if($this->Partner_model->save($user_data,$fea))
{
$msg = "save sucesss" ;
}
else
{
$msg = "not save";
}
$this->session->set_flashdata('msg', $msg);
$this->load->view('partner_profile');
}
& here is my model:
public function save($data,$fea)
{
return $this->db->insert('property', $data,$fea);
}
Your model is faulty.
You are passing three arguments to insert() but the third you use is not appropriate.
That argument should be a boolean that indicates whether to escape values and identifiers or not. You need to incorporate $fea into $data which should probably be done in the controller.
There is an easier way to create the array $user_data since it is essentially a copy of $_POST just use $this->input->post().
Also, there is no obvious reason why you use json_encode. Unless you need it that way when you retrieve it from the DB there is no reason to bother with it. Consider removing json_encode.
First, change the model
public function save($data)
{
return $this->db->insert('property', $data);
}
Here's a revised save method
public function save()
{
$this->load->model('Partner_model');
$user_data = $this->input->post(); //makes a copy of $_POST
$feature = $this->input->post('feature');
if($feature) //because $feature will be null if no boxes are checked
{
$user_data['feature'] = json_encode(implode(",", $feature));
}
$msg = $this->Partner_model->save($user_data) ? "save sucesss" : "not save";
$this->session->set_flashdata('msg', $msg);
$this->load->view('partner_profile');
}
An explanation as requested via comments.
A call to $this->input->post('pname') returns the value of $_POST['pname'] if it is exists, but returns null if it does not exist.
When you create $user_data you make six calls to $this->input() with a different "key" each time to make a copy of $_POST.
$this->input->post() without any arguments returns the whole $_POST array. (See documentation)
$user_data = $this->input->post();
Makes a copy of $_POST using one line of code. It will include $_POST['feature'] if any boxes are checked, but $_POST['feature'] will not be set if no boxes are checked.
There are two ways to test if any boxes were checked. First we can test if isset($_POST['feature']) == true or we can test if $this->input->post('feature') == true. I use the second with the call
if($feature)
Which is pretty much the same as any of the following lines
if($feature != false)...
if($feature != null)...
if( ! empty($feature))...
if( ! is_null($feature))...
In other words, if($feature) evaluates as true if $feature is set and is anything except null, false, 0, "0", "" (an empty string), array() (an empty array)
public function save()
{
$this->load->model('Partner_model');
$feature = $this->input->post('feature');
$user_data= array(
'pname' => $this->input->post('pname'),
'type' => $this->input->post('type'),
'address' => $this->input->post('address'),
'about' => $this->input->post('about'),
'city' => $this->input->post('city'),
'code' => $this->input->post('code'),
'feature'=>json_encode(implode(",",$feature))
);
if($this->Partner_model->save($user_data)){
$msg = "save sucesss" ;
}else{
$msg = "not save";
}
$this->session->set_flashdata('msg', $msg);
$this->load->view('partner_profile');
}
model file should be :
public function save($data) {
return $this->db->insert('property', $data);
}
I am creating an event, each event will have attendees, I got this working fine, the problem I am having is an attendee can attend the same event twice, which is not good.
Event View
<?php if($this->session->userdata('user_id')): ?>
<hr>
<?php echo form_open('/attendees/add/'.$event['id']); ?>
<input type="hidden" name="user_id" value="<?php echo $_SESSION['user_id']; ?>">
<input type="submit" value="I'm in!" class="btn btn-success">
</form>
<?php endif; ?>
Attendees Controller
<?php
class Attendees extends CI_Controller {
public function add($event_id) {
// Check login
if(!$this->session->userdata('logged_in')){
redirect('users/login');
}
$this->form_validation->set_rules('user_id', 'required|callback_check_userid_eventid');
if($this->form_validation->run() === FALSE){
$this->session->set_flashdata('attendee_not_added', 'You are already on the list.');
redirect('home');
} else {
$this->attendee_model->add_attendee($event_id);
// Set message
$this->session->set_flashdata('attendee_added', 'You have been added to this event.');
redirect('events');
}
}
}
Attendees Model
<?php
class Attendee_model extends CI_Model {
public function __contruct() {
}
public function get_attendees($id = FALSE){
if($id === FALSE) {
$query = $this->db->get('attendees');
return $query->result_array();
}
$this->db->select('attendees.id, attendees.team, attendees.is_goalie, event.id, user.first_name, user.last_name');
$this->db->from('attendees');
$this->db->join('event', 'attendees.event_id = event.id', 'inner');
$this->db->join('user', 'attendees.user_id = user.id', 'inner');
$this->db->where('event.id', $id);
$query = $this->db->get();
return $query->row_array();
}
public function add_attendee($event_id){
$data = array(
'event_id' => $event_id,
'user_id' => $this->session->userdata('user_id')
);
return $this->db->insert('attendees', $data);
}
// Check attendee exists in event
public function check_userid_eventid($event_id, $user_id){
$query = $this->db->get_where('attendees', array('user_id' => $user_id, 'event_id' => $event_id));
if(empty($query->row_array())){
return true;
} else {
return false;
}
}
}
As you can see I tried creating a custom callback on the button form validation but it did not work.
If anyone can point me in the right direction, let me know if I am even somewhat close.
Thanks in advance.
You are not passing the $event_id value to the callback function. Replace your validation with the following line
$this->form_validation->set_rules('user_id', 'User ID', 'required|callback_check_userid_eventid['.$event_id.']');
add following callback function inside the Attendees Controller file
public function check_userid_eventid($user_id, $event_id){
$CI =& get_instance();
$CI->load->database();
$CI->form_validation->set_message('user_id_unique', "Sorry, that %s is already being used.");
return isset($CI->db) ? ($CI->db->limit(1)->get_where('attendees',compact('user_id','event_id'))->num_rows() == 0) : false;
}
Your callback is in a model that form validation knows nothing about. If you look at the docs: callbacks should be in the same controller as the form validation method that uses it.
However, you can use a function in a model as a callback with a different syntax:
$this->form_validation->set_rules(
'username', 'Username',
array(
'required',
array($this->users_model, 'valid_username')
)
);
as documented here.
Finally, on a false return, you need to make sure that you are setting a message as seen in this example:
public function username_check($str)
{
if ($str == 'test')
{
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
return FALSE;
}
else
{
return TRUE;
}
}
In conclusion: the documentation has all the answers.
Put the call back function into Controller
<?php
class Attendees extends CI_Controller {
public function add($event_id) {
// Check login
if(!$this->session->userdata('logged_in')){
redirect('users/login');
}
$this->form_validation->set_rules('user_id', 'required|callback_check_userid_eventid');
if($this->form_validation->run() === FALSE){
$this->session->set_flashdata('attendee_not_added', 'You are already on the list.');
redirect('home');
} else {
$this->attendee_model->add_attendee($event_id);
// Set message
$this->session->set_flashdata('attendee_added', 'You have been added to this event.');
redirect('events');
}
}
// Check attendee exists in event
public function check_userid_eventid($event_id, $user_id){
$query = $this->db->get_where('attendees', array('user_id' => $user_id, 'event_id' => $event_id));
if(empty($query->row_array())){
return true;
} else {
return false;
}
}
}
How can i upload csv file and save data in to my mysql database.
according to id.in cakephp 3
i am unable to do that. can any one help me.
my controller
public function import() {
if(isset($_POST["submit"])){
if($_FILES['file']['csv']){
$filename = explode('.', $_FILES['file']['csv']);
debug($filename);
if($filename[1]=='csv'){
$handle = fopen($_FILES['file']['csv'], "r");
while ($data = fgetcsv($handle)){
$item1 = $data[0];
// $item2 = $data[1];
// $item3 = $data[2];
// $item4 = $data[3];
$Applicants = $this->Applicants->patchEntity($Applicants, $item1);
$this->Applicants->save($Applicants);
}
fclose($handle);
}
}
}
$this->render(FALSE);
}
my view:
<div class="col-md-8">
<?= $this->Form->create('Applicants',['type' => 'file','url' => ['controller'=>'Applicants','action' => 'import'],'class'=>'form-inline','role'=>'form',]) ?>
<div class="form-group">
<label class="sr-only" for="csv"> CSV </label>
<?php echo $this->Form->input('csv', ['type'=>'file','class' => 'form-control', 'label' => false, 'placeholder' => 'csv upload',]); ?>
</div>
<button type="submit" class="btn btn-default"> Upload </button>
<?= $this->Form->end() ?>
</div>
Your question is a bit unclear what do you want to do in the controller do you want to update the existing records or save new data. If you want to update then only you need to use patchEntity.
The patchEntity should have a database entity fetched where in you can change or update the data as per your need, so in case if your first column contains the id of the Applications table then below code can work and in $data you can write whatever fields you want to update or add
So you can use the below code block instead
public function import() {
if(isset($_POST["submit"])){
if($_FILES['file']['csv']){
$filename = explode('.', $_FILES['file']['csv']);
debug($filename);
if($filename[1]=='csv'){
$handle = fopen($_FILES['file']['csv'], "r");
while ($data = fgetcsv($handle)){
$item1 = $data[0];
$data = array(
'fieldName' => $item1
);
// $item2 = $data[1];
// $item3 = $data[2];
// $item4 = $data[3];
$Applicant = $this->Applicants->newEntity($data);
$this->Applicants->save($Applicant);
}
fclose($handle);
}
}
}
$this->render(FALSE);
}
If you have more specific code/requirement then please share, so that I can help you out accordingly.
Here is my Solution to upload csv file and save database
public function import($id = NULL) {
$data = $this->request->data['csv'];
$file = $data['tmp_name'];
$handle = fopen($file, "r");
while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
if($row[0] == 'id') {
continue;
}
$Applicants = $this->Applicants->get($row[0]);
$columns = [
'written_mark' => $row[1],
'written_comments' => $row[2],
'viva_mark' => $row[3],
'viva_comments' => $row[4]
];
$Applicant = $this->Applicants->patchEntity($Applicants, $columns);
$this->Applicants->save($Applicant);
}
fclose($handle);
$this->set('title','Upload Student CSV File Input Number and others');
return $this->redirect($this->referer());
}
I have one little problem with checkboxes in yii. I have modal popup, where i have form for update.
Here is my controller:
public function actionUpdateroomrow(){
$model = Rooms::findOne($_POST['id']);
$model -> room_number_of_people = $_POST['room_number_of_people'];
$model -> room_name = $_POST['room_name'];
if(isset($_POST['room_air_conditioning']))
$model -> room_air_conditioning = $_POST['room_air_conditioning'];
else $model -> room_air_conditioning = false;
$model->update();
if (isset ($_POST['room_multimedia_id'])){
foreach($_POST['room_multimedia_id'] as $key => $value){
$model2 = RoomMultimediaData::findOne($value);
$model2 -> room_multimedia_data_value = $key;
var_dump($model2 -> errors);
}
}
$this->redirect('index');
}
Where is problem? In this row.
<div class="form-group">
<?php foreach($room_multimedia as $rm){ ?>
<label><?= $rm->room_multimedia_title ?></label><input type="checkbox" name="room_multimedia_id[<?= $rm->Checkmultimediadata($room->room_id,$rm->room_multimedia_id)->room_multimedia_data_id ?>]" value="<?= $rm->room_multimedia_id ?>"/>
<?php } ?>
</div>
This is row from update formular and im not really sure, where i failed.
In RoomMultimedia.php, modul i have this:
public function Checkmultimediadata($room_id,$room_multimedia){
return RoomMultimediaData::find()->where('room_id='.$room_id.' and room_multimedia_id='.$room_multimedia.'')->one();
}
Warning from yii:
PHP Warning – yii\base\ErrorException
Creating default object from empty value
$model2 -> room_multimedia_data_value = $key;
Can you help me solve this?
Thank you all! :)
my controller:
function getFeed()
{
$feed_url = $this->input->get("url");
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
foreach($x->channel->item as $entry) {
$feeds[] = array(
'title' => (string)$entry->title,
'url'=> (string)$entry->link,
'username' => $this->session->userdata('username')
);
$this->load->model('membership_model');
$this->membership_model->feeds($feeds);
}
Model:
function feeds($feeds_data)
{
$this->db->insert_batch('feeds', $feeds_data);
}
Is there a function to insert if only the row doesn't exists in the table? I have a table with 4 column : id,title,url,username. I have an anchor when i click him it calls geFeed function and insert the info into table. But i want to insert only if not exists.
I had the same challenge, so i eventually come up with a function which might be helpful to you.
function safe_update_batch($table_name,$records,$filter_field)
{
$filters=array();
foreach($records as $record)$filters[]=$record[$filter_field];
$this->db->query("SET SESSION group_concat_max_len=10000000");
$query=$this->db->select("GROUP_CONCAT($filter_field) AS existing_keys",FALSE)->where_in($filter_field, $filters)->get($table_name);
$row=$query->row();
$found_fields=explode(',',$row->existing_keys);
$insert_batch=array();
$update_batch=array();
foreach($records as $record)
{
if(in_array($record[$filter_field],$found_fields))$update_batch[]=$record;
else $insert_batch[]=$record;
}
if(!empty($insert_batch))$this->db->insert_batch($table_name,$insert_batch);
if(!empty($update_batch))$this->db->update_batch($table_name,$update_batch,$filter_field);
}
//sample usage
$this->safe_update_batch('feeds', $feeds_data,'title');
You can try this in your model!!
function insertClient($array)
{
$this->db->from('MyTable');
$this->db->where('Id', $array['Id']);
$query = $this->db->get();
if($query->num_rows() != 0){
$data = array(
'name'=>$array['name'],
'phone'=>$array['phone'],
'email'=>$array['email']
);
$this->db->where('Id', $array['Id']);
$this->db->update('CLIENTS', $data);
}else{
$data = array(
'name'=>$array['name'],
'phone'=>$array['phone'],
'email'=>$array['email']
);
$this->db->insert('CLIENTS',$data);
}
}
In controller:
$this->site_model->insertClient($_POST);
Sadly if you are using the active record class an INSERT IF NOT EXISTS function doesn't exist. You could try
Extending the active record class (easier said than done)
You could set indexes on certain columns as UNIQUE so that MySQL will check to see if it already exists
You could do some kind of SELECT before your INSERT to determine if the record is already there
For the queries where you need to do INSERT IF NOT EXISTS do $this->db->query('INSERT IF NOT EXISTS...')
function getFeed()
{
// Load the model up here - otherwise you are loading it multiple times
$this->load->model('membership_model');
$feed_url = $this->input->get("url");
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
foreach($x->channel->item as $entry) {
// check if the feed is unique, if true then add to array
if( $this->membership_model->singleFeedIsUnique($entry) == TRUE ){
$feeds[] = array(
'title' => (string)$entry->title,
'url'=> (string)$entry->link,
'username' => $this->session->userdata('username')); }
} //foreach
// check to make sure we got any feeds with isset()
// if yes, then add them
if (isset($feeds)){ $this->membership_model->feeds($feeds); }
}
You can try this in your model and leave you controller without changes
function feeds($feeds_data)
{
$data = array(
title => $feeds_data[0],
url => $feeds_data[1],
username => $feeds_data[2]
);
$this->db->select('*');
$this->db->from('mytable');
$this->db->where('title',$feeds_data[0]);//you can use another field
if ($this->db->count_all_results() == 0) {
$query = $this->db->insert('mytable', $data);//insert data
} else {
$query = $this->db->update('mytable', $data, array('title'=>$feeds_data[0]));//update with the condition where title exist
}
}
you can check the id if you have it, adding in the data array and use it to check if exist