Issue sending routed POST params - php

I have problems with a submit form (or with the routing design) that deletes N table based on id.
I've a made a simple routing function that use the index php file:
function relativeRouter ($controller,$action,$query_data=""){
$param = is_array($query_data) ? http_build_query($query_data) : "$query_data";
$url = "index.php?controller=$controller&action=$action&$param";
return $url;
The index create instances of controllers using controller=?&action=?.
It also bind the POST/GET params to the methods arguments (in an array, $params). (im already aware to not use directly calls to superglobals)
$params=array();
if(isset($_GET['controller'])&&isset($_GET['action'])){
$c = $_GET['controller'];
$a = $_GET['action'];
// add all query string additional params to method signature i.e. &id=x&category=y
$queryParams = array_keys($_GET);
$queryValues = array_values($_GET);
for ($i=2;$i<count($queryParams);$i++) {
$params[$queryParams[$i]] = $queryValues[$i];
}
if ($_POST) {
print_r($_POST); // THIS CONTAINS ONLY 1 PASSED ID.
// add all query string additional params to method signature i.e. &id=x&category=y
$queryParams = array_keys($_POST);
$queryValues = array_values($_POST);
for ($i=0;$i<count($_POST);$i++) {
$params[$queryParams[$i]] = $queryValues[$i];
}
}
include_once APP_ROOT."/controller/$c.php";
$controller = new $c();//CombustibiliController
$controller->$a($params);//inserimento
} else {
//attiva controller predefinito
$controller = new Admin();
$controller->index();
}
The routing works well in a form with different HTML form item names. (name='') but i'm expriencing problems by passing an array of id that are used for a multi-checkbox delete.
The $_POST is arriving with an array with only one items instead of many :
Array ( [ids] => 110 )
While works with no hassle with the insert form:
Array ( [title] => 435 [desc] => 5534 )
Here the table view:
<?php
if (isset($products)) {
$action = relativeRouter("ProductsController", "deleteProducts");
$html="<form id='multiselect' action='$action' method='POST'>\n";
foreach ($products as $product) {
$html.= "<tr>\n"
."<td><input type='checkbox' name='ids' value='".$product->id."'></td>\n"
."<td>".$product->id."</td>\n"
."<td>".$product->title."</td>\n"
."<td>".$product->description."</td>\n"
."<td>".$product->image."</td>\n"
."</tr>\n";
}
$html.="</form>\n";
echo $html;
}
?>
And here the jQuery that runs the form from a button:
<script>
function send() {
$('#multiselect').submit();
$('.play-confirm-modal').modal('hide');
}
$('.play-crud-delete').on('click',function(){
var checked = $( "input:checkbox:checked" ).length;
if(checked>0) {
$('.play-confirm-modal').modal('show');
console.log(checked);
} else {
alert("No selected checkboxes");
}
});
</script>
Hope someone can help. Firefox networks show module params but the POST only contains one of them, always the last.

<input type='checkbox' name='ids[]' value='".$product->id."'>
replace this and check. name should contain array operator for multivalue

Related

value stored as array in the database getting deleted while adding new values into the same array while updating

Here my problem is when i go for updating the values already stored in the database is getting deleted and only the newly added values are getting
here is my code
<script>
$(document).ready(function() {
if(destId=='bar3' || sourceId=='bar3') {
var itemvalue2 =Array();
$('ul#bar3 li').each(function() {
itemvalue2.push($(this).attr("value"));
});
document.getElementById("bar3-output").value=itemvalue2;
}
});
</script>
here is my view
<ul id="bar3" class="block__list block__list_tags">
<input type="hidden" id="bar3-output" name="all_active_menu3" class="form-control"
value="<?php if(!empty($team_info->members)) {
$tagsArray = explode(',', $team_info->members);
$tagsLinksArray = array();
foreach($tagsArray as $tag) {
$tagName = trim($tag);
$tagsLinksArray[]=$tagName;
}
$tagsLinks = implode(',', $tagsLinksArray);
echo $tagsLinks;}?>
">
</ul>
Here is my control
public function save_team($team_id = NULL)
{
$profile_data=$this->Teams_model->array_from_post(array('team_name'));
$this->Teams_model->_table_name = 'tbl_teams'; // table name
$this->Teams_model->_primary_key = 'team_id'; // $id
if (!empty($team_id)) {
$profile_data['members']=$this->input->post('all_active_menu3');
$this->Teams_model->save($profile_data, $team_id);
} else {
$profile_data['members']=$this->input->post('all_active_menu3');
$this->Teams_model->save($profile_data);
}
if (!empty($team_id)) {
$message = ('Team Info Updated');
} else {
$message = ('Team Info Saved');
}
$type = 'success';
set_message($type, $message);
redirect('admin/team/team_list'); //redirect page
}
the value in the database is not becoming stable i had used many ideas but didn't reached destination.hope your help please help me
I'm not certain how your code works but here is what my guess is and what is going wrong: You're just replacing the old value in both cases.
This seems to be the relevant code fragment.
$profile_data=$this->Teams_model->array_from_post(array('team_name'));
//...
if (!empty($team_id)) {
$profile_data['members']=$this->input->post('all_active_menu3');
$this->Teams_model->save($profile_data, $team_id);
} else {
$profile_data['members']=$this->input->post('all_active_menu3');
$this->Teams_model->save($profile_data);
}
The first assignment of $profile_data reads the current team data from the existing team. Your naming is a bit confusing as you're not actually reading any POST data it seems. The assignment within the if block that would fulfill the condition !empty($team_id) should update the team members and the false block should create a new team. Did you verify that $team_id gets set successfully?
I'm not certain about the structure of the team information but rather than a straight assignment using = in the true block you should be using += or manually combine the new and old data and do the assignment afterwards.
Using something like array_merge or a loop to create an intermittent object to hold the combined data should work here.

