Laravel Display Array on blade with "unserialize" - php

im facing an issue to retrive an array from my database and display it on my blade.
So to understand my work, im actualy saving "Cart" informations on my "Orders Table" with Serialize the Products
public function store(Request $request)
{
$order = new Order();
$order->user_id = request('user_id');
$order->wilaya = request('wilaya');
$order->province = request('province');
$order->address = request('address');
$order->phone = request('phone');
$order->quantity = request('quantity');
$order->subtotal = request('total');
$order->status = request('status');
$products = [];
$i = 0;
foreach (Cart::content() as $product){
$products['product_' . $i][]= $product->name;
$products['product_' . $i][]= $product->options->color;
$products['product_' . $i][]= $product->price;
$products['product_' . $i][]= $product->options->size;
$products['product_' . $i][]= $product->options->image;
$products['product_' . $i][]= $product->qty;
$i++;
}
$order->products = serialize($products);
//dd($order);
if(Cart::count() <= 0){
return redirect('/products');
}else{
$order->save();
Cart::destroy();
return view('checkout.thankyou');
}
}
So when i try to retrive my data from the "Products" column with Unserialize on my show ressource
public function show($id)
{
$orderShow = Order::find($id);
$arr = unserialize($orderShow->products);
dd($arr);
return view('dashboard.order.show', compact('orderShow', 'arr'));
}
I get this result
array:2 [▼
"product_0" => array:6 [▼
0 => "T-Shirt Fashion 3"
1 => "black"
2 => 1300.0
3 => "S"
4 => "QFh840we7wZBKO790A6wFlipJB1ASaCpt3zJhJl8.png"
5 => 1
]
"product_1" => array:6 [▼
0 => "T-Shirt Fashion"
1 => "green"
2 => 1200.0
3 => "L"
4 => "CdMVwEJcMQbJjMp70UhRnkNQnRmWxzAGiWKxFeWN.png"
5 => 1
]
]
result of dd($arr) with image
I also try this
$json = json_encode(unserialize($orderShow->products));
And i get this result
"{"product_0":["T-Shirt Fashion 3","black",1300,"S","QFh840we7wZBKO790A6wFlipJB1ASaCpt3zJhJl8.png",1],"product_1":["T-Shirt Fashion","green",1200,"L","CdMVwEJcMQbJjMp70UhRnkNQnRmWxzAGiWKxFeWN.png",1]} ◀"
So i dont know how to deal with these arrays on my blade, i know that i need a Foreach loop to display it on the right way, but i have no idea how to proceed.

It can be a good idea to store your $products as an object (with key and value) instead of a pure array.
In your store function, you can try the following :
$products = [];
foreach (Cart::content() as $product) {
// similar to array_push()
$products[] = [
"name" => $product->name,
"color" => $product->options->color,
"price" => $product->price,
"size" => $product->options->size,
"image" => $product->options->image,
"qty" => $product->qty,
];
}
In your show function
public function show($id)
{
$orderShow = Order::find($id);
$products = unserialize($orderShow->products);
return view('dashboard.order.show', compact('orderShow', 'products'));
}
Then, in your blade template, if you need to display $products as a table:
<table>
<thead>
<tr>
<th>name</th>
<th>color</th>
<th>price</th>
<th>size</th>
<th>image</th>
<th>qty</th>
</tr>
</thead>
<tbody>
#foreach($products as $product)
<tr>
<td>{{$product['name']}}</td>
<td>{{$product['color']}}</td>
<td>{{$product['price']}}</td>
<td>{{$product['size']}}</td>
<td>{{$product['image']}}</td>
<td>{{$product['qty']}}</td>
</tr>
#endforeach
</tbody>
</table>
Quick tip, it is a good practice to define attributes (de)serialization in your model instead of your controller.
Have a look at Eloquent Mutator, and update your Order.php model with the following :
class Order extends Model {
// ...
public function setProductsAttribute($products)
{
$this->attributes['products'] = serialize($products);
}
public function getProductsAttribute()
{
return unserialize($this->attributes['products']);
}
// ...
}

