Cakephp3 pass (custom) validation to flash message - validation

It is simple to pass a message to flash via:
$this->Flash->error(__('The user could not be saved. Please, try again.'));
But when there are more errors from:
$package->errors();
I use just a simple foreach loop:
foreach ($package->errors() as $error=>$value)
{
foreach ($value as $single_error)
{
$error_array[] = ($single_error);
}
}
Then I pass it to a flash element:
$this->Flash->custom($error_array, [
'key' => 'custom']);
And in the flash message:
if ($message > 0) {
foreach ($message as $m) {
echo h($m).'<br />';
}
} else {
echo h($message);
}
I wonder it here is a better way of handling an array of validation errors.

I am using the following method if there are errors:
Controller:
$errors = $action->errors();
$errorMessages = [];
array_walk_recursive($errors, function($a) use (&$errorMessages) { $errorMessages[] = $a; });
$this->Flash->error(__('Your action cannot be saved!'), ['params' => ['errors' => $errorMessages]]);
Template/Element/Flash/error.tcp:
<?php if (isset($params) AND isset($params['errors'])) : ?>
<ul class="collection with-header">
<li class="collection-header"><h5><?= __('The following errors occurred:') ?></h5></li>
<?php foreach ($params['errors'] as $error) : ?>
<li class="collection-item"><i class="material-icons">error</i><?= h($error) ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
Result:
Just for anyone interested, I am using MaterializeCSS.

Related

Codeigniter after insert success message show in view

