I have two table in my database, One is Categories and the other is Sub_Categories, I want to display them like this:
Categorie 1
sub categoie 1
sub categoie 2
sub categoie 3
sub categoie 4
Categorie 2
sub categoie 1
sub categoie 2
sub categoie 3
sub categoie 4
But i don't know how to do this.
In my Database table i have this fields :
Categories: ID, Name, Icon.
Sub_Categories: ID, Categ_id, Name
This should work;
public function get_categories()
{
$query = $this->db->get('Categories');
$return = array();
foreach ($query->result() as $category)
{
$return[$category->id] = $category;
$return[$category->id]->subs = $this->get_sub_categories($category->id); // Get the categories sub categories
}
return $return;
}
public function get_sub_categories($category_id)
{
$this->db->where('Category', $category_id);
$query = $this->db->get('Sub_Categories');
return $query->result();
}
All this does is get's all the categories, but then gets all the subcategories for each of the categories. Calling the get_categories() function should return an object in the format you want.
I hope this helps.
Edit
You would call the get_categories function from your controller and pass it to the view;
$data['categories'] = $this->your_model->get_categories();
$this->load->view('view_file', $data);
Then within your view you would display them like this;
<ul>
<?php
foreach ($categories as $category)
{
?>
<li><?php echo $category->name; ?>
<?php
if(!empty($category->subs)) {
echo '<ul>';
foreach ($category->subs as $sub) {
echo '<li>' . $sub->name . '</li>';
}
echo '</ul>';
}
?>
</li>
<?php
}
?>
</ul>
Database
image for database table
Try this
in Model
public function getCategories()
{
$query = $this->db->query('select * from categories where cat_parent=0');
return $query->result_array();
}
public function getCategoriesSub($parent)
{
$query = $this->db->query("select * from categories where cat_parent='$parent'");
return $query->result_array();
}
in Controller
public function categories()
{
$data['mcats'] = $this->admin_model->getCategories();
foreach($data['mcats'] as $key =>$val){
$subcats = $this->admin_model->getCategoriesSub($val['cid']);
if($subcats){
$data['scats'][$val['cid']] = $subcats;
}
}
$this->load->view('admin/header');
$this->load->view('admin/category_list', $data);
$this->load->view('admin/footer');
}
In view
<ul>
<?php
foreach ($mcats as $key =>$val)
{
?>
<li><?php echo $val['cat_name']; ?>
<ul>
<?php
foreach ($scats[$val['cid']] as $sub) {
echo '<li>' . $sub['cat_name'] . '</li>';
}
?>
</ul>
</li>
<?php
}
?>
</ul>
its already working code - i think it is usefull
Related
I would like to create a photo gallery, taking images from the database.
I'm using codeigniter.
Database
this is a static page located in views/pages/gallery.php
does anyone have any ideas?
What you want is to query the database table, get the relevant fields, and return that to a view. In MVC, it looks something like this:
Model:
class Portfolio_model extends CI_Model {
public function get_items() {
$this->db->select('name, description, image');
$this->db->order_by('date', 'DESC');
$q = $this->db->get('tablename'); // your tablename here
if ($q->num_rows() > 0) {
return $q->result();
} else {
return null;
}
}
}
Controller:
class Portfolio extends CI_Controller {
public function index() {
$this->load->helper('html');
$this->load->model('portfolio_model');
$data['items'] = $this->portfolio_model->get_items();
$this->load->view('portfolio', $data);
}
}
View:
if (!is_null($items)) {
foreach ($items as $item) {
echo $item->name . '<br>';
echo $item->description . '<br>';
echo 'Image src: ' . base_url() . $item->image . '<br>'; // might need slash after base_url, don't remember
echo img($item->image);
}
} else {
echo 'No items found!';
}
This worked for me :
Controller -
public function index(){
$this->load->model('galleryModel');
$data1['items'] = $this->galleryModel->get_items();
$this->load->view('gallery', $data1);
}
Model -
public function get_items() {
$this->db->select('*');
$this->db->from('gallery');
$query = $this->db->get();
if($query->num_rows() != 0){
return $query->result_array();
}else{
return false;
}
}
View -
<?php
foreach ($items as $item) {
$image_id = $item['image_id'];
$name = $item['name'];
$category = $item['category'];
$image = $item['image'];
?>
<div class="tile scale-anm <?php echo $category; ?>">
<img src="<?php echo $image; ?>" class="film-img-gallery" alt="" />
</div>
<?php } ?>
I have two tables state and city
state table has two column
state_id | state_name
---------|-----------
1 | Alabama
2 | Alaska
3 | Arizona
and City table has two column as well
state_name | city_name
-----------|----------
1 |
1 |
1 |
2 |
2 |
3 |
Controller
function city()
{
$data = array();
$data['states']=$this->state_model->state_query();
$data['cities']=$this->cities_model->cities_query();
$this->load->view('city', $data);
}
Model
public function state()
{
$this->db->select('state_name');
$this->db->from('state');
$this->db->join('city', 'city.state_name = state.state_name');
$result = $this->db->get();
}
View
<?php foreach ($cities as $city) { ?>
<?php echo $city->city_name; ?>
<?php echo $city->state_name; ?>
<?php } ?>
the above code is the controller, model, and view respectively. The issue is that I want to echo state_name but not working, the city name is displaying as expected. Please, I need suggestion on what to do.
Your Model Should Be:
public function state()
{
$this->db->select('s.state_name as state,c.city_name as city, c.state_name as state_id');
$this->db->from('state as s');
$this->db->join('city as c', 'c.state_name = s.state_id ');
$result = $this->db->get();
$data = $result->result_array();
if(isset($data) && !empty($data))
{
return $data;
} else {
return FALSE;
}
}
Your Controller Should be:
public function city()
{
$this->load->model('your_model');
$city_state_data = $this->your_model->state();
// I have just added example of getting data from model to controller
// and then passing it to view. You need to use it as you need
$this->load->view('your_view', ['city_state_data' => $city_state_data]);
}
View:
<?php foreach ($city_state_data as $single_city_state) { ?>
<?php echo $single_city_state['state']; ?>
<?php echo $single_city_state['city']; ?>
<?php } ?>
Model
public function state()
{
$this->db->select('state.state_name as state_tbl1, city.state_name as state_tbl2, city.city_name');
$this->db->join('city', 'city.state_name = state.state_name');
$result = $this->db->get('state');
return $result->result();
}
Controller
function city()
{
$data['states']=$this->state_model->state();
$this->load->view('city', $data);
}
View
<?php foreach ($states as $city) {
echo $city->city_name;
echo $city->state_tbl1;
echo $city->state_tbl2;
} ?>
I want to display all categories and their subcategories in primary nav menu.
When i hover on cateory, it should display its subcategories.
I want to implement this functionality without loading Mage::getModel('catalog/category') in foreach loop.
as you want to write code in phtml file use below code which create tree structure of category.
<ul>
<?php
$obj = new Mage_Catalog_Block_Navigation();
$storeCategories = $obj->getStoreCategories();
Mage::registry('current_category') ? $currentCategoryId = Mage::registry('current_category')->getId() : $currentCategoryId='';
foreach ($storeCategories as $_category):
?>
<li>
<strong><?php echo $_category->getName(); ?></strong>
<?php $categoryChildren = $_category->getChildren(); ?>
<?php if($categoryChildren->count()) : ?>
<ul>
<?php foreach($categoryChildren as $_categoryChild) : ?>
<?php $_categoryChildModel = Mage::getModel('catalog/category')->load($_categoryChild->getId());?>
<?php $categoryGrandchildren=$_categoryChild->getChildren(); ?>
<li>
<?php
$currentCategoryId===$_categoryChild->getId() ? $bold="style=\"font-weight:bold\"" : $bold='';
echo ' ' . '<a href="' . $_categoryChildModel->getUrl() . '"' . $bold . '>' . $_categoryChild->getName() . '(' . $_categoryChildModel->getProductCollection()->count() . ')</a>';
?>
</li>
<?php if($categoryGrandchildren->count()) : ?>
<?php foreach($categoryGrandchildren as $_categoryGrandchild) : ?>
<?php $_categoryGrandchildModel = Mage::getModel('catalog/category')->load($_categoryGrandchild->getId());?>
<li>
<?php
$currentCategoryId===$_categoryChild->getId() ? $bold="style=\"font-weight:bold\"" : $bold='';
echo ' ' . '<a href="' . $_categoryGrandchildModel->getUrl() . '"' . $bold . '>' . $_categoryGrandchild->getName() . '(' . $_categoryGrandchildModel->getProductCount() . ')</a>';
?>
</li>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</li>
<?php endforeach ?>
</ul>
and using css and HTML you can achieve your goal to display sub menu on hover of main menu.
Still let me if you need any other help.
Thanks
ok so I just did this and I figured I'd search to see if anyone was wondering how to achieve this. The trick to this is
Mage::getResourceSingleton('catalog/category')->getAttributeRawValue($categoryEntityId,array('name','level','url_key','path','is_active'),Mage::app()->getStore());
This does not load the category model lets take a look at what it is actually doing.
Go to app/code/core/Mage/Catalog/Model/Resource/Abstract
public function getAttributeRawValue($entityId, $attribute, $store)
{
if (!$entityId || empty($attribute)) {
return false;
}
if (!is_array($attribute)) {
$attribute = array($attribute);
}
$attributesData = array();
$staticAttributes = array();
$typedAttributes = array();
$staticTable = null;
$adapter = $this->_getReadAdapter();
foreach ($attribute as $_attribute) {
/* #var $attribute Mage_Catalog_Model_Entity_Attribute */
$_attribute = $this->getAttribute($_attribute);
if (!$_attribute) {
continue;
}
$attributeCode = $_attribute->getAttributeCode();
$attrTable = $_attribute->getBackend()->getTable();
$isStatic = $_attribute->getBackend()->isStatic();
if ($isStatic) {
$staticAttributes[] = $attributeCode;
$staticTable = $attrTable;
} else {
/**
* That structure needed to avoid farther sql joins for getting attribute's code by id
*/
$typedAttributes[$attrTable][$_attribute->getId()] = $attributeCode;
}
}
/**
* Collecting static attributes
*/
if ($staticAttributes) {
$select = $adapter->select()->from($staticTable, $staticAttributes)
->where($this->getEntityIdField() . ' = :entity_id');
$attributesData = $adapter->fetchRow($select, array('entity_id' => $entityId));
}
/**
* Collecting typed attributes, performing separate SQL query for each attribute type table
*/
if ($store instanceof Mage_Core_Model_Store) {
$store = $store->getId();
}
$store = (int)$store;
if ($typedAttributes) {
foreach ($typedAttributes as $table => $_attributes) {
$select = $adapter->select()
->from(array('default_value' => $table), array('attribute_id'))
->where('default_value.attribute_id IN (?)', array_keys($_attributes))
->where('default_value.entity_type_id = :entity_type_id')
->where('default_value.entity_id = :entity_id')
->where('default_value.store_id = ?', 0);
$bind = array(
'entity_type_id' => $this->getTypeId(),
'entity_id' => $entityId,
);
if ($store != $this->getDefaultStoreId()) {
$valueExpr = $adapter->getCheckSql('store_value.value IS NULL',
'default_value.value', 'store_value.value');
$joinCondition = array(
$adapter->quoteInto('store_value.attribute_id IN (?)', array_keys($_attributes)),
'store_value.entity_type_id = :entity_type_id',
'store_value.entity_id = :entity_id',
'store_value.store_id = :store_id',
);
$select->joinLeft(
array('store_value' => $table),
implode(' AND ', $joinCondition),
array('attr_value' => $valueExpr)
);
$bind['store_id'] = $store;
} else {
$select->columns(array('attr_value' => 'value'), 'default_value');
}
$result = $adapter->fetchPairs($select, $bind);
foreach ($result as $attrId => $value) {
$attrCode = $typedAttributes[$table][$attrId];
$attributesData[$attrCode] = $value;
}
}
}
if (sizeof($attributesData) == 1) {
$_data = each($attributesData);
$attributesData = $_data[1];
}
return $attributesData ? $attributesData : false;
}
As you can see no model loading happening just retrieving specific pieces of info. Also being part of the resource abstract means all catalog resource models (I haven't checked other resource models but, I wouldn't be too surprised to find this in others) have this available.
If you use this in an override of Mage_Catalog_Block_Navigation you can then call all of the info you need about any category without loading the model. To traverse the tree however, you have to do terrible things.
You can use 'path'(explode on /) to easily retrieve parents but you will need to get dirty in order to retrieve children categories so something like this to get Children.
$childrenQuery = "SELECT entity_id FROM catalog_category_entity WHERE path REGEXP '^.*\/" . $categoryId . "\/[[:digit:]]?[[:digit:]]?[[:digit:]]?[[:digit:]]?$'";
$resource = Mage::getSingleton('core/resource');
$readCxn = $resource->getConnection('core/read');
$children = $readCxn->fetchAll($childrenQuery);
if ($children[0]) {
return $children;
} else {
return;
}
The overall difficulty is that all model and resource model functions will expect an instance of a category object to make them all work with just the entity_id is definitely possible just a pain.
So I would not recommend doing this in general the only reason I did this is because the default magento root category in my case was not the actual functional root of categories (fun eh). If you are using a standard root category I would recommend using the Helper functions and retrieving the info from cache.
Either way from here all you have to do complete your functions in Mage_Catalog_Block_Navigation and assemble your menu in a template. And there you go; complete category menu without ever accessing a model->load.
Try This Code
<?php
require_once("app/Mage.php");
Mage::app();
function getChildCategories($category, $First = false) {
$sub = $First ? $category : $category->getChildren();
foreach ($sub as $child) {
$_categories[] = [ "name" => $child->getName(), "id" => $child->getId(), "children" => getChildCategories($child) ];
}
return $_categories;
};
function CategoriesTree($category, $First = false) {
$sub = $First ? $category : $category->getChildren();
echo "<pre>";
foreach ($sub as $child) {
echo $child->getName(); ;
CategoriesTree($child);
}
}
$_categories = Mage::helper('catalog/category')->getStoreCategories();
$categories = getChildCategories($_categories, true);
CategoriesTree($_categories, true);
?>
I use CI form with form_dropdown helper and tried to pull Mysql data into its options, from the below code, its only retrieve the last record from db into the option list?
please advise what is wrong with my code?
Model
public function getStates() {
$query = $this->db->get('states');
$return = array();
if($query->num_rows() > 0){
$return[''] = 'please select';
foreach($query->result_array() as $row){
$return[$row['state_id']] = $row['state_name'];
}
}
return $return;
}
Controller
$this->load->model('db_model');
$data['options'] = $this->db_model->getStates();
$this->load->view('create_new', $data);
View
$state = array(
'name' => 'state',
'id' => 'state',
//'value' => set_value('state', $state)
);
<?php echo form_label('State', $state['id']); ?>
<?php echo form_dropdown($state['name'], $options); ?>
<?php echo form_error($state['name']); ?>
<?php echo isset($errors[$state['name']])?$errors[$state['name']]:''; ?>
send full query result from the model to the view like this
Model
public function getStates() {
$query = $this->db->get('states');
return $query->result();
}
let the controller as it is and now you can populate states in dropdown like this:
View
<?php
foreach($options as $opt){
$options[$opt->state_id]=$opt->state_name;
}
echo form_dropdown($state['name'], $options);
?>
Try this:
function getStates() {
$return = array();
$query = $this->db->get('states')->result_array();
if( is_array( $query ) && count( $query ) > 0 ){
$return[''] = 'please select';
foreach($query as $row){
$return[$row['state_id']] = $row['state_name'];
}
}
return $return;
}
I am trying to build a forum with Codeigniter.
So far i have the forums themselves displayed and the threads displayed, based on the creating dynamic news tutorial.
But that is 2 different pages, i need to obviously display them into one page, like this:
Forum 1
- thread 1
- thread 2
- thread 3
Forum 2
- thread 1
- thread 2
etc.
And then the next step is obviously to display all the posts in a thread. Most likely with some pagination going on. But that is for later.
For now i have the forum controller (slimmed version):
<?php
class Forum extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('forum_model');
$this->lang->load('forum');
$this->lang->load('dutch');
}
public function index()
{
$data['forums'] = $this->forum_model->get_forums();
$data['title'] = $this->lang->line('title');
$data['view'] = $this->lang->line('view');
$this->load->view('templates/header', $data);
$this->load->view('forum/index', $data);
$this->load->view('templates/footer');
}
public function view($slug)
{
$data['forum_item'] = $this->forum_model->get_forums($slug);
if (empty($data['forum_item']))
{
show_404();
}
$data['title'] = $data['forum_item']['title'];
$this->load->view('templates/header', $data);
$this->load->view('forum/view', $data);
$this->load->view('templates/footer');
}
}
?>
And the forum_model (also slimmed down)
<?php
class Forum_model extends CI_Model {
public function __construct()
{
$this->load->database();
}
public function get_forums($slug = FALSE)
{
if ($slug === FALSE)
{
$query= $this->db->get('forum');
return $query->result_array();
}
$query = $this->db->get_where('forum', array('slug' => $slug));
return $query->row_array();
}
public function get_threads($forumid, $limit, $offset)
{
$query = $this->db->get_where('thread', array('forumid', $forumid), $limit, $offset);
return $query->result_array();
}
}
?>
And the view file
<?php foreach ($forums as $forum_item): ?>
<h2><?=$forum_item['title']?></h2>
<div id="main">
<?=$forum_item['description']?>
</div>
<p><?=$view?></p>
<?php endforeach ?>
Now that last one, i would like to have something like this:
<?php foreach ($forums as $forum_item): ?>
<h2><?=$forum_item['title']?></h2>
<div id="main">
<?=$forum_item['description']?>
</div>
<?php foreach ($threads as $thread_item): ?>
<h2><?php echo $thread_item['title'] ?></h2>
<p><?=$view?></p>
<?php endforeach ?>
<?php endforeach ?>
But the question is, how do i get the model to return like a double query to the view, so that it contains both the forums and the threads within each forum.
I tried to make a foreach loop in the get_forum function, but when i do this:
public function get_forums($slug = FALSE)
{
if ($slug === FALSE)
{
$query= $this->db->get('forum');
foreach ($query->row_array() as $forum_item)
{
$thread_query=$this->get_threads($forum_item->forumid, 50, 0);
}
return $query->result_array();
}
$query = $this->db->get_where('forum', array('slug' => $slug));
return $query->row_array();
}
i get the error
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: models/forum_model.php
Line Number: 16
I hope anyone has some good tips, thanks!
Lenny
*EDIT***
Thanks for the feedback.
I have been puzzling and this seems to work now :)
$query= $this->db->get('forum');
foreach ($query->result() as $forum_item)
{
$forum[$forum_item->forumid]['title']=$forum_item->title;
$thread_query=$this->db->get_where('thread', array('forumid' => $forum_item->forumid), 20, 0);
foreach ($thread_query->result() as $thread_item)
{
$forum[$forum_item->forumid]['thread'][]=$thread_item->title;
}
}
return $forum;
}
What is now next, is how to display this multidimensional array in the view, with foreach statements....
Any suggestions ?
Thanks
You are using row_array() hence your error, change your get_forums() to:
$thread_query=$this->get_threads($forum_item['forumid'], 50, 0);
But I believe you should actually be using result_array() since you want a list of all forums.