Related

How to combine two SQL tables in codeigniter without using SQL queries?

Here is my codes,
//FROM MY CONTROLLER
$companies = $this->Uploads_model->getallcompanies();
$general = $this->Uploads_model->getallcontract();
$this->data['companieslist'] = $companies;
$this->data['uploads'] = $general;
$this->render('contracts/index_view');
// MY VIEW
foreach($companieslist as $company){
$general_c[] = $company->company_id;
$general_c[] = $company->company_name;
}
foreach ( $uploads as $key => $con ) {
?>
<tr>
<td class="center">
<label class="pos-rel">
<input type="checkbox" class="ace"/>
<span class="lbl"></span>
</label>
</td>
<td>
<a href="#">
<?php
if($con->Company_id == $general_c[$company_id]){ // MY QUESTION IS HERE
echo $con->Company_name;
}
?>
</a>
</td>
So, am working on this web app where am supposed to display in table all contract files followed with company owned this contract.
I have two tables in my Database as follow Companies_tbl and contract_tbl.
I have Company_id as a foreign key in contract_tbl.
Create a custom function to filter your contracts based on Company_id
function getContractsForId($contracts,$Company_id) {
return array_filter($contracts,function(){
return $contracts->Company_id === $Company_id;
});
}
template loop:
foreach( getContractsForId($uploads,$Company_id) as $key => $con) {
//...html...
//remove the if
}
You are not building the array of companies the right way.
foreach($companieslist as $company){
$general_c[] = $company->company_id;
$general_c[] = $company->company_name;
}
After you looped once, the $general_c array will look like this:
$general_c = [
0 => 1, //company id
1 => 'Company name'
]
After the second time:
$general_c = [
0 => 1, //company id
1 => 'Company name',
2 => 2, //company id
3 => 'Company name 2'
]
What you want is the following:
foreach($companieslist as $company){
$general_c[$company->company_id] = $company->company_name;
}
And below:
<?php
if($general_c[$con->Company_id]) {
echo $general_c[$con->Company_id];
} ?>
This will let you output the company name based on ID.
But i suggest you do a MySQL join in your model. Add something like this to your Uploads_model:
function getContractsWithCompany() {
$query = $this->db->select('*')
->from('contract_tbl')
->join('Companies_tbl', 'Companies_tbl.id = contract_tbl.Company_id')
->get();
return $query->result();
}
You need first to group files by Company_id then list the specific company files
$companies = $this->Uploads_model->getallcompanies();
$general = $this->Uploads_model->getallcontract();
$this->data['companieslist'] = $companies;
$this->data['uploads'] = array();
//group file list by Company_id
foreach ($general as $key => $file) {
if(!isset($this->data['uploads'][$file->Company_id ]))
$this->data['uploads'][$file->Company_id] = array();
$this->data['uploads'][$file->Company_id][] = $file;
}
// in your view
foreach($companieslist as $company){
$general_c[] = $company->company_id;
$general_c[] = $company->company_name;
if(isset($uploads[$company->company_id])) {
foreach ( $uploads[$company->company_id] as $key => $con ) {
?>
<tr>
<td class="center">
<label class="pos-rel">
<input type="checkbox" class="ace"/>
<span class="lbl"></span>
</label>
</td>
<td>
<?=$company->company_name?>
</td>
</tr>
<!-- and the rest of logic -->
<?php
}
}
}

DataTable with Ajax is not working well after use serverSide: true

I have an user table using DataTables, that will contain more than 200 rows. It's look so fine when I'm using DataTables for default the "pageLength": 10, and this is the table example.
Username | Type | Request |
user01 1 request01
user02 1 request02
user03 2 request03
user04 1 request04
user05 1 request05
user06 1 request06
user07 1 request07
user08 1 request08
user09 1 request09
user10 1 request10
Showing 1 to 10 of 200 entries FirstPrevious123...20NextLast
So, for reducing the loading time, I decide to use "processing": true and "serverSide": true. Then I got some issue with this "serverSide" : true, It's print 200 rows of data in table.
Showing 0 to 0 of 0 entries (filtered from NaN total entries). Then the pagination is still print and after I click the page 2, it's doing nothing.
I wan't the DataTables is getting the 10 data for the first, after pagination 2 is clicked, it will get 10 more and so on.
I'm using CodeIgniter, here is my code :
On my Views + Js :
<select name="task" id="task">
<option value="1">Task 1</option>
<option value="2">Task 2</option>
</select>
<table id="user-request" class="table">
<thead>
<tr>
<th>Username</th>
<th>Type</th>
<th>Request</th>
</tr>
</thead>
</table>
<script>
... on task change ...
... var task = $("#task").val(); ...
$('#user-request').DataTable({
'processing': true,
'serverSide': true,
'ajax': {
'type': 'POST',
'url': base_url+'user/get_user_request',
'data': {"task":task,"csrf_token":$("input[name=csrf_token]").val()}
}
})
</script>
Note : Task is a different group, example like Class 1 or Class 2, Orchard University or Harvard University
On my Controller :
$task = $this->input->post('task', TRUE);
$user_request = $this->model->all_user_request(task);
foreach ($user_request as $ur)
{
$arr = array();
$arr[] = $ur->username;
$arr[] = $ur->type;
$arr[] = $ur->request;
$data[] = $arr;
}
$output = array(
"data" => $data
);
if (COUNT($output) > 0)
{
echo json_encode($output);
}
On my Model :
public function all_user_request($task_id) {
$query = "SELECT * FROM user_request WHERE task_id = ?";
return $this->db->query($query, $task_id)->result();
}
Note : In model is actually using 2 INNER JOIN, I'm just simplifying the select only for asking here. (turning into denormalization table only in here).
I was trying to add draw, recordsTotal, recordsFiltered to $output in my controller just using numeric data. Example
$output = array(
"draw" => 5,
"recordsTotal" => 5,
"recordsFiltered" => 5,
"data" => $data
);
if (COUNT($output) > 0)
{
echo json_encode($output);
}
I was searching for the answer but, and I think the problem is here but I still have no idea where I must get the draw - recordsTotal - recordsFiltered data. I see on another answer from others, they use "draw" => $_POST['draw'], then I tried it, and it's do nothing.
So I'm trying that using numeric data, but the result is still same. I need some help with this. It's still print 200 rows of data in table.
Showing 0 to 0 of 0 entries (filtered from NaN total entries). Then the pagination is still print and after I click the page 2, it's doing nothing.
Datatables send everything you need - if you take a look in your console under network you'll see, that they use the ajax-get method to send those requests to the server
The GET Parameter are as follows
draw
columns
start
length
search
You can find the entire list here
which means - you've to adapt your model properly...
something like that should work
public function all_user_request($task_id)
{
$intStart = intval($this->input->get("start"));
$intLength = intval($this->input->get("length"));
$strSearch = (strlen($this->input->get("search")["value"]) >= 2) ? $this->input->get("search",true)["value"] : false;
$order = $this->input->get("order",true);
$this->setQuery($task_id,$strSearch);
$query = $this->db->get();
$this->recordsTotal = $query->num_rows();
$this->setQuery($task_id, $strSearch);
if ($intStart >= 0 && $intLength > 0)
{
$this->db->limit($intLength,$intStart);
}
$strOrderField = 'username';
$strDirection = "ASC";
if (is_array($order))
{
switch($order[0]['column'])
{
case 1:
$strOrderField = 'type';
break;
case 2:
$strOrderField = 'request';
break;
}
if (!empty($order[0]['dir'])) $strDirection = $order[0]['dir'];
}
$this->db->order_by($strOrderField,$strDirection);
$query = $this->db->get();
$arrData = $query->result();
return $arrData;
}
public function getRecordsTotal()
{
return $this->recordsTotal;
}
private function setQuery($task_id, $strSearch="")
{
$this->db
->select('*')
->from('user_request')
->where('task_id', $task_id);
if (!empty($strSearch))
{
$this->db->like('task_id', $strSearch);
}
}
and your controller
//controller
$task = $this->input->post('task', TRUE);
$user_request = $this->model->all_user_request($task);
$data = [];
foreach ($user_request as $ur)
{
$data[] = [
$ur->username,
$ur->type,
$ur->request
];
}
$arrCompiledData = [
'data' => $data,
'draw' => $this->input->get('draw'),
'recordsTotal' => $this->model->getRecordsTotal(),
'recordsFiltered' => $this->model->getRecordsTotal(),
];
$this->output
->set_content_type('application/json')
->set_output(json_encode($arrCompiledData));
Please keep in mind i just wrote this down - maybe there are some typos, but you should be able to understand how the serverside processing of a datatables request should work.
As long as you chose the server mode, you have to manage everything via the requests.
So, you have to dynamically create the values of the output array :
$output = array(
"draw" => $_POST['draw'],
"recordsTotal" => $this->my_model->get_total_records(),
"recordsFiltered" => $this->my_model->get_total_filtered(),
"data" => $this->my_model->all_user_request($id)
);
and the model functions
public function all_user_request($task_id) {
$query = "SELECT * FROM user_request WHERE task_id = ?"; // add limit $_POST['length'], $_POST['start'] to your request
return $this->db->query($query, $task_id)->result();
}
If you're using serverSide = true, you should provide your own filter count and total count. Also provide your own search function, ordering and etc. Use controller & model below for your reference.
Controller
$task = $this->input->post('task', TRUE);
$user_request = $this->model->all_user_request($task);
$output = array(
'draw' => $this->input->post('draw', TRUE),
'recordsTotal' => $user_request['recordsTotal'],
'recordsFiltered => $user_request['recordsFiltered'],
'data' => empty($user_request['data'])? array() : $user_request['data']
);
echo json_encode($output);
Model
public function all_user_request($task_id) {
$params = $this->input->post(null, TRUE);
$search_fields = array('username','type','request'); //change this into your table fields
$data = array();
$this->db->start_cache();
$this->db->select("username, type, request");
$this->db->from("user_request");
$this->db->where("task_id", $task_id);
if(!empty($params['search']['value'])){
$str = $params['search']['value'];
$this->db->group_start();
foreach($search_fields as $row){
$this->db->or_like($row, $str, 'BOTH');
}
$this->db->group_end();
}
$data['recordsTotal'] = $this->db->count_all_results();
$this->db->stop_cache();
$this->db->limit($params['length'], $params['start']);
$data['recordsFiltered'] = $this->db->count_all_results();
$query = $this->db->get();
$this->db->flush_cache();
foreach($query->result_array() as $row){
$data['data'][] = array_values($row);
}
return $data;
}

Add fields in laravel dynamically and unlimited

I have part of my website where users or admins can add restaurant list (is really like posts, just different naming)
There is some fixed inputs such as (title, description and map) I also need a part where users/admins can add restaurants menu this options is obviously can be different for each restaurant as their menu is a short list or long list.
So what I need is like + button where people can add fields and named their menu items with another field for the price of each item.
So my question is how to achieve this option?
What do I have at the moment?
Restaurant migrate:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRestaurantsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('restaurants', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->unique();
$table->string('slug')->unique();
$table->string('description')->nullable();
$table->string('image')->nullable();
$table->string('menu')->nullable();
$table->string('address')->nullable();
$table->integer('worktimes_id')->unsigned();
$table->integer('workday_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->string('verified')->default(0);
$table->string('status')->default(0);
$table->timestamps();
});
Schema::table('restaurants', function($table) {
$table->foreign('worktimes_id')->references('id')->on('worktimes');
$table->foreign('workday_id')->references('id')->on('workdays');
$table->foreign('user_id')->references('id')->on('users');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('restaurants');
}
}
That's all, I still didn't create CRUD controller for restaurant because I'm holding for this option and your opinions.
Thanks.
UPDATE
STORE METHOD:
public function store(Request $request)
{
//Validating title and body field
$this->validate($request, array(
'title'=>'required|max:225',
'slug' =>'required|max:255',
'image' =>'sometimes|image',
'description' => 'required|max:100000',
'address' => 'sometimes|max:500',
'user_id' => 'required|numeric',
'verified' => 'sometimes',
'status' => 'required|numeric',
));
$restaurant = new Restaurant;
$restaurant->title = $request->input('title');
$restaurant->slug = $request->input('slug');
$restaurant->description = $request->input('description');
$restaurant->address = $request->input('address');
$restaurant->user_id = $request->input('user_id');
$restaurant->verified = $request->input('verified');
$restaurant->status = $request->input('status');
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = 'restaurant' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = public_path('images/');
$request->file('image')->move($location, $filename);
$restaurant->image = $filename;
}
// menu
$newArray = array();
$menuArray = $request->custom_menu; //Contains an array of Menu Values
$priceArray = $request->custom_price; //Contains an array of Price Values
//Creating new array with ARRAY KEY : MENU VALUES and ARRAY VALUE: PRICE VALUES
foreach ($menuArray as $key => $singleMenu) {
$newArray[$singleMenu] = $priceArray[$key];
}
//Output : array("Menu01" => "Price01", "Menu02" => "Price 02", "Menu03" => "Price 04", "Menu04" => "Price 05")
//Converting array to json format to store in your table row 'custom_menu_price'
$jsonFormatData = json_encode($newArray);
//Output like: {"Menu01":"Price01","Menu02":"Price 02","Menu03":"Price 04","Menu04":"Price 05"}
// Save in DB
//
//
//
// To retrieve back from DB to MENU and PRICE values as ARRAY
$CustomArray = json_decode($jsonFormatData, TRUE);
foreach ($CustomArray as $menu => $price) {
echo "Menu:".$menu."<br>";
echo "Price:".$price."<br>";
}
// menu
$restaurant->save();
$restaurant->workdays()->sync($request->workdays, false);
$restaurant->worktimes()->sync($request->worktimes, false);
//Display a successful message upon save
Session::flash('flash_message', 'Restaurant, '. $restaurant->title.' created');
return redirect()->route('restaurants.index');
What you can do is
1) add another one table row for custom_menu_price in your migration file
$table->string('custom_menu_price')->nullable();
2) Modify your form
<form method="POST" action="{{ ...... }}">
{{ csrf_field() }}
//I'm Looping the input fields 5 times here
#for($i=0; $i<5; $i++)
Enter Menu {{ $i }} : <input type="text" name="custom_menu[]"> //**Assign name as ARRAY
Enter Price {{ $i }} : <input type="text" name="custom_price[]"> //**Assign name as ARRAY
<br><br>
#endfor
<input type="submit" name="submit">
</form>
3) In your controller
public function store(Request $request) {
//Validating title and body field
$this->validate($request, array(
'title'=>'required|max:225',
'slug' =>'required|max:255',
'image' =>'sometimes|image',
'description' => 'required|max:100000',
'address' => 'sometimes|max:500',
'user_id' => 'required|numeric',
'verified' => 'sometimes',
'status' => 'required|numeric',
));
$restaurant = new Restaurant;
$restaurant->title = $request->input('title');
$restaurant->slug = $request->input('slug');
$restaurant->description = $request->input('description');
$restaurant->address = $request->input('address');
$restaurant->user_id = $request->input('user_id');
$restaurant->verified = $request->input('verified');
$restaurant->status = $request->input('status');
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = 'restaurant' . '-' . time() . '.' . $image->getClientOriginalExtension();
$location = public_path('images/');
$request->file('image')->move($location, $filename);
$restaurant->image = $filename;
}
// menu
$newArray = array();
$menuArray = $request->custom_menu; //Contains an array of Menu Values
$priceArray = $request->custom_price; //Contains an array of Price Values
//Creating new array with ARRAY KEY : MENU VALUES and ARRAY VALUE: PRICE VALUES
foreach ($menuArray as $key => $singleMenu) {
$newArray[$singleMenu] = $priceArray[$key];
}
//Output : array("Menu01" => "Price01", "Menu02" => "Price 02", "Menu03" => "Price 04", "Menu04" => "Price 05")
//Converting array to json format to store in your table row 'custom_menu_price'
$jsonFormatData = json_encode($newArray);
//Output like: {"Menu01":"Price01","Menu02":"Price 02","Menu03":"Price 04","Menu04":"Price 05"}
// Save in DB
$restaurant->custom_menu_price = $jsonFormatData;
// menu
$restaurant->save();
$restaurant->workdays()->sync($request->workdays, false);
$restaurant->worktimes()->sync($request->worktimes, false);
//Display a successful message upon save
Session::flash('flash_message', 'Restaurant, '. $restaurant->title.' created');
return redirect()->route('restaurants.index');
}
inside your front.restaurantshow view:
#php
// To retrieve back from DB to MENU and PRICE values as ARRAY
$CustomArray = json_decode($restaurant->custom_menu_price, TRUE);
#endphp
#foreach ($CustomArray as $menu => $price)
Menu Name: {{ $menu }} <br>
Menu Price: {{ $price }} <br><br>
#endforeach
Hope it makes sense.