I am new in Codeigniter and I need to show success and error message after insert data's in database.
How can I show the message in the view page?
This is my coding:
Model
function addnewproducts($data)
{
if($data['product_name']!="" && $data['product_qty']!="" && $data['product_price']!="" && $data['date']!="")
{
$res=$this->db->insert('product_list',$data);
return $this->db->insert_id();
}
else
{
return false;
}
}
Controller
function addnewproduct()
{
$this->load->model('products');
$data['product_name'] = trim(strip_tags(addslashes($this->input->post('product_name'))));
$data['product_qty'] = trim(strip_tags(addslashes($this->input->post('product_qty'))));
$data['product_price'] = trim(strip_tags(addslashes($this->input->post('product_price'))));
$data['datetime']=date('d-m-Y');
$res = $this->products->addnewproducts($data);
if($res==true)
{
$data['success'] = 'Successful';
$this->load->view('addproduct',$data);
}
}
View
<p><?php echo $success; ?></p>
There are many ways but below is which i recommend:
Set temp session in controller on success or error:
$res = $this->products->addnewproducts($data);
if($res==true)
{
$this->session->set_flashdata('success', "SUCCESS_MESSAGE_HERE");
}else{
$this->session->set_flashdata('error', "ERROR_MESSAGE_HERE");
}
In View you can display flashdata as below:
echo $this->session->flashdata('success');
or
echo $this->session->flashdata('error');
Source : Codeigniter official website https://codeigniter.com/userguide3/libraries/sessions.html
I appreciate that you got your answer but I think flash data is bit old now, as we can use bootstrap to alert if any error and that looks good to on web page.
In controller
$res = $this->products->addnewproducts($data);
if($res==true)
{
$this->session->set_flashdata('true', 'write_the_message_you_want');
}
else
{
$this->session->set_flashdata('err', "write_the_message_you_want");
}
In View
<?php
if($this->session->flashdata('true')){
?>
<div class="alert alert-success">
<?php echo $this->session->flashdata('true'); ?>
<?php
} else if($this->session->flashdata('err')){
?>
<div class = "alert alert-success">
<?php echo $this->session->flashdata('err'); ?>
</div>
<?php } ?>
Controller:
function addnewproduct()
{
$this->load->model('products');
$data['product_name'] = trim(strip_tags(addslashes($this->input->post('product_name'))));
$data['product_qty'] = trim(strip_tags(addslashes($this->input->post('product_qty'))));
$data['product_price'] = trim(strip_tags(addslashes($this->input->post('product_price'))));
$data['datetime']=date('d-m-Y');
if($this->products->addnewproducts($data));
{
$this->session->set_flashdata('Successfully','Product is Successfully Inserted');
}
else
{
$this->session->set_flashdata('Successfully','Failed To
inserted Product');
}
// redirect page were u want to show this massage.
redirect('Controller/Fucntion_name','refresh');
}// close function
view :
On Redirect Page write This code top of Form
<?php if($responce = $this->session->flashdata('Successfully')): ?>
<div class="box-header">
<div class="col-lg-6">
<div class="alert alert-success"><?php echo $responce;?></div>
</div>
</div>
<?php endif;?>

How to make sure that foreach loop data shows in correct set position views

I have a controller that shows modules for my each position
Array
(
[0] => Array
(
[layout_module_id] => 1
[layout_id] => 1
[module_id] => 1
[position] => column_left
[sort_order] => 1
)
[1] => Array
(
[layout_module_id] => 2
[layout_id] => 1
[module_id] => 2
[position] => column_left
[sort_order] => 2
)
)
Above currently I have only two modules set and the are in the position of column left.
Because the position views are out side of the foreach loop they are picking up that module even though not set for that position? As shown in image.
Question: How can I make sure that the module will only display in its set position view.
public function index() {
$layout_id = $this->getlayoutID($this->router->class);
$modules = $this->getlayoutsmodule($layout_id);
echo '<pre>';
print_r($modules);
echo "</pre>";
$data['modules'] = array();
foreach ($modules as $module) {
$this->load->library('module/question_help');
$data['modules'][] = $this->load->view('module/question_help', $this->question_help->set(), TRUE);
}
// Position Views
$data['column_left'] = $this->load->view('column_left', $data, TRUE);
$data['column_right'] = $this->load->view('column_right', $data, TRUE);
$data['content_top'] = $this->load->view('content_top', $data, TRUE);
$data['content_bottom'] = $this->load->view('content_bottom', $data, TRUE);
// Main view
$this->load->view('welcome_message', $data);
}
public function getlayoutsmodule($layout_id) {
$this->db->select('*');
$this->db->from('layouts_module');
$this->db->where('layout_id', $layout_id);
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result_array();
}
}
Each of the position views have the same foreach loop
<?php if ($modules) { ?>
<?php foreach ($modules as $module) { ?>
<?php echo $module;?>
<?php } ?>
<?php }?>
main view
<div class="container">
<div class="row">
<?php echo $column_left; ?>
<?php if ($column_left && $column_right) { ?>
<?php $class = 'col-sm-6'; ?>
<?php } elseif ($column_left || $column_right) { ?>
<?php $class = 'col-sm-9'; ?>
<?php } else { ?>
<?php $class = 'col-sm-12'; ?>
<?php } ?>
<div id="content" class="<?php echo $class; ?>">
<?php echo $content_top; ?>
<h1>Welcome to CodeIgniter!</h1>
<div id="body">
<p>The page you are looking at is being generated dynamically by CodeIgniter.</p>
<p>If you would like to edit this page you'll find it located at:</p>
<code>application/views/welcome_message.php</code>
<p>The corresponding controller for this page is found at:</p>
<code>application/controllers/Welcome.php</code>
<p>If you are exploring CodeIgniter for the very first time, you should start by reading the User Guide.</p>
</div>
<p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds. <?php echo (ENVIRONMENT === 'development') ? 'CodeIgniter Version <strong>' . CI_VERSION . '</strong>' : '' ?></p>
<?php echo $content_bottom; ?>
</div>
<?php echo $column_right; ?></div>
</div>
I would do it like this (not sure if the library needs to be loaded in each iteration but leaving it there):
$tmpdata = array();
foreach ($modules as $module) {
$this->load->library('module/question_help');
$tmpdata[$module['position']]['modules'][] = $this->load->view('module/question_help', $this->question_help->set(), TRUE);
}
$data = array();
foreach ($tmpdata as $pos => $mods) {
$data[$pos] = $this->load->view($pos, $tmpdata[$pos], TRUE);
}
$this->load->view('welcome_message', $data);
Passing $tmpdata[$pos] to each position's view makes the array called $modules available, so in the views, just use
if ($modules) {
foreach ($modules as $module) {
echo $module;
}
}
as before.
This keeps it dynamic and you don't have to modify this code if you change or add positions. I'm using two data arrays just to avoid passing unnecessary data.

