Flash message shows twice in a view CakePHP3 - cakephp-3.0

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());
}

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');

cakephp 3.4 shopping cart

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);

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'],
];
}
}

Error in wbranca dynagrid update

Am using wbranca yii2 to create dynamic forms but the update action returns an error of
array_combine(): Both parameters should have an equal number of elements
This is the form for the update
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 10, // the maximum times, an element can be cloned (default 999)
'min' => 1, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $modelsPrItem[0],
'formId' => 'dynamic-form',
'formFields' => [
'po_item_no',
'quantity',
],
]); ?>
<div class="container-items">
<!-- widgetContainer -->
<?php foreach ($modelsPrItem as $i => $modelPrItem): ?>
<div class="item paneld">
<!-- widgetBody -->
<div class="panelf-heading">
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panelf-body">
<?php
// necessary for update action.
if (! $modelPrItem->isNewRecord) {
echo Html::activeHiddenInput($modelPrItem, "[{$i}]PRID");
}
?>
<div class="row">
<div class="col-md-2">
<?= $form->field($modelPrItem, "[{$i}]Quantity")->textInput(['maxlength' => 128]) ?>
</div>
<div class="col-md-2">
<?= $form->field($modelPrItem, "[{$i}]Unit_Price")->textInput(['maxlength' => 128]) ?>
</div>
<div class="col-md-2">
<?= $form->field($modelPrItem, "[{$i}]Extended_price")->textInput(['maxlength' => 128]) ?>
</div>
<div class="col-md-2">
<?= $form->field($modelPrItem, "[{$i}]Currency_ID")->dropDownList(
ArrayHelper::map(Tblcurrency::find()->all(),'CurrencyID','currency_symbol'),[]
); ?>
</div>
<div class="col-md-4">
<?= $form->field($modelPrItem, "[{$i}]Description")->textArea(['maxlength' => 128]) ?>
</div>
</div>
<!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
This is the model:
<?php
namespace app\models;
use Yii;
use yii\helpers\ArrayHelper;
class Model extends \yii\base\Model
{
/**
* Creates and populates a set of models.
*
* #param string $modelClass
* #param array $multipleModels
* #return array
*/
public static function createMultiple($modelClass, $multipleModels = [])
{
$model = new $modelClass;
$formName = $model->formName();
$post = Yii::$app->request->post($formName);
$models = [];
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
$multipleModels = array_combine($keys, $multipleModels);
}
if ($post && is_array($post)) {
foreach ($post as $i => $item) {
if (isset($item['id']) && !empty($item['id']) && isset($multipleModels[$item['id']])) {
$models[] = $multipleModels[$item['id']];
} else {
$models[] = new $modelClass;
}
}
}
unset($model, $formName, $post);
return $models;
}
}
The above returns an error when i run update especially when updating more than one item
The error message say that the number of element in $keys and $values (alias $multipleModels ) are not the same so you are trying to build an associative array witth a wrong pair of key => value elements
Try var_dump (or inspect with xdebug) the content of the $keys and$multipleModels and adapt the code to your real need .
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
var_dump($keys );
var_dump($multipleModels);
$multipleModels = array_combine($keys, $multipleModels);
}