Adding more data in the view using Symfony and Twig templating engine

I am trying to add more data from API to my page. The API has been paginated due to memory concerns. I am using symfony and Twig templating to get a list of articles. The API call has filter of page number. Is there a way I can call this API multiple times in my display function to get the data from other pages.
Here is my code. In the controller I have the following display function
public function display(Application $app)
{
$lang = $app['filterLang'];
$years = [];
$activeYear = $this->getActiveYear($app['request']->get('year'));
$modelManagerFactory = $app['factories.model_manager'];
$articleCmsManager = $modelManagerFactory->create('ArticleManager');
$articles = $articleCmsManager->getList($lang, $activeYear);
$categories = $articleCmsManager->getCategories();
$cmsYears = $articleCmsManager->getCmsYears($lang);
$allYears = array_unique(array_merge($years, $cmsYears));
$oldActiveYear = $activeYear;
if (is_null($app['request']->get('year')) && empty($articles)) {
$activeYear = $oldActiveYear - 1;
$articles = $articleCmsManager->getList($lang, $activeYear);
}
$articleIssues = [];
foreach ($articles as $article) {
if (strpos($article->publicationDate, "$activeYear") !== false) {
$category = [
'en_US' => isset($categories['en_US'][$article->category]) ? $categories['en_US'][$article->category] : ''
];
if ('en_US' != $lang) {
$category[$lang] = isset($categories[$lang][$article->category]) ? $categories[$lang][$article->category] : '';
}
$articleIssues[] = [
'title' => isset($article->content->title) ? $article->content->title : '',
'category' => $category,
'image' => isset($article->image) ? $article->image : '',
'url' => isset($article->content->url) ? $article->content->url : '',
'date' => isset($article->publicationDate) ? $article->publicationDate : '',
'artist' => isset($article->artist) ? $article->artist : '',
'metadescription' => isset($article->content->metadescription) ? $article->content->metadescription : ''
];
}
}
return $app['twig']->render(
'archive/ArchivePage.html',
array(
'issues' => [],
'articles' => $articleIssues,
'years' => $allYears,
'activeYear' => $activeYear
)
);
}
The getList function which is responsible for the getting the data from the API is defined as
public function getList($lang = null, $activeYear = null)
{
// define a fallback language (locale)
$fallbackLang = '';
$filter = [
'filter[sort]=startdate_desc',
'page=0',
'per_page=100',
'filter[status]=published',
'filter[publicationDate]='.urlencode(date("Y-m-d H:i:s")),
'filter[year]='.$activeYear
];
$query = array(
'url' => '/cms/article?'.implode('&', $filter),
'data' => array()
);
$results = $this->repo->getList($query);
$articles = array();
foreach ($results as $article) {
if (!empty($article->displayInArchive)) {
if (isset($article->content->$lang->html) && !empty($article->content->$lang->html)) {
$article->content = $article->content->$lang;
$articles[] = $article;
} elseif (isset($article->content->$fallbackLang->html) && !empty($article->content->$fallbackLang->html)) {
$article->content = $article->content->$fallbackLang;
$articles[] = $article;
}
}
}
return $articles;
}
As you can see the view can only get a total of 100 results i.e all the articles on page 0. Now if I also want to show the articles on page 1,2 and so on the same view i.e archive how do I go about doing that without running into memory constraints.