Yii2 Session, Flash messages

I have a problem with setting flash messages.
So, i have an action which in some cases should redirect with flash. It looks like this:
if(!$this->_isSameOrg($reports)){
\Yii::$app->session->setFlash('consol_v_error',\Yii::t('app/consol', 'some_text'));
$this->redirect(\Yii::$app->request->getReferrer());
return;
}
After redirect in view i have this
<div class="col-lg-12">
<?php if(Yii::$app->session->hasFlash('consol_v_error')): ?>
<div class="alert alert-danger" role="alert">
<?= Yii::$app->session->getFlash('consol_v_error') ?>
</div>
<?php endif; ?>
</div>
The problem is i don't see any message here. In Debug panel i see SESSION var populated with good flash, but it doesn't display with this if-statement.
Maybe i need to configure session component or something?...
To set flash,try like
\Yii::$app->getSession()->setFlash('error', 'Your Text Here..');
return $this->redirect('Your Action');
And to display it..
<?= Yii::$app->session->getFlash('error'); ?>
you can try like this
<?php
foreach (Yii::$app->session->getAllFlashes() as $key => $message) {
echo '<div class="alert alert-' . $key . '">' . $message . '</div>';
}
?>
Simply do:
Add two strings to: /views/layout/main.php
in block use:
use frontend\widgets\Alert;
before <?= $content ?>:
<?= Alert::widget() ?>
Now all messages automatically will be on screen. Lets try it! Add in any controller's method:
Yii::$app->session->setFlash('warning', 'bla bla bla bla 1');
Yii::$app->session->setFlash('success', 'bla bla 2');
Yii::$app->session->setFlash('error', 'bla bla 3');
Instead of this:
$this->redirect(\Yii::$app->request->getReferrer());
return;
try this:
return $this->redirect(\Yii::$app->request->getReferrer());
It's working fine for me.
in yii2 flash can be set like this
Yii::$app->session->setFlash('success', 'Thank you ');
Here is my solution:
overwrite standart Session class:
namespace app\components;
use Yii;
class Session extends \yii\web\Session {
public function getAllFlashesNormalized() {
$flashes = [];
foreach (Yii::$app->session->getAllFlashes() as $key => $flash) {
if (is_array($flash))
foreach ($flash AS $message)
$flashes[] = ['key' => $key, 'message' => $message];
else
$flashes[] = ['key' => $key, 'message' => $flash];
}
return $flashes;
}
}
So you can:
Yii::$app->session->addFlash('success', 'Text.');
Yii::$app->session->addFlash('success', 'Another text.');
And output this messages:
<?php foreach (Yii::$app->session->getAllFlashesNormalized() as $flash) { ?>
<div class="alert alert-<?=$flash['key']?>" role="alert"><?=$flash['message']?></div>
<?php } ?>
in my case flash message deleted after redirect, when i use hasFlash before redirect.
if (!Yii::$app->getSession()->hasFlash('success')) {
Yii::$app->getSession()->setFlash('success', Yii::t('app', 'your text'));
}
So i added this and it helped
if (!Yii::$app->getSession()->hasFlash('success')) {
Yii::$app->getSession()->setFlash('success', Yii::t('app', 'your text'));
} else {
Yii::$app->getSession()->set('__flash', array('success' => -1));
}
Did not work for me.
I'd rather use:
In the controler:
$session = new Session;
$session->addFlash("warning","Your text here");
In the view :
<?php
$session = new Session;
foreach ($session->getAllFlashesNormalized() as $flash) {
?>
<div class="alert alert-<?=$flash['key']?>" role="alert">
<?=$flash['message']?>
</div>
<?php
}
?>

Codeigniter nested foreach in slideshow?

