cakephp 3.4 shopping cart - cakephp-3.0

I am using cakephp 3.4 for my project. I am trying to add shoping cart. I got an example of shopping cart for cakephp 2 from the following link:
https://www.startutorial.com/articles/view/build-a-shopping-cart-with-cakephp-and-jquery-part-2
I was trying to add it to my project. I couldn't able to add more than one data to the cart.
Also, when I click the update button from 'shopping cart view', it shows the following error:
Error: Call to a member function saveProduct() on boolean
File my_project_url\src\Controller\CartsController.php
Line: 59
Here is my code:
Product view
<div class="single-but item_add">
<?php echo $this->Form->create('Cart', ['id'=>'add-form', 'url' => ['controller'=>'carts', 'action' => 'add']]); ?>
<?php echo $this->Form->hidden('product_id',array('value'=>$fruit->id))?>
<input type="submit" value="add to cart"/>
<?= $this->Form->end() ?>
Shopping cart view
<?php echo $this->Form->create('Cart',array('url'=>array('controller'=>'carts', 'action'=>'update')));?>
<div class="row">
<div class="col-lg-12">
<table class="table">
<thead>
<tr>
<th>Product Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<?php $total=0;?>
<?php foreach ($products as $product):?>
<tr>
<td><?php echo $product['name'];?></td>
<td>tk. <?php echo $product['price_exact'];?>
</td>
<td><div class="col-xs-3">
<?php echo $this->Form->hidden('product_id.',array('value'=>$product['Product']['id']));?>
<?php echo $this->Form->input('count.',array('type'=>'number', 'label'=>false,
'class'=>'form-control input-sm', 'value'=>$product['count']));?>
</div></td>
<td>tk. <?php echo $product['count']*$product['price_exact']; ?>
</td>
</tr>
<?php $total = $total + ($product['count']*$product['price_exact']);?>
<?php endforeach;?>
<tr class="success">
<td colspan=3></td>
<td>tk. <?php echo $total;?>
</td>
</tr>
</tbody>
</table>
<p class="text-right">
<?php echo $this->Form->submit('Update',array('class'=>'btn btn-warning','div'=>false));?>
<a class="btn btn-success"
onclick="alert('Implement a payment module for buyer to make a payment.');">CheckOut</a>
</p>
</div>
</div>
<?php echo $this->Form->end();?>
CartsController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Core\Configure;
class CartsController extends AppController {
public function beforeFilter(Event $event)
{
// allow all action
$this->Auth->allow();
}
public function add() {
$this->autoRender = false;
if ($this->request->is('post')) {
$this->Carts->addProduct($this->request->data['product_id']);
}
echo $this->Carts->getCount();
$this->redirect(['controller'=>'fruits', 'action' => 'index']);
}
public function view() {
$this->loadModel('Fruits');
$carts = $this->Carts->readProduct();
$products = array();
if (null!=$carts) {
foreach ($carts as $productId => $count) {
$product = $this->Fruits->get($productId);
$product['count'] = $count;
$products[]=$product;
}
}
$this->set(compact('products'));
}
public function update() {
if ($this->request->is('post')) {
if (!empty($this->request->data)) {
$cart = array();
foreach ($this->request->data['count'] as $index=>$count) {
if ($count>0) {
$productId = $this->request->data['id'][$index];
$cart[$productId] = $count;
}
}
$this->Cart->saveProduct($cart);
}
}
$this->redirect(array('action'=>'view'));
}
}
CartsTable.php
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\ORM\TableRegistry;
use Cake\Network\Session;
use Cake\Core\Configure;
class CartsTable extends Table
{
/**
* Initialize method
*
* #param array $config The configuration for the Table.
* #return void
*/
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('carts');
}
/*
* add a product to cart
*/
public function addProduct($productId) {
$allProducts = $this->readProduct();
if (null!=$allProducts) {
if (array_key_exists($productId, $allProducts)) {
$allProducts[$productId]++;
} else {
$allProducts[$productId] = 1;
}
} else {
$allProducts[$productId] = 1;
$this->saveProduct($allProducts);
}
}
/*
* get total count of products
*/
public function getCount() {
$allProducts = $this->readProduct();
if (count($allProducts)<1) {
return 0;
}
$count = 0;
foreach ($allProducts as $product) {
$count=$count+$product;
}
return $count;
}
/*
* save data to session
*/
public function saveProduct($data) {
$session = new Session();
return $session->write('cart',$data);
}
/*
* read cart data from session
*/
public function readProduct() {
$session = new Session();
return $session->read('cart');
}
}