Get ID but display Name

I have an autocomplete field in my form that lets me select a contact name and associate it with a listing.
On the edit page however, it will display the contact ID and not his firstname and lastname.
How can I do that?
This is getEdit() method in ListingsController.php
public function getEdit($id)
{
// get the nerd
$listings = Listing::find($id);
$listings->images = Image::where('listing_id', $id)->get();
$ImagesFileName = "";
$listings->imagesFiles = "";
if ($listings->images) {
foreach ($listings->images as $CurImage) {
$ImagesFileName[] = $CurImage['image_name'];
}
$listings->imagesFiles = implode(",", $ImagesFileName) ;
}
$query = DB::table('contacts')->get();
foreach ($query as $firstname)
{
$name[] = $firstname->firstname." ".$firstname->lastname;
}
$fullname = json_encode($name);
// show the edit form and pass the nerd
$this->layout->content = View::make('listings/edit')
->with('listings', $listings)
->with('getClientsByLetters', $fullname);
}
This is action_getClientsByLetters() in ListingsController.php
public function action_getClientsByLetters() {
$term = Input::get('query');
$data = array();
$query = DB::query("
SELECT * FROM contacts
WHERE MATCH (contact)
AGAINST('+".$term."*' IN BOOLEAN MODE)
");
foreach ($query as $results => $contact) {
$data[] = array(
'id' => $contact->id,
'value' => $contact->firstname
);
}
return json_encode($data);
}
This is the field in views/listings/edit.blade.php
<p>{{ Form::text('contact_id', null, array('class'=>'form-control', 'placeholder'=>'Contact Name', 'id'=>'contact', 'onblur'=>'test()')) }}</p>
And this is the javascript code on the same view
$(function() {
var availableTags = <?php echo $getClientsByLetters; ?>;
$( "#contact" ).autocomplete({
source: availableTags,
minLength: 2,
});
});
I think this is just a problem of approach. Normally I would just set up this kind of field as a SELECT control, using the ID as the key field and the name as the displayed option values. In all modern browsers you get progressive autocomplete on SELECT controls by default. One important question, however, is whether you are intending users to be able to add arbitrary new names to this field, or if it is intended to only allow existing names with assigned IDs to be entered. In the latter case then yes, we probably need to figure out how to get your autocomplete text field to work instead.
Your action_getClientsByLetters looks close, but I don't think it's ever being run.
Autocomplete is accepting an array of strings or an array of objects where each object has both a label and a value, which I think is what you should be aiming for.
With that in mind, I'd add a function whose sole responsibility is to fetch the contacts and put them in the required form that autocomplete is expecting, which you would probably be using the array of objects because it looks like your going to need the ID later.
function getContacts()
{
$contacts = Contact::all();
$autoComplete = array();
foreach($contacts as $contact) {
$autoComplete[]['label'] = $contact->first_name . ' ' . $contact->last_name;
$autoComplete[]['value'] = $contact->id;
}
return json_encode($autoComplete);
}
Then you'd call the view with...
$this->layout->content = View::make('listings/edit')
->with('listings', $listings)
->with('getClientsByLetters', $this->getContacts());

Form validation for multiple text input Codeigniter

Array values in form are always a problem for form validation in CI. Now I've to input multiple values and those array values are to be stored in DB. Now the user can keep some fields blanks by mistake as shown below in the links:
Input values.
Values in the array on submission.
I used this tutorial to add input boxes on + button click. On submission the blank values will be truncated and then not null array values will added to database. I tried this using a sample program in native PHP but could not implement it in CI.
I used the following code in native PHP to insert values in DB truncating null values:
<?php
include 'sql_connect.php';
$str = array();
for($i=0;$i<count($_POST["txtSiteName"]);$i++)
{
$str[] = $_POST["txtSiteName"][$i];
}
$str = array_filter($str, function($item) {if(!is_null($item)) return $item;});
foreach($str as $loop_str)
{
$arr_str[] = $loop_str;
}
for($k = 0; $k<count($arr_str);$k++)
{
mysql_query("INSERT INTO sitename (name) VALUES ('".$arr_str[$k]."')") or die(mysql_error());
}
print_r($arr_str);
?>
How can I achieve this in CI ?
I tried to use callback function but the array value is not being passed to the callback function.
EDIT:
The below code shows my callback function :
On entering 3 urls it is called 3 times. Is that normal ?
Also my array_walk's callback function is not working. Calling a callback function inside another callback function is not possible ?
public function null_check()
{
$urls = $this->input->post('link_name');
array_walk($urls, 'prepurl');
var_dump($urls);
}
prepurl function:
public function prepurl($item, $key)
{
$item = "http://".$item;
}
Your question is not clear to me but since you mentioned to validate multiple text boxes. So if your text boxes are something like this
<input type="text" name="txtSiteName[]" />
<input type="text" name="txtSiteName[]" />
then simply you can use
$this->form_validation->set_rules('txtSiteName[]', 'Site Name', 'required|xss_clean');
to validate all the text boxes against null or empty.
Update (TO pass an argument in to the callback)
$this->form_validation->set_rules('txtSiteName[]', 'Site Name', 'callback_sitename_check[' . $this->input->post('txtSiteName') . ']');
function sitename_check($str, $sitenames) {
// $sitenames will be your textboxe's array
}
The first argument is used by CodeIgniter by default so second argument is your parameter. Also take a look at insert_batch() to insert multiple records.
Also you can do this like
$this->form_validation->set_rules('txtSiteName[]', 'Site Name', 'callback_sitename_check');
function sitename_check() {
$sitenames = $this->input->post('txtSiteName');
}
Update: (For array_walk)
array_walk($urls, array($this, 'prepurl'));
Here is a simple process of doing it
Set message like this
$this->form_validation->set_rules('txtSiteName[]', 'Site Name', 'required|xss_clean|callback_check_array');
Here is callback
function check_array()
{
$txtSiteName = $this->input->post('txtSiteName');
$error = 0;
foreach($txtSiteName as $key => $value)
{
if(!empty($value)){
$error = $error + 1;
}
}
if($error == 0){
return TRUE;
}else{
$this->form_validation->set_message('check_array', 'All fields are empty. Please provide at leaset 1');
return FALSE;
}
}
When validation is successfull run this code or modify according to your requirements
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$txtSiteName = $this->input->post('txtSiteName');
foreach($txtSiteName as $key => $value)
{
if(!empty($value)){
$data['name'] = $value;
$this->mymodel->insert($data);
}
}
}
Model Method
function insert($data)
{
$this-db->insert('table_name',$data);
}