I ask this https://stackoverflow.com/a/14277726/1670630 on other post but my problem still exist.
In codeigniter 2.1 I'm trying to display channels by category. So if i have a category called Film, i should see a list of Channels within Film. I tried a nested foreach loop to accomplish this but can't seem to get it to work in the slidshow and limit by number of row.
My model:
<?php
class Pages_model extends CI_Model {
function get_channels_by_categ_tv()
{
$this->db->select('categories.category_name, channels.channel_name');
$this->db->from('type_categ');
$this->db->join('categories', 'categories.category_id = type_categ.category_id');
$this->db->join('channels', 'channels.channel_id = type_categ.channel_id');
$this->db->order_by('categories.category_id');
//$this->db->group_by(array('categories.category_id'));
$query = $this->db->get();
if($query->num_rows() == 0)
{
#no channels
return false;
}
return $query->result_array();
}
}
I have this in the view:
<ul class="slides">
<li>
<?php $cat_shown = ''; ?>
<div class="programe-tv_link">
<?php $cat_show = ''; $cnl_show = '';?>
<?php foreach ($category_chaneels as $category): ?>
<?php
if ($cat_show != $category['category_name']) {
$cat_show = $category['category_name'];
echo '<p>' . $cat_show . '</p>';
}
$cnl_show = $category['channel_name'];
echo '<dd> >>' . $cnl_show . '</dd> ';
?>
<?php endforeach; ?>
</div>
</li>
<li>
<div class="programe-tv_link">
<p>Arte</p>
<dd> >> Acasa</dd>
<dd> >> Antena 1</dd>
<dd> >> Pro TV</dd>
</div>
<div class="programe-tv_link">
<p>Music Box</p>
<dd> >> Acasa</dd>
<dd> >> Antena 1</dd>
<dd> >> Pro TV</dd>
<dd> >> TLC</dd>
</div>
</li>
</ul>
I atache image with ilustration,
sorry for my english and if you don't understund me please write here. THX in advance.
My finale code is this.
<div id="programe-tv-slide" class="flexslider">
<strong>Programe TV</strong>
<div class="redLine"></div>
<?php $cat_cnl = array();
$list = array();
$i=1;
foreach ($category_chaneels as $option) {
$catname = $option['category_name'];
$chlname = $option['channel_name'];
$cat_cnl[$catname][$i] = $chlname;
$list[$i] = $catname;
$i++;
};
?>
<?php
$rows = array_chunk($cat_cnl, 4, TRUE);
foreach ($rows as $row) { //var_dump($rows);
?>
<ul class="slides">
<?php
echo ('<li>');
foreach ($row as $category => $channels) {
echo '<div class="programe-tv_link">';
echo '<p>' . $category . '</p>';
foreach ($channels as $channel) {
echo '<dd>' . $channel . '</dd> ';
};
echo '</div>';
};
echo ('</li>');
?>
</ul>
<?php }; ?>
</div>

Opencart how to display only 5 subcategory in a column