In CakePHP 3 you must call a method from the Table class witch is in plural form, so in this part of your controller:
$this->Cart->saveProduct($cart);
you must use:
$this->Carts->saveProduct($cart);

Related

Yii2 render view displays HTML code as text

I have a problem in rendering a view in Yii2 that has been troubling me for a couple of days.The rendering was working just fine until one morning it decided not to work. The view displays raw HTML code instead of the user interface.
Here is the code for my controller that renders the view
if ($fails == TRUE)
{
Yii::$app->session->setFlash('error', 'The following records failed validation, kindly update and submit');
return $this->render('failedvalidation',['fails' => $fails,]);
} else {
Yii::$app->session->setFlash('success', 'File uploaded successfully,waiting approval');
return $this->redirect(Yii::$app->request->referrer);
}
Below is the code for my view file(failedvalidation.php)
<?php
use yii\helpers\Html;
use yii\bootstrap\Modal;
use yii\helpers\Url;
?>
<div class="bulkpayments-view">
<div class="box box-default">
<div class="table-responsive">
<table class="display nowrap" id="example1">
<thead>
<tr>
<th>Ref No</th>
<th>Full Names</th>
<th>Id No</th>
<th>Credit Account</th>
<th>Amount</th>
<th>Narration</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach($fails as $data) {?>
<tr class="gradeX">
<td><?= $data['BENEFICIARYREFNO'];?></td>
<td><?= $data['BENEFICIARYFULLNAMES'];?></td>
<td><?= $data['IDNO'];?></td>
<td><?= $data['TOACCOUNT'];?></td>
<td><?= $data['AMOUNT'];?></td>
<td><?= $data['NARRATION'];?></td>
<td><?= Html::button('<i class="fa fa-pencil"></i>
Update', ['value' => Url::to(['update-failed-validation', 'id' =>
$data['ID'],'transid' => $data['TRANSACTIONID']]), 'class' => 'button btn
btn-primary btn-xs']) ?></td>
</tr>
<?php }?>
</tbody>
</table>
</div>
</div>
</div>
<?php
Modal::begin([
'header' => '<h4>Update Record</h4>',
'id' => 'modal',
'size' => 'modal-lg',
'clientOptions' => ['backdrop' => 'static', 'keyboard' => false],
]);
echo '<div id="content"></div>';
Modal::end();
?>
<?php
$js = <<<JS
$('.button').click(function() {
if($('#modal').data('shown.bs.modal')) {
$('#modal').find('#content')
.html('<i class="fa fa-spinner fa-pulse fa-2x"></i>')
.load($(this).attr('value'));
}
else {
$('#modal').modal('show')
.find('#content')
.html('<i class="fa fa-spinner fa-pulse fa-2x"></i>')
.load($(this).attr('value'));
}
});
JS;
$this->registerJs($js);
?>
<?php
$script = <<< JS
$(function () {
$('#example1').DataTable( {
dom: 'Bfrtip',
buttons: [
{
//extend: 'excel',
exportOptions: {
orthogonal: 'sort'
}
}
],
columnDefs: [{
targets:[0,1,2],
render: function(data, type, row, meta){
if(type === 'sort'){
//data = ' ' + data ;
return "\u200C" + data ;
}
return data ;
}
}]
} );
});
JS;
$this->registerJs($script);
?>
<style>
.box{
padding:30px;
}
</style>
Screenshot of my view on browser and the raw HTML it displays:
Hi I had a similar situation and struggled for a few days. Finally I found that in one of my functions had this statement
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
So I had disabled this statement. It worked but I need to find a better solution. Hope this help

how to insert data in database using cakephp