cakephp getting value of textfield in model

Hi I have dynamically added input fields on my add view. When I submit my form I want all them input fields to be concatenated into one string and stored in a single database field.
Im trying to achieve this using the beforeSave method of cakephp but I can't seem to find out how to get the values of a text field within the Model.
function beforeSave($options)
{
$result = '';
$bool = true;
$counter = 0;
while($bool == true)
{
$result = $result + ',' + $this->data['Variable']['selectOptions' + counter];
}
return true;
}
Anyone any ideas on how to achieve this?
Thanks in advance.
In my opinion (from MVC point of view) it would be better to concatenate the fields in controller and then unset unnecessary fields before saving the model...
after get the post values in model you can merge the array values into a single variable like this..
<?php
$var = array('test1','test2','test3','test4','test5','test6');
$new_values = implode(',',$var);
echo $new_values;
?>
You can retrieve these values after saving to database.
this might not be the perfect answer but might give you some head start in that direction
function beforeSave($options = array()) {
pr($this->data); // <= show data you intend to save
exit;
}
use foreach to loop the data array ($this->data) and perform concatenation on the values and assign the concatenated string to the feild name
function beforeSave($options = array()) {
foreach ($this->data['Variable'] as $key=>$value)
{
$feildflag = strstr($key, 'selectOptions');
if($feildflag){
$concatenatedstring .= $value;
}
}
$this->data['Variable']['your_feild_name'] = $concatenatedstring ;
}
Your dynamic form field should looks like in a foreach loop:
<?php echo $this->Form->input('Model.field][', array());
In your model:
function beforeSave($options)
{
if(!empty($this->data))
{
$this->data['Model']['common_field'] = implode(",", $this->data['Model'['field'];
unset($this->data['Model']['field']);
}
}

How to alter Symfony form array value before saving?

I have a form and after submission, I can view the form values using: var_dump($this->form->getValues();. One of my form values (from a multi-select widget) is this:
["cat_list"]=>
array(1) {
[0]=>
string(1) "1"
}
I wish to append a value to this array before saving the form. How do I do this? I thought I can do this:
$values = $this->form->getValues();
array_push($values['cat_list'], '99'); // <--- 99 is the number I want to append
$this->form->setCatList($values['cat_list']);
$this->form->save();
But that doesn't work:
Call to undefined method FrontendOfferForm::setCatList.
Any clues?
In the action where you initialize the form before the validation (normally in either the create or the update function), just pass to the form an empty object with the value you want to add arbitrarily already set.
Let's call your form myModelForm and your model myModel.
In the action (before the processForm)
$obj = new myModel();
$obj->setCatList(array(99));
$this->form = new myModelForm($obj);
This should work
You should override doUpdateObject function in the form calss.
protected function doUpdateObject($values)
{
parent::doUpdateObject($values);
if (isset($values['cat_list']))
{
$carList = is_array($values['cat_list']) ? $values['cat_list'] : array($values['cat_list']);
array_push($catList, 99);
$this->getObject()->setCatList($catList)
}
}
And that's it. You should call only $this->form->save() in the action.
You should have an other method than the one from #1ed.
When you save the form, it returns the object. So, you have to save the form first and then, update the cat_list:
$values = $this->form->getValues();
$object = $this->form->save();
array_push($values['cat_list'], '99'); // <--- 99 is the number I want to append
$object->setCatList($values['cat_list']);
$object->save();
By the way, if you choose the solution from #1ed, you should use an external parameter to define your 99, if you want to be able to use something else than 99.
Like:
$this->form->catListExtraValue = 99;
$this->form->save();
Then:
public $catListExtraValue = null;
protected function doUpdateObject($values)
{
parent::doUpdateObject($values);
if (isset($values['cat_list']) && null !== $this->catListExtraValue)
{
$carList = is_array($values['cat_list']) ? $values['cat_list'] : array($values['cat_list']);
array_push($catList, $this->catListExtraValue);
$this->getObject()->setCatList($catList)
}
}

Categories