Issue/Question: I'm using CodeIgniter to build an event calendar, and I have included a sharing option. This option works at a base level, but only displays the users' ID (primary key) in an <ul>. This isn't ideal, and I would like to show the users' first and last names in the <ul> instead. I thought creating an associative array would work, but I'm receiving funky results. The first and last name echo out as "Array Array" when the page loads, and the URL id comes up as "Array" when you select the "Array Array" link. I'm wondering what is wrong in my logic.
Funky link generated in view:
Array Array
Funky URL that is linked to "Array Array":
http://example.com/user/shared/view/Array
Modified Controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Shared extends Common_Auth_Controller {
private $end_user;
public function __construct()
{
parent::__construct();
$this->end_user = $this->ion_auth->user()->row();
$data['end_user'] = $this->end_user;
$this->load->vars($data);
$this->load->model('events_model', 'events');
}
public function index()
{
$title['title'] = 'Shared';
$this->load->model('shared_model','shared');
$data['sharers'][] = array(
'shared_owner_id' => $this->shared->get($this->end_user->id),
'owner_first_name' => $this->shared->get($this->end_user->first_name),
'owner_last_name' => $this->shared->get($this->end_user->last_name),
);
$this->load->view('public/head_view', $title);
$this->load->view('user/header_view');
$this->load->view('user/shared_view', $data);
$this->load->view('user/footer_view');
}
Modified View:
<div class="hide-on-phones">
<ul>
<?php foreach($sharers as $key => $value): ?>
<li><?php echo $value['owner_first_name']." ".$value['owner_last_name'] ?></li>
<?php endforeach; ?>
</ul>
</div>
Model:
class Shared_model extends crud_model {
public function __construct()
{
parent::__construct();
$this->pk = 'id';
$this->table_name = 'shared';
}
public function get($shared_to_user_id)
{
$this->db->where('shared_to_id', $shared_to_user_id);
$ids = parent::get_all();
$users = array();
foreach ($ids as $id)
{
$users[] = $id->owner_id;
}
return $users;
}
}
Thank you so much for your help, and let me know if there is any more information that may be required. Below are the original view and controllers that work, but are not preferable.
Original Controller:
public function index()
{
$title['title'] = 'Shared';
$this->load->model('shared_model','shared');
$data['sharers'] = $this->shared->get($this->end_user->id);
$this->load->view('user/head_view', $title);
$this->load->view('user/header_view');
$this->load->view('user/navigation_view');
$this->load->view('user/shared_view', $data);
$this->load->view('user/footer_view');
}
Original View:
<?php foreach($sharers as $s): ?>
<li><?php echo $s ?></li>
<?php endforeach; ?>
Disclaimer: I'm new to web development, and I suck at associative arrays (apparently).
Your $data['sharers'] array doesn't have arrays as $values. Therefore, the way you are calling the $value[]'s in your foreach aren't working. You have no reason for calling the foreach at this point.
<div class="hide-on-phones">
<ul>
<li><a href="<?=base_url('user/shared/view/'.$sharers['shared_pk_id'])?>">
<?=$sharers['first_name'] . ' ' . $sharers['last_name']?>
</a>
</li>
</ul>
</div>
I expect you will later on fill an array with the data, in which case you can fill it as
$data['sharers'][] = array(
'shared_pk' => $this->shared->get($this->end_user->id),
'first_name' => $this->events->get($this->end_user->first_name),
'last_name' => $this->events->get($this->end_user->last_name)
);
Which, in turn can be looped using
<div class="hide-on-phones">
<ul>
<? foreach($sharers as $sharer): ?>
<li>
<a href="<?=base_url('user/shared/view/' . $sharer['shared_pk'])?>">
<?=$sharer['first_name'] . ' ' . $sharer['last_name']?>
</a>
</li>
<? endforeach; ?>
</ul>
</div>
I've figured it out. I needed to create an associative array in my model; not my controller. Thanks to everyone for your help!
Model:
class Shares_model extends crud_model {
public function __construct()
{
parent::__construct();
$this->pk = 'id';
$this->table_name = 'shares';
}
public function get($shared_to_user_id)
{
$this->db->where('shared_to_id', $shared_to_user_id);
$ids = parent::get_all();
$users = array();
foreach ($ids as $id)
{
$users[$id->owner_id]['owner_id'] = $id->owner_id;
$users[$id->owner_id]['owner_first_name'] = $id->owner_first_name;
$users[$id->owner_id]['owner_last_name'] = $id->owner_last_name;
}
return $users;
}
}
View:
<ul>
<?php foreach($sharers as $s): ?>
<li><?php echo $s['owner_first_name']." ".$s['owner_last_name'] ?></li>
<?php endforeach; ?>
</ul>
Controller:
public function index()
{
$title['title'] = 'Shared';
$this->load->model('shares_model','shares');
$data['sharers'] = $this->shares->get($this->end_user->id);
$this->load->view('public/head_view', $title);
$this->load->view('user/header_view');
$this->load->view('user/shared_view', $data);
$this->load->view('user/footer_view');
}
If we take your $data['sharers'] array and put in values for the php, then we would get something like this:
$data['sharers'] = array(
0 => array(
'id' => 1234,
'first_name' => 'John',
'last_name' => 'Doe'
),
1 => array(
'id' => 1235,
'first_name' => 'Jane',
'last_name' => 'Doe'
)
);
So, when you loop through this in your view, you need to access these correctly:
foreach($sharers as $key => $value):
// at this point, in the first iteration of the loop
// $key is 'id', or 'first_name', or 'last_name'
// and $value is 1234, or 'John', or 'Doe'
endforeach;
So, to loop through the sharers a bit easier, you just need to update your foreach a bit. At this point, change your view to this:
<div class="hide-on-phones">
<ul>
<?php foreach($sharers as $sharer): ?>
<li>
<a href="<?php echo base_url('user/shared/view/'.$sharer['shared_pk_id']) ?>">
<?php echo $sharer['first_name']. " " .$sharer['last_name'] ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
Related
I am starting to learn Yii framework so I am a beginner. I am struggling. I want to fetch the data from database using yii2 framework. This is my controller
public function actionView()
{
$this->view->title = 'List Hotels';
$items = ArrayHelper::map(Hotel::find()->all(), 'id', 'name');
return $this->render('index', [
'items' => $items,
]);
}
In my view file, I used the fetched data as below;
<?php
/* #var $this yii\web\View */
use yii\helpers\Html;
$this->title = 'Hotel list';
$this->params['breadcrumbs'][] = $this->title;
?>
<?php foreach ($items as $item): ?>
<p> <?= $item-> name ?></p>
<p> <?= $item->address ?></p>
<p> <?= $item->description ?></p>
<?php endforeach; ?>
When I wrote var_dumps($items) under $items I can see the datas. However in the view It says Trying to get property 'name' of non-object. What did I wrong here please guide me. THanks for your time.
ArrayHelper::map()
Returns an array where, in your case, second argument passed is a key, the third is a value. So you need to access its elements as an array elements instead of class properties. Like:
<?php foreach ($items as $key => $value): ?>
<p> <?= $key ?></p>
<p> <?= $value ?></p>
<?php endforeach; ?>
More details here: https://www.yiiframework.com/doc/api/2.0/yii-helpers-basearrayhelper#map()-detail
But if you need to access data as class properties change the line in your controller:
$items = ArrayHelper::map(Hotel::find()->all(), 'id', 'name');
to:
$items = Hotel::find()->all();
$items = Hotel::find()->all();
I should not add Array Helper
I use basic mode on Yii2 framework. I create two controllers - SiteController and CategoryController. I have two folders with few views - site (index and about) and category (category and search).
When i render view by SiteController evething is ok, but when i render view by CategoryController actionSearch - do not call main.php and do not show any html in view, but if i call die - the results is there.
Here is a code:
model:
namespace app\models;
use yii\db\ActiveRecord;
class Categories extends ActiveRecord
{
public static function tableName()
{
return 'categories';
}
public function getProducts(){
return $this->hasMany(Products::className(), ['category_id' => 'id']);
}
}
and CategoryController:
public function actionSrch() {
$cat = Categories::findOne(1);
$q = Yii::$app->request->get('q');
if(isset($q) and $q!=''){
$query = Products::find()->where(['like', 'title', $q]);
// pagination
$pages = new Pagination([
'totalCount' => $query->count(),
'pageSize' => 4,
'forcePageParam' => false,
'pageSizeParam' => false ]);
$products = $query->offset($pages->offset)->limit($pages->limit)->all();
}else{
$products = Products::find()->where('title<>:title', [':title'=>''])->all();
}
$this->render('search', compact('products','pages', 'q', 'cat'));
}
and the Search form:
<div class="col-sm-3">
<div class="search_box pull-right">
<form action="<?= \yii\helpers\Url::to(['categories/search']) ?>" method="get">
<input type="text" placeholder="Search" name="aaa">
</form>
</div>
</div>
and the view in search.php
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\LinkPager;
<ul class="catalog category-products">
<?= \app\components\MenuWidget::Widget(['tpl' => 'menu']) ?>
</ul>
<div class="col-sm-9 padding-right">
<div class="features_items"><!--features_items-->
<?php if(!empty($products)): ?>
<?php $i = 0; foreach($products as $prd): ?>
<h2><?= $prd->price ?></h2>
<?php endif; ?>
<?php endforeach; ?>
<?php else :?>
<div class="alert alert-danger">Do not have products!!!</div>
<?php endif; ?>
First chack your action name actionSrch or actionSearch.
And add return before render file like below.
public function actionSrch() {
$cat = Categories::findOne(1);
$q = Yii::$app->request->get('q');
if(isset($q) and $q!=''){
$query = Products::find()->where(['like', 'title', $q]);
// pagination
$pages = new Pagination([
'totalCount' => $query->count(),
'pageSize' => 4,
'forcePageParam' => false,
'pageSizeParam' => false
]);
$products = $query->offset($pages->offset)->limit($pages->limit)->all();
}else{
$products = Products::find()->where('title<>:title', [':title'=>''])->all();
}
return $this->render('search', compact('products','pages', 'q', 'cat'));
}
Refere Yii2 Base Actions and Yii2 Render()
I am getting user profile fields from the database and want to display in my view but don't know to do this with the master layout.
this is my model
function fetchProfile($id,$page){
$query = $this->db->query("SELECT * FROM staff_master WHERE Id='$id'");
return $query->result();
}
this is my controller:
public function edit($id,$page){
$data['query'] = $this->StaffModel->fetchProfile($id,$page);
$data= array('content'=>'view_staff_edit');
$this->load->view('template_master',$data);
}
I am also trying to find a solution. I am passing user Id and another by URL (get method).
You are overwriting $data['query'] when you assign the array next:
$data['query'] = $this->StaffModel->fetchProfile($id,$page);
$data= array('content'=>'view_staff_edit');
Either do:
$data= array('content'=>'view_staff_edit');
$data['query'] = $this->StaffModel->fetchProfile($id,$page); // note position
Or:
$data = array(
'content' = 'view_staff_edit',
'query' => $this->StaffModel->fetchProfile($id,$page),
);
Access in view via $query and $content.
Unrelated:
You are also missing $page in your query, and its generally a good idea to declare gets as null if not set or you will get a notice: public function edit($id=null,$page=null){
Your overriding your first declaration of variable $data what you can do is to initialize them both at the same time.
Controller
public function edit($id,$page){
$data = array(
'query' => $this->StaffModel->fetchProfile($id,$page),
'content' => 'view_staff_edit'
);
$this->load->view('template_master',$data);
}
Then access it on your View file
<h1><?php echo $content ?></h1>
<?php foreach($query as $result): ?>
<p><?php echo $result->id ?></p>
<?php endforeach; ?>
Try doing something like this:
public function edit($id,$page) {
$data['query'] = $this->StaffModel->fetchProfile($id,$page);
$data['content']= 'view_staff_edit';
$this->load->view('template_master',$data);
}
YOUR MODEL
function fetchProfile($id){
return $this->db->get_where('Id' => $id)->result_array();
}
YOUR CONTROLLER
public function edit($id,$page){
$data = array(
'query' => $this->StaffModel->fetchProfile($id),
'content' => 'view_staff_edit',
);
$this->load->view('template_master',$data);
}
YOUR "template_master" VIEW
<?php foreach ($query as $res){?>
<span><?php echo $res['Id'];?></span> //User html content according to your requirements ALSO you can add all columns retrieved from database
<?php } ?>
I am trying to create dynamic menu using PHP Codeigniter.
There are some Main Menu
Each Main Menu have some Sub_Menu Like, Categories ->Hardware, Software etc.
I somehow made it but there is an issue, the Main menu is showing correctly but the sub menu under main menu is repeating in each Main menu.
This is the image of the issue:
My View Code
<ul class="slimmenu">
<?php foreach($menus as $menu): ?>
<li>
<?php echo $menu -> Menu_Name;?>
<ul>
<?php foreach($submenus as $submenu): ?>
<li>
<?php echo $submenu -> Sub_Menu_Name;?>
</li>
<?php endforeach;?>
</ul>
</li>
<?php endforeach;?>
</ul>
My Controller Code
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class MainSystem extends CI_Controller
{
function __construct() {
parent::__construct();
$this->load->model('menusys','ms');
}
function menu()
{
$this->data['menus'] = $this->ms->get_menu();
$this->data['submenus'] = $this->ms->get_submenu();
$this->load->view('index', $this->data);
}
function add_menu()
{
$data = array(
'Menu_Name' => $this->input->post('mname'),
'Menu_Link' => $this->input->post('mlink'),
);
$this->ms->adm($data);
}
function sub_menu()
{
$this->data['mmenu'] = $this->ms->get_menu();
$this->load->view('submenu', $this->data);
}
function add_submenu()
{
$data = array(
'Main_Menu_Name' => $this->input->post('mmname'),
'Sub_Menu_Name' => $this->input->post('mname'),
'Sub_Menu_Link' => $this->input->post('mlink'),
);
$this->ms->adsm($data);
}
}
?>
My Model Code
<?php
defined('BASEPATH') or exit('no direct script directy allowed');
/**
*
*/
class menusys extends CI_Model
{
public function __construct()
{
parent::__construct();
}
public function adm($data)
{
$this->db->set('Is_Active',0);
$this->db->insert('main_menu',$data);
$this->session->set_flashdata('msg', 'Meun has been added');
redirect('MainSystem/menu');
}
//sub-menu Section
public function get_menu()
{
//$this->db->where('Is_Active',1);
// $this->db->select('*');
// $this->db->from('main_menu');
// $this->db->join('sub_menu', 'main_menu.Menu_Name = sub_menu.Main_Menu_Name','inner');
// $query = $this->db->get();
// return $query->result();
//
$query=$this->db->get_where('main_menu',array('Is_Active'=>1));
return $query->result();
}
function get_submenu()
{
$this->db->where('main_menu.Menu_Name = sub_menu.Main_Menu_Name');
$this->db->select('*');
$this->db->from('sub_menu');
$this->db->join('main_menu', 'main_menu.Menu_Name = sub_menu.Main_Menu_Name','inner');
$query = $this->db->get();
return $query->result();
}
public function adsm($data)
{
$this->db->set('Is_Active',1);
$this->db->insert('sub_menu',$data);
$this->session->set_flashdata('msg', 'Meun has been added');
redirect('MainSystem/menu');
}
}
What I Want: I want that each Sub_Menu will show under his parent menu.
Any help will be appreciated.
UPDATE
This is sub-menu table image.
you need to format your menu array and loop it something like this
$menu = array(
'menu_name_1' => array(
'submenu1_1' => 'www.something.com',
'submenu1_2' => 'www.something.com',
),
'menu_name_2' => array(
'submenu2_1' => 'www.something.com',
'submenu2_2' => 'www.something.com',
)
);
foreach($menu as $menu_name => $submenu){
echo $menu_name.'<br>';
if (!empty($submenu)){
foreach($submenu as $submenu_name => $submenu_link){
echo ''.$submenu_name.'<br>';
}
}
}
You have array with menu names and submenu. First you loop menu name and check dose it has submenu, it if has, you loop submenu and make links.
I'm using Codeigniter to write a shopping cart system. Tried to research but unable to figure out the way, I want to get the dynamic value "Green/Red/Yellow" in dynamic drop-down list like below:
Below is my code:
Model:
class Products_model extends CI_Model {
public function get_all() {
$result = $this->db->get('products');
foreach ($result->result() as $value) {
if ($value->option_values){
$value->option_values = explode(',', $value->option_values);
}
} return $result;
}
Controller:
class Shopping_cart extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->helper('html');
$this->load->model('products_model');
$this->load->library('cart');
}
public function index() {
$data['records'] = $this->products_model->get_all();
$data['main'] = 'shopping_cart_view';
$this->load->view('templates/shopping_cart', $data);
}
public function add() {
//If the product is not listed, perform insert
$data = array(
'id' => $this->input->post('id'),
'qty' => $this->input->post('quantity'),
'price' => $this->products_model->get_by_id($this->input->post('id'))->price,
'name' => $this->products_model->get_by_id($this->input->post('id'))->name,
'option' => '' //I want to get the dynamic values in dropdown list and put in to this option array.
);
$this->cart->insert($data);
redirect('shopping_cart');
}
View:
<?php
//List products
foreach ($records->result() as $value) :
echo form_open('shopping_cart/add');
?>
<?php //List the dropdown if value has option i.e color/size/type
if ($value->option_name)
:?>
<?php echo form_label($value->option_name, $value->id)?>
<?php echo form_dropdown(
$value->option_name,
$value->option_values
)?>
<?php endif;?>
<?php
echo form_hidden('id', $value->id);
echo form_submit('submit', 'Add to cart');
?>
<?php echo form_close();?>
<?php endforeach; ?>
And below is $this->cart->contents() when i submitted "add to cart":
Array ( [c4ca4238a0b923820dcc509a6f75849b] => Array ( [rowid] => c4ca4238a0b923820dcc509a6f75849b [id] => 1 [qty] => 1 [price] => 100 [name] => T-shirt [option] => [subtotal] => 100 ) )
I am running out of ideas try to get the dynamic value inside dynamic loop. Any advises are really appreciated.
Thanks a lots!
I would create the array of option_values in the controller (so bring option_values as string via Model and declare an array in the controller that will contain the explode(',', option_values) ).
Then use this array as source for 'option'.
Hope this helps.
The problem is in this part:
foreach ($result->result() as $value) {
if ($value->option_values){
$value->option_values = explode(',', $value->option_values);
}
}
return $result;
$value is only valid, in the way you have done this, during the method. It's not saved to the $result. You would need to do something along these lines:
$new_result = array ();
foreach ($result->result() as $value) {
if ($value->option_values){
$value->option_values = explode(',', $value->option_values);
}
$new_result[] = $value;
}
return $new_result;
When you are going through a foreach loop like that, you disconnect the $value form $result.
There are other ways to do this, but I think that is the clearest and most understandable.