i have a table name stores and i have controller name is StoresController.php and model name is Stores.php and have a add.ctp file inside Stores folder but i an unable to insert data from form.here is my add.ctp file
<div class="row form-main">
<div class="panel panel-default">
<div class="panel-body">
<?php echo $this->Form->create('Store', array('class'=>"contact-
form"));
?>
<div class="form-group">
<div class="col-sm-6">
<?php
echo $this->Form->input('name',array('required'=>false,'class'=>"form-
control", 'placeholder'=>"Enter Name","label"=>false));
?>
</div>
<div class="col-sm-6">
<?php
echo $this->Form-
>input('address1',array('required'=>false,'class'=>"form-control",
'placeholder'=>"Enter Address1","label"=>false));
?>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" name="submit" value="Submit" class="btn
btn-success">
<button type="submit" class="btn btn-info">Cancel</button>
</div>
</div>
<?php echo $this->Form->end(); ?>
here is my StoresController.php
<?php
App::uses('AppController', 'Controller');
class StoresController extends AppController {
var $uses = array();
var $component = array("Common");
public $paginate = array();
public function add(){
$this->layout = 'user_layout';
$user_id = $this->UserAuth->getUserId();
$owner_id = $this->Common->getOwnerId($user_id);
if ($this->request->is('post')) {
$this->Store->create();
if ($this->Store->save($this->request->data)) {
$this->Flash->success(__('User has been Added'));
return $this->redirect(array('action' => 'add'));
} $this->Flash->error(__('Unable to add your post.'));
}
}
}
?>
and i am getting error Call to a member function create() on a non-object in controller
you should be using:
$this->Form->create('Store');
public function add(){
$this->layout = 'user_layout';
$user_id = $this->UserAuth->getUserId();
$owner_id = $this->Common->getOwnerId($user_id);
if ($this->request->is('post')) {
$this->Store->create('Store');
if ($this->Store->save($this->request->data)) {
$this->Flash->success(__('User has been Added'));
return $this->redirect(array('action' => 'add'));
} $this->Flash->error(__('Unable to add your post.'));
}
}
Yes, I solved the problem. There was a minor problem. I forgot the following line in the controller:
var $uses = array('Store');

value not set in my model on selection of combo box Yii2

I have created custom model for my report.Here i have declared two variables fy_yr and fy_qtr.In my report form ,i have two combo boxes and I have to generate my report according to values from my combo boxes.But my problem is the selected values from combos are not set in my custom model.What is the problem?
My report view code:
<?php $form = ActiveForm::begin(['id' => 'member-report',
'action' => ['member-report'],
'method' => 'post',
]); ?>
<table border="1" class="table-bordered">
<tr>
<td style="margin-right:20px;">
<?= $form->field($model, 'fy_yr')->dropDownList(
ArrayHelper::map(FiscalYear::getAllFiscalYr(),'fy_id','fiscal_yr'),
['prompt'=>'Select Fiscal Year.']
)
?>
</td>
<td>
<?= $form->field($model, 'fy_qtr')->dropDownList(
ArrayHelper::map(CodeValue::getFiscalYrQuater(),'cv_id','cv_lbl'),
['prompt'=>'Select Quarter.']
)
?>
</td>
<td><input type="submit" value="Search" class="btn btn-primary btn-block btn-flat"/></td>
<td><input type="submit" value="Print" class="btn btn-primary btn-block btn-flatb"/></td>
</tr>
</table>
<?php ActiveForm::end(); ?>
My model is:
class SfclReport extends Model
{
public $fy_yr;
public $fy_qtr;
public function rules()
{
return [
[['fy_id', 'fy_qtr'], 'required'],
];
}
}
and my controller is
public function actionMemberReport()
{
$model = new SfclReport;
if ($model->load(Yii::$app->request->post())) {
}
return $this->render('member_report',['model'=>$model]);
}
add fy_yr and Specify your variable datatype
class SfclReport extends Model
{
public $fy_yr;
public $fy_qtr;
public function rules()
{
return [
[['fy_id', 'fy_qtr'], 'required'],
[['fy_id',], 'integer'],
[['fy_yr','fy_qtr'], 'string'],
];
}
}

Flash message shows twice in a view CakePHP3

I've encountered this issue several times and tried to avoid it by removing calling Flash method. Lately, I want to show an error flash to non-logged in user who tries to log out. However, when I test this action(by accessing localhost:8765/users/logout without being logged in), everything works fine except I get 2 error messages "You are not authorized to access this location". How can I fix this issue?
Here are my codes
In AppController:
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'], //For User authorize checking, this tells app to let each controller decides own rules for authorize
'loginRedirect' => ['controller' => 'Articles', 'action' => 'index'],
'logoutRedirect' => ['controller' => 'Users', 'action' => 'index']
]);
}
public function beforeFilter(Event $event)
{
//this applied to every controller
$this->Auth->allow(['index', 'view', 'display']);
}
...
public function isAuthorized($user)
{
//Admin can access every action
if(isset($user['role']) && $user['role'] === 'admin'){
return true;
}
//Default deny
return false;
}
In UsersController:
public function isAuthorized($user)
{
//All registered users can add articles
if($this->request->action === 'add'){
return true;
}
//The self user can edit and delete the account
if(in_array($this->request->action, ['edit', 'delete'])){
//get id of targeted user
$targetUserId = (int)$this->request->params['pass'][0];
//check if current user is the targeted user
if($this->Users->selfUser($targetUserId, $user['id'])){
return true;
}else{
$this->Flash->error(__('You are not authorized for this action'));
}
}
return parent::isAuthorized($user);
}
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['add']);
}
...
public function logout()
{
return $this->redirect($this->Auth->logout());
}
In UsersTable
public function selfUser($targetedUserId, $userId)
{
return $targetedUserId == $userId;
}
In default.ctp
$cakeDescription = 'CakePHP: the rapid development php framework';
?>
<!DOCTYPE html>
<html>
<head>
<?= $this->Html->charset() ?>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
<?= $cakeDescription ?>:
<?= $this->fetch('title') ?>
</title>
<?= $this->Html->meta('icon') ?>
<?= $this->Html->css('base.css') ?>
<?= $this->Html->css('cake.css') ?>
<?= $this->fetch('meta') ?>
<?= $this->fetch('css') ?>
<?= $this->fetch('script') ?>
</head>
<body>
<nav class="top-bar expanded" data-topbar role="navigation">
<ul class="title-area large-3 medium-4 columns">
<li class="name">
<h1><?= $this->fetch('title') ?></h1>
</li>
</ul>
<div class="top-bar-section">
<ul class="right">
<li><a target="_blank" href="http://book.cakephp.org/3.0/">Documentation</a></li>
<li><a target="_blank" href="http://api.cakephp.org/3.0/">API</a></li>
</ul>
</div>
</nav>
<?= $this->Flash->render() ?>
<div class="container clearfix">
<?= $this->fetch('content') ?>
</div>
<footer>
</footer>
</body>
</html>
In login.ctp
<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your username and password') ?></legend>
<?= $this->Form->input('username') ?>
<?= $this->Form->input('password') ?>
</fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
Could you also post even just an excerpt from your CTP file? It could be possible that within the page layout the Flash was rendered twice.
You must add this line in your logout action:
$this->autoRender = false;
So, in your case, your UsersController should be:
public function isAuthorized($user)
{
//All registered users can add articles
if($this->request->action === 'add'){
return true;
}
//The self user can edit and delete the account
if(in_array($this->request->action, ['edit', 'delete'])){
//get id of targeted user
$targetUserId = (int)$this->request->params['pass'][0];
//check if current user is the targeted user
if($this->Users->selfUser($targetUserId, $user['id'])){
return true;
}else{
$this->Flash->error(__('You are not authorized for this action'));
}
}
return parent::isAuthorized($user);
}
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['add']);
}
...
public function logout()
{
$this->autoRender = false;
return $this->redirect($this->Auth->logout());
}