How to update the value of array in Yii session

I am using "ajaxSubmitButton" to send some values of 3 fields: registrant, product id and quantity to controller (controller name: actionCart). After submitting the button I receive those values in session array what I did successfully. At this point, if I submit same product id but different quantity, I want to update the quantity key with new value. I have done this by php global $_SESSION but can't using Yii session variable.
public function actionCart()
{
if(isset($_POST["Order"])){
$item = $_POST["Order"];
$registration_id = $item["registration_id"];
$this->productId = $item["item"];
$quantity = $item["quantity"];
$quantity = $item["quantity"]=='' ? 1 : $item["quantity"];
$productInfo = Products::model()->findByPk(array('id'=>$this->productId));
$totalPrice = $productInfo->price * $quantity;
$newItem = array("product_id" => $this->productId , "product_name" => $productInfo->name, "quantity" => $quantity,"price" => $productInfo->price,"totalPrice" => $totalPrice);
$session = Yii::app()->session;
$cartArray = $session['cart'];
$searchArrResult = $this->searchSubArray($session['cart'],'product_id',$this->productId);
if (!empty($searchArrResult)) {
/***** this works *****/
foreach ( $_SESSION['cart'] as $key=>$cart ) {
if ( $cart["product_id"] == $this->productId ) {
$_SESSION['cart'][$key]['quantity']=$quantity;
$_SESSION['cart'][$key]['totalPrice']=$totalPrice;
}
}
/***** following commented code does not work *****
*
foreach($session['cart'] as $key=>$cart){
if ($cart["product_id"] == $this->productId){
$session['cart'][$key]['quantity'] == $quantity;
$session['cart'][$key]['totalPrice'] == $totalPrice;
}
}*/
}
else {
$cartArray[] = $newItem;
$session['cart'] = $cartArray;
}
print_r($session['cart']);
//unset(Yii::app()->session['cart']);
}
}
In the above code I marked by commenting where I want to update session values. Please help me someone if it is possible do in yii.
Try this:
$carts = $session['cart'];
foreach($carts as $key=>&$cart){
if ($cart["product_id"] == $this->productId){
$cart['quantity'] == $quantity;
$cart['totalPrice'] == $totalPrice;
}
}
$session['cart'] = $carts;
Yii::app()->session return object of CHttpSession, not reference to $_SESSION.
$carts = $session['cart'] equals operation $carts = $session->get('cart'); (by means magic method __get in CHttpSession) and $session['cart'] = $carts; equals to $session->set('cart', $carts); (by __set)
That's why you can't setting by $session['cart'][$key]['quantity'] = $quantity;
UPDATED full solution (I change logic of saving products - $key = product_id)
public function actionCart()
{
if(isset($_POST["Order"])){
$item = $_POST["Order"];
$registration_id = $item["registration_id"];
$this->productId = $item["item"];
$quantity = empty(intval($item["quantity"])) ? 1 : intval($item["quantity"]);
$productInfo = Products::model()->findByPk(array('id'=>$this->productId));.
if(empty($productInfo))
return false; // or other action
$newItem = array(
"product_id" => $this->productId ,
"product_name" => $productInfo->name,
"quantity" => $quantity,
"price" => $productInfo->price,
"totalPrice" => ($productInfo->price * $quantity)
);
$cartArray = Yii::app()->session['cart'];
$cartArray[$this->productId] = $newItem;
Yii::app()->session['cart'] = $cartArray;
}
}

Categories