I'm new to opencart. I'm using category module to display category in left sidebar. I'm trying to add subcategory limit (say 5 in a column) same like ebay.in left categories.
My .../module/category.php file is
<?php class ControllerModuleCategory extends Controller {
protected function index($setting) {
$this->language->load('module/category');
$this->data['heading_title'] = $this->language->get('heading_title');
if (isset($this->request->get['path'])) {
$parts = explode('_', (string)$this->request->get['path']);
} else {
$parts = array();
}
if (isset($parts[0])) {
$this->data['category_id'] = $parts[0];
} else {
$this->data['category_id'] = 0;
}
if (isset($parts[1])) {
$this->data['child_id'] = $parts[1];
} else {
$this->data['child_id'] = 0;
}
if (isset($parts[2])) {
$this->data['sisters_id'] = $parts[2];
} else {
$this->data['sisters_id'] = 0;
}
$this->load->model('catalog/category');
$this->load->model('catalog/product');
$this->data['categories'] = array();
$categories = $this->model_catalog_category->getCategories(0);
foreach ($categories as $category) {
$children_data = array();
$children = $this->model_catalog_category->getCategories($category['category_id']);
foreach ($children as $child) {
$sister_data = array();
$sisters = $this->model_catalog_category->getCategories($child['category_id']);
if(count($sisters) > 1) {
foreach ($sisters as $sisterMember) {
$sister_data[] = array(
'category_id' =>$sisterMember['category_id'],
'name' => $sisterMember['name'],
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id']. '_' . $sisterMember['category_id'])
);
}
$children_data[] = array(
'category_id' => $child['category_id'],
'sister_id' => $sister_data,
'name' => $child['name'],
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
);
}else{
$children_data[] = array(
'category_id' => $child['category_id'],
'sister_id' =>'',
'name' => $child['name'],
'href' => $this->url->link('product/category', 'path=' . $category['category_id'] . '_' . $child['category_id'])
);
}
}
$data = array(
'filter_category_id' => $category['category_id'],
'filter_sub_category' => true
);
$product_total = $this->model_catalog_product->getTotalProducts($data);
$this->load->model('tool/image');
$this->data['categories'][] = array(
'category_id' => $category['category_id'],
'name' => $category['name'],
'children' => $children_data,
'sister' => $sister_data,
'category_image' => $this->model_tool_image->resize($category['image'], 20, 20),
'href' => $this->url->link('product/category', 'path=' . $category['category_id'])
);
}
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/category.tpl')) {
$this->template = $this->config->get('config_template') . '/template/module/category.tpl';
} else {
$this->template = 'default/template/module/category.tpl';
}
$this->render();
}}?>
And my ...module/category.tpl file is
<div id="menu_box">
<div class="box-heading"><?php echo $heading_title; ?></div>
<ul>
<?php foreach ($categories as $category) { ?>
<li>
<?php if ($category['category_id'] == $category_id) { ?>
<?php echo $category['name']; ?>
<?php } else { ?>
<?php echo $category['name']; ?>
<span style="float:right; font-weight:bold;">ยป</span>
<a class="menuimg" ><img src="<?php echo $category['category_image']; ?> " /></a>
<?php } ?>
<?php if ($category['children']) { ?>
<ul class="second-level" style="position: absolute;left: 166px;top:-2px;padding: 5px;margin: 0px;width:350px; background-color: whitesmoke; border:1px solid#ececec; z-index:10;">
<?php foreach ($category['children'] as $child) { ?>
<li id="second-li">
<?php if ($child['category_id'] == $child_id) { ?>
<a style="border-bottom:1px solid #5d5d5d;" href="<?php echo $child['href']; ?>" class="active"> <?php echo $child['name']; ?></a>
<?php } else { ?>
<a style="border-bottom:1px solid #5d5d5d;" href="<?php echo $child['href']; ?>"> <?php echo $child['name']; ?></a>
<?php } ?>
<?php if($child['sister_id']){ ?>
<ul>
<?php foreach($child['sister_id'] as $sisters) { ?>
<li>
<?php if ($sisters['category_id'] == $sisters_id) { ?>
<?php echo $sisters['name']; ?>
<?php } else { ?>
<?php echo $sisters['name']; ?>
<?php } ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</li>
<?php } ?>
</ul>
</div>
Any suggestion to do this is much appreciated.
For main category
Ugly/Quick fix
You can add this line
$categories = array_slice($categories, 0, 5);
just below
$categories = $this->model_catalog_category->getCategories(0);
in catalog/controller/module/category.php
Better Solution
In catalog/model/catalog/category.php replicate the function getCategories($parent_id = 0) and add a second parameter limit to it. Use this parameter inside the query to limit the results returned
To limit the results in children/sub-category
Ugly-Fix
Add this line
$children = array_slice($children, 0, 5);
Just below
$children = $this->model_catalog_category->getCategories($category['category_id']);
in catalog/controller/module/category.php
Better Solution
Replicate the function getCategoriesByParentId($category_id) in catalog/model/catalog/category.php, add a second paramter limit to it, use this parameter in the SQL query.
Hope that helps!

Resources