Update Link name in Codeigniter from Database

I am new to codeigniter & my company gave me a following task
there is one table in that thr is one column status & in status there are two option 1 is Active & 2nd is Deactive.
if current status is Active & if we click on that \active link it wil turn to deactive.
remember link value is fetched from database so, if link value is Active itr means in database status field value is Active & when we click on Active it will turn to Deactive and in database the value of status nmust be changed to Deactive from Active.
Main_view.php (view)
<html>
<head>
<script type="text/javascript">
oldTextAry = new Array();
function changeText (fieldObj, newTexStr) {
if (newTexStr == fieldObj.innerHTML) {
fieldObj.innerHTML = oldTextAry[fieldObj.id];
} else {
oldTextAry[fieldObj.id] = fieldObj.innerHTML;
fieldObj.innerHTML = newTexStr;
}
}
</script>
</head>
<body>
<form action="<?php echo base_url();?>index.php/main_control/add" method="post">
<table align="center" border=2>
<tr>
<!--<th>ID</th>-->
<!--<th>Category</th>-->
<th>Name</th>
<th>Description</th>
<th>Status</th>
</tr>
<?php
if (isset($result) && !empty($result))
{
//print_r($result);exit;
foreach ($result as $row)
{
?> <tr>
<?php /*?><td><?php echo $row->category; ?></td><?php */?>
<td><?php echo $row['name']; ?></td>
<td><?php echo $row['description']; ?></td>
<td><a href="#" onClick="changeText(this,'deactivate');" id="text1link">active</td>
</tr>
<?php
} }?>
<tr><td align="center" colspan="4"><input type="submit" value="Add New Sub Category" /> </td></tr>
</table>
</form>
</body>
</html>
main_category.php (model)
<?php
class main_category extends CI_Model
{
public function getCategory(){
$this->db->select("*");
$this->db->from('main_category');
$this->db->where('m_id','0');
$query = $this->db->get();
if ($query->num_rows > 0)
{
return $query->result();
}
else
{
return false;
}
}
public function category()
{
$x=0;
$this->db->select("*");
$this->db->from('main_category');
$this->db->where('m_id','0');
$query = $this->db->get();
if ($query->num_rows > 0)
{
$data = $query->result();
foreach($data as $value){
$valueofmain = $value->id;
$arr[$x]['id'] = $valueofmain;
$arr[$x]['name'] = $value->name;
$arr[$x]['description'] = $value->description;
$arr[$x]['status'] = $value->status;
$this->db->select("*");
$this->db->from('main_category');
$this->db->where('m_id',$valueofmain);
$query1 = $this->db->get();
if ($query1->num_rows > 0)
{
$x++;
$data1 = $query1->result();
foreach($data1 as $value1){
$arr[$x]['id'] = $value1->id;
$arr[$x]['name'] = "-".$value1->name;
$arr[$x]['description'] = $value1->description;
$arr[$x]['status'] = $value1->status;
}
}
$x++;
}
//print_r($arr);exit;
}
else
{
return false;
}
return $arr;
}
public function update_status()
{
$data = array( 'status' =>$this->input->post('stat') );
// $this->db->where('status', $this->input->post->('stat'));
$this->db->update('main_category', $data);
}
public function insert_into_db()
{
$data = array(
'm_id'=>$this->input->post('catsel'),
'name' => $this->input->post('title'),
'description' => $this->input->post('desc'),
'status' => $this->input->post('status'));
return $this->db->insert('main_category', $data);
}
/* public function insertcategory()
{
$data1 = array('m_id'=>$this->input->post();)
}*/
}
?>
main_control.php (control)
?php
class Main_control extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->model('main_category');
}
function index()
{
$res = $this->main_category->category();
$data = array('result'=>$res);
$this->load->view('Main_view', $data);
}
function add()
{
$res = $this->main_category->getCategory();
$data = array('result'=>$res);
$this->load->view('addcate',$data);
}
function update_status()
{
if($stat='active' || $stat='Deactive')
{
$this->main_category->update_status();
//redirect('main_control','refresh');
}
}
function insert_to_db()
{
/*if($catsel=="0 Root")
{
}*/
$this->main_category->insert_into_db();
//this->load->view('Main_view');//, $data);
redirect('main_control','refresh');
}
function addmaincategory()
{
$this->load->view('addcmaincate');
}
public function getCategory($id)
{
$categories = array();
while($id != 0)
{
$this->db->from('main_categories'); //$this->table is a field with the table of categoris
$this->db->where('id', $id);
$this->db->limit(1);
$result = $this->db->get()->row(); //fetching the result
$categories[] = $result;
$id = $result->m_id;
}
return $categories;
}
}
?>
addcate.php(view)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<form action="<?php echo base_url();?>index.php/main_control/insert_to_db" method="post">
<h2 align="center">Category Form</h2>
<table align="center" border="2">
<tr><td>Category</td>
<td>Title</td>
<td>Desc</td>
<td>Status</td>
<tr>
<td>
<select name="catsel">
<option selected="selected">--Select Category--</option>
<option value="0">Root</option>
<?php
if (isset($result) && !empty($result))
{
foreach ($result as $row)
{
?>
<option value="<?php echo $row->id; ?>"><?php echo $row->name; ?></option>
<?php
} }?>
</select>
</td>
<td><input type="text" name="title" value="-"/></td>
<td><input type="text" name="desc" /></td>
<td><input type="radio" name="status" value="active"/>active<input type="radio" name="status" value="deactive"/>dective</tr>
<tr><td align="center" colspan="4"><input type="submit" Name="save" value="SAVE"/></td> </tr>
</table>
</body>
</html>