Codeigniter foreach displaying only one div - php

My table has got 4 categories with unique id. And all I am doing is just querying the database and including a foreach loop which is getting the cateogry ids based on which subcategories are being fetched. Since my table has got 4 categories . So running the loop has to return the div 4 times which I will echo out in the view. That is the concept I had. But it is returning only once. So the div main_div gets printed only for once. I don't understand what is wrong here.
In my Model
public function getSubCategory(){
$sub_div = null;
$query_main_cat = $this->db->query("SELECT * FROM main_category");
foreach($query_main_cat->result_array() as $row){
$mc_id = $row['id'];
$query_get_sub = $this->db->get_where("sub_category", array('main_cat_id' => $mc_id));
foreach ($query_get_sub->result_array() as $row_sub_cat) {
$sub_cat_id = $row_sub_cat['id'];
$sub_cat_name = $row_sub_cat['sub_name'];
$sub_cat_mc_id = $row_sub_cat['main_cat_id'];
$sub_div .= '<div class="col-sm-6 col-md-4">
<div class="table-responsive">
<table class="table table-striped text-center">
<th class="text-center">'.$sub_cat_name.'</th>
<tbody>
<tr><td>Hello</td></tr>
<tr><td>Hello</td></tr>
</tbody>
</table>
</div>
</div>';
}
$main_div = '<div class="tab-pane" id="tab'.$mc_id.'">
'.$sub_div.'
</div>';
return $main_div;
}
}
In my controller
public function load_view(){
$this->load->model("get_category");
$data['sub_category'] = $this->get_category->getSubCategory();
$this->load->view('index', $data);
}
In view
echo $sub_category;
This should return the div main_div 4 times. since I have got 4 rows in my table. But only is showing for once. Need some help here.

You get only once hello, because you prematurely return out of the loop.
return "hello";
You should not use return in the loop, but accumulate the string and return it at the end.
$text = '';
foreach($query_main_cat->result_array() as $row){
$text .= "hello";
}
return $text;

Related

Dynamically EDIT table data, PHP, AJAX

I am looking for the cleanest way I could do the following.
<?php
function display_data($label, $yes_no, $model) {
$return = "<tr><th><label>".$label."</label></th><td>";
if ($yes_no == '1') { $return .= "Yes"; } else { $return .= "No"; }
$return .= "</td><td>";
if (isset($model)) {
$return .= $model;
}
$return .= "</td></tr>";
return $return;
}
?>
<table>
<thead>
<tr>
<th>Make</th>
<th>Yes/No</th>
<th>Model</th>
</tr>
</thead>
<tbody>
<?php
echo display_data("Ford", $car_form["available"], $car_form["avail_model"]);
echo display_data("Honda", $car_form["available"], $car_form["avail_model"]);
?>
</tbody>
</table>
I want to be able to EDIT the body contents of the table by just clicking on any of them, with say jquery. Changing the value and once I click out of it, it saves with AJAX.
So I should be able to click into any of the Yes/No or Model rows and change them. I'm going to have a lot of data, so I am not sure how to do this in large scale. I just don't want to have to create a individual jquery function, and divs for every single piece of data I have. If anyone can think of a cleaner way, that would be awesome.
Everything I have now, is working correctly, I just have not implemented a CRUD like system into this yet.

How to retrieve explode images path in database to view in codeigniter 2.2.6

`hi guys am trying from 4 days am not getting . how to retrieve multiple images from using explode functionality.Now I need to explode that image in view . i getting single images from an array but not retrieveing multiple images in my database have one row contains three images how to return result from model.
and show in the view file
myview file:
`<div class="carousel-inner" >
<?php echo $this->session->flashdata('message')?>
<?php $item_class = 'active';
foreach($newzw as $result){?>
<div class="item <?php echo $item_class; ?> ">
<div class="overlay"></div>
<?php $img=explode(",",base_url().'uploads/images/'.$result->image);
//print_r($img);exit;
?>
<img src="<?php echo $img[0] ?> " alt="Los Angeles" style="height:662px;" >
</div>
<?php $item_class = '';
} ?>
</div>
<!-- Left and right controls -->
</div>
</div>
my model code:
function uploadslide1()
{
$this->db->select('*');
$this->db->order_by("id", "DESC");
$query = $this->db->get("sg_slides");
if ($query->num_rows() > 0) {
foreach ($query->result() as $row) {
$data[] = $row;
}
return $data;
}
return false;
}
controller:
function index()
{
$data=$this->general();
$data['newzw']=$this->public_model->uploadslide1();
$data['body']="static/body";
$this->load->view('welcome',$data);
}
I'm just telling you how to using explode.
The explode() function breaks a string into an array. If you want to break your image value into an array format then you have to do this
explode(separator,string); // Syntax
In your case , plays a role of separator.
$img = explode(",", $result->image); //store image value as an array format in img
Now you have the $img variable as an array now you can perform itteration using foreach
example:
foreach($img as $src){
echo '<img src="'.base_url().'uploads/images/'.trim($src)." />';
}

Too many queries, php. Creating lite forum engine

I've started to writing my engine of forum, just to refresh php skills.
My problem is that, when I make a board and one theard, I have double queries.
I know why, I have "foreach in different foreach" but I cannot find a way to sort it out, can you guys help me how would you do it? To avoid this big number of queries?
An example, SMF forum main page has only 12 queries (NO MATTER OF NUMBERS BOARDS AND THEARDS).
My page have 12 already, but I have only 2 categories, 5 boards, 4 theards, 1 user.
If I add one board, and one theard I have +2 queries.
<?php
if(!defined('USED'))
exit;
# Name of page!
$page = 'Forum';
$db = new Database();
$array = $db -> select("SELECT `id`,`name` FROM `".PREFIX."category`");
if(count($array) > 0)
{
$container .= '';
foreach($array as $category)
{
$container .= '<div class="panel panel-primary" id="category-'.$category['id'].'">
<div class="panel-heading">
<h3 class="panel-title">
'.$category['name'].'
</h3>
</div>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th class="col-md-9">Board Name</th>
<th class="col-md-3">Latest</th>
</tr>
</thead>';
$array2 = $db -> select("SELECT `id`,`id_category`,`name`,`info` FROM `".PREFIX."boards` WHERE `id_category`=".$category['id']."");
if(count($array2) > 0)
{
foreach($array2 as $board)
{
$container .='<tbody>
<tr>
<td>
<strong>'.$board['name'].'</strong><br/>
<small>'.$board['info'].'</small>
</td>';
$array3 = $db -> select("SELECT `id`,`id_board`,`title`,`created_by`,`created_date` FROM `".PREFIX."theards` WHERE `id_board`=".$board['id']." ORDER BY `created_date` DESC LIMIT 1");
if(count($array3) > 0)
{
foreach($array3 as $theards)
{
$array4 = $db -> select("SELECT `id`,`name` FROM `".PREFIX."users` WHERE `id`=".$theards['created_by']."");
foreach($array4 as $user)
{
$created_by = $user['name'];
}
$container .='<td>
'.$theards['title'].'<br/><small>'.$created_by.', <abbr class="timeago" title="'.$theards['created_date'].'">less than a month ago</abbr></small>
</td>';
}
}
else
{
$container .= '<td>
Nothing is here!
</td>';
}
$container .=' </tr>
</tbody>';
}
}
else
{
$container .='<tbody>
<tr>
<td>Nothing is here!</td>
<td>...</td>
</tr>
</tbody>';
}
$container .='</table>
</div>';
}
}
else
{
Site::Error("You need to add a category first!");
}
And my select:
public function select($query) {
$rows = array();
$result = $this -> query($query);
if($result === false) {
return false;
}
while ($row = $result -> fetch_assoc()) {
$rows[] = $row;
}
global $db_count;
$db_count = !isset($db_count) ? 1 : $db_count + 1;
return $rows;
}
Ive added $db_count at the end of the file to check numbers of queries.
Instead of running one query to get a list of IDs, then looping across those IDs to get another set of IDS, then looping across those IDs to get a set of data, how about writing one query, using a JOIN to line up the three tables?

Have a php class return array values and keep looping until end

I'm trying to create a website that allows for easy theme adding/manipulation like wordpress and other CMS systems do. To do this I'd like to make it so the theme file that delivers the content uses as little php code as possible. At the moment this is the (extremely simplified) class
class getparents {
var $parentsarray;
function get_parents() {
$this->parentsarray = array();
$this->parentsarray[] = array('Parent0',3,1);
$this->parentsarray[] = array('Parent1',8,2);
$this->parentsarray[] = array('Parent2',2,3);
return $this->parentsarray;
}
}
And retrieving it like this:
$parents = new getparents();
?><table><?php
foreach($parents->get_parents() as $rowtable)
{
echo "<tr><td>$rowtable[0] has category ID $rowtable[1] and is on level $rowtable[2] </td></tr>";
}
?></table><?php
But I want to make the retrieving more like this:
<table>
<tr><td><?php echo $cat_title; ?> has category ID <?php echo $cat_id; ?> and is on level <?php echo $cat_level; ?> </td></tr>
</table>
Which basically mean the class would just return the value in an understandable way and automatically keep on looping without the user having to add *foreach($parents->get_parents() as $rowtable)* or something similar in their theme file.
Here's an example wordpress page to (hopefully) illustrate what I mean. This page retrieves all posts for the current wordpress category which is what I'm trying to mimic in my script, but instead of retrieving posts I want to retrieve the category's parents, but I don't think it's important to explain that in detail.
<?php
/**
* The template for displaying Category Archive pages.
*
* #package WordPress
* #subpackage Twenty_Ten
* #since Twenty Ten 1.0
*/
get_header(); ?>
<div id="container">
<div id="content" role="main">
<h1 class="page-title"><?php
printf( __( 'Category Archives: %s', 'twentyten' ), '<span>' . single_cat_title( '', false ) . '</span>' );
?></h1>
<?php
$category_description = category_description();
if ( ! empty( $category_description ) )
echo '<div class="archive-meta">' . $category_description . '</div>';
/* Run the loop for the category page to output the posts.
* If you want to overload this in a child theme then include a file
* called loop-category.php and that will be used instead.
*/
get_template_part( 'loop', 'category' );
?>
</div><!-- #content -->
</div><!-- #container -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Note: My actual question doesn't have anything to do with wordpress at all so I didn't add it as a tag.
UPDATE: I think my question may have been unclear. Here's a messy example (that works nevertheless)
index.php
<?php
include_once("class.php");
include_once("config.php");
if(isset($_GET['catid']))
{
$getproducts = new getproducts($_GET['catid']);
$catproductsarray = $getproducts->getarray();
$indexxx = 0;
foreach($catproductsarray as $rowtable)
{
include("templates/$template/all_products.php");
$indexxx++;
}
}
class.php
class getproducts {
var $thearrayset = array();
public function __construct($indexx) {
$this->thearrayset = $this->makearray($indexx);
}
public function get_id($indexxx) {
echo $this->thearrayset[$indexxx]['id'];
}
public function get_catID($indexxx) {
echo $this->thearrayset[$indexxx]['catID'];
}
public function get_product($indexxx) {
echo $this->thearrayset[$indexxx]['name'];
}
public function makearray($indexx) {
$thearray = array();
if(!is_numeric($indexx)){ die("That's not a number, catid."); };
$resulttable = mysql_query("SELECT * FROM products WHERE catID=$indexx");
while($rowtable = mysql_fetch_array($resulttable)){
$thearray[] = $rowtable;
}
return $thearray;
}
public function getarray() {
return $this->thearrayset;
}
}
templates/default/all_products.php
<!-- The below code will repeat itself for every product found -->
<table>
<tr><td><?php $getproducts->get_id($indexxx); ?> </td><td> <?php $getproducts->get_catID($indexxx); ?> </td><td> <?php $getproducts->get_product($indexxx); ?> </td></tr>
</table>
So basically, index.php gets loaded by user after which the amount of products in mysql database is taken from the class. For every product, all_products.php gets called with $indexxx upped by one.
Now the only thing the user has to do is edit the HTML all_products.php and the products will all be displayed differently. This is what I'm going for, but in a clean, responsible way. Not like this, this is a mess!
UPDATE2: I found a better way to do it, but added it as an answer. Seemed more fitting and pevents this question from getting any longer/messyer than it already is.
Ok I'm getting a little bit closer to what I want, so I'm adding this as an answer.
The template:
<?php include("templates/$template/header.php"); ?>
<!-- [product][description][maxchars=##80##][append=##...##] -->
<!-- [categories][parents][name][append= ->] --><!-- maxchars=false means dont cut description -->
<!-- [categories][children][prepend=nothing] --><!-- prepend=nothing means no prepend -->
<div id="middle-left-section">
<table>
{start-loop-categories-parents}
<tr><td><!-- [categories][parents][name] --></td><td>
{end-loop-categories-parents}
</table>
<table>
<tr><td><!-- [categories][current] --></tr></td>
{start-loop-categories}
<tr><td> <!-- [categories][children] --></td><td>
{end-loop-categories}
</table>
</div>
<div id="middle-right-section">
<table id="hor-minimalist-a">
<thead>
<th scope="col"> </th>
<th scope="col">Name</th>
<th scope="col" width="200px">Description</th>
<th scope="col">Price</th>
</thead>
<tbody>
{start-loop-product}
<tr><td><img src="fotos/<!-- [product][thumb] -->"></img></td><td><!-- [product][name] --></td><td><!-- [product][description] --></td><td><!-- [product][price] --></td></tr>
{end-loop-product}
</tbody>
</table>
</div>
<div style="clear: both;"/>
</div>
<?php include("templates/$template/footer.php"); ?>
The class:
<?php
///////////////////////////
//Includes and functions//
/////////////////////////
include_once("config.php");
include_once("includesandfunctions.php");
function get_between($input, $start, $end)
{
$substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
return $substr;
}
function get_between_keepall($input, $start, $end)
{
$substr = substr($input, strlen($start)+strpos($input, $start), (strlen($input) - strpos($input, $end))*(-1));
return $start.$substr.$end;
}
class listproducts {
var $thearrayset = array();
var $file;
var $fp;
var $text;
var $products;
var $productskeepall;
var $done;
var $returnthisloopdone;
public function __construct() {
global $template;
//Get items from mysql database and put in array
$this->thearrayset = $this->makearray();
//Read file
$this->file = "templates/$template/all_products.php";
$this->fp = fopen($this->file,"r");
$this->text = fread($this->fp,filesize($this->file));
//Set other vars
$this->products = '';
$this->productskeepall = '';
$this->returnthisloopdone = '';
$this->done = ''; //Start $done empty
}
public function makearray() {
$thearray = array();
$resulttable = mysql_query("SELECT * FROM products");
while($rowtable = mysql_fetch_array($resulttable)){
$thearray[] = $rowtable; //All items from database to array
}
return $thearray;
}
public function getthumb($indexxx) {
$resulttable = mysql_query("SELECT name FROM mainfoto where productID=$indexxx");
while($rowtable = mysql_fetch_array($resulttable)){
return $rowtable['name']; //Get picture filename that belongs to requested product ID
}
}
public function listproduct()
{
global $template;
$this->products = get_between($this->done,"{start-loop-product}","{end-loop-product}"); //Retrieve what's between starting brackets and ending brackets and cuts out the brackets
$this->productskeepall = get_between_keepall($this->done,"{start-loop-product}","{end-loop-product}"); //Retrieve what's between starting brackets and ending brackets and keeps the brackets intact
$this->returnthisloopdone = ''; //Make loop empty in case it's set elsewhere
for ($indexxx = 0; $indexxx <= count($this->thearrayset) - 1; $indexxx++) //Loop through items in array, for each item replace the HTML comments with the values in the array
{
$this->returnthis = $this->products;
$this->returnthis = str_replace("<!-- [product][thumb] -->", $this->getthumb($this->thearrayset[$indexxx]['id']), $this->returnthis);
$this->returnthis = str_replace("<!-- [product][catid] -->", $this->thearrayset[$indexxx]['catID'], $this->returnthis);
$this->returnthis = str_replace("<!-- [product][name] -->", $this->thearrayset[$indexxx]['name'], $this->returnthis);
preg_match('/(.*)\[product\]\[description\]\[maxchars=##(.*)##\]\[append=##(.*)##\](.*)/', $this->done, $matches); //Check if user wants to cut off description after a certain amount of characters and if we need to append something if we do (like 3 dots or something)
$maxchars = $matches[2];
$appendeez = $matches[3];
if($maxchars == 'false'){ $this->returnthis = str_replace("<!-- [product][description] -->", $this->thearrayset[$indexxx]['description'], $this->returnthis);
}else{ $this->returnthis = str_replace("<!-- [product][description] -->", substr($this->thearrayset[$indexxx]['description'],0,$maxchars).$appendeez, $this->returnthis);
}
$this->returnthis = str_replace("<!-- [product][price] -->", $this->thearrayset[$indexxx]['price'], $this->returnthis);
$this->returnthisloopdone .= $this->returnthis; //Append string_replaced products section for every item in array
}
$this->done = str_replace($this->productskeepall, $this->returnthisloopdone, $this->done);
//Write our complete page to a php file
$myFile = "templates/$template/cache/testfile.php";
$fh = fopen($myFile, 'w') or die("can't open file");
$stringData = $this->done;
fwrite($fh, $stringData);
fclose($fh);
return $myFile; //Return filename so we can include it in whatever page requests it.
}
} //End class
?>
The php requested by the website visitor, which will call the current template's all_products.php
include_once("class.php");
$listproducts = new listproducts();
include_once($listproducts->listproduct());
So what this really is, is just string_replacing the HTML comments in the template file with the PHP result I want there. If it's a loop, I Single out the html code I want to loop -> Start an empty string variable -> Repeat that HTML code, appending each loop to the string variable -> Use this string variable to replace the HTML comment
The newly built page is then written to an actual file, which is then included.
I'm completely new to OOP, so this is pretty elaborate stuff for me. I'd like to know if this is a good way to tackle my problem. And also, is it possible to prevent having to rewrite that entire class for every page?
As an example, if I also wanted to build a guestbook I'd like to rewrite the class in a way that it can accept passed variables and build the page from there, rather than pre-setting alot of stuff limiting it to one 'task' such as retrieving products. But before I go any further I'd like to know if this is an a-okay way to do this.

Codeigniter table Join then Display Tags Problem

I have a problem that concerns blog posts and displaying the tag words from another table.
I seem to be able to pull the info out of the tables fine, however when I try to display the posts and the tags, I get one tag per post. In other words if I have 7 tags for a post, I get 7 iteration's of that post each with one tag instead of 1 post with 7 tags.
My Controller ( do have a question about the $this->db->get(posts, tags) is that correct
$this->db->order_by('posts.id', 'DESC');
$where = "publish";
$this->db->where('status', $where);
$this->db->join('tags', 'tags.post_id = posts.id');
$this->db->limit('7');
$query = $this->db->get('posts', 'tags');
if($query->result())
$data = array();
{
$data['blog'] = $query->result();
}
$data['title'] = 'LemonRose';
$data['content'] = 'home/home_content';
$this->load->view('template1', $data);
The view.
$limit = 5; // how many posts should we show in full?
$i = 1; // count
foreach ($blog as $row):
$permalink = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING'];
$url = CompressURL ("$permalink");
$description = $row->title . $row->post;
$twittermsg = substr($description, 0, 110);
$twittermsg .= "...more " . $url;
if ($i < $limit) // we are under our limit
{ ?>
<div class="titlebox">
<div class="title"><? echo ucwords($row->title); ?></div>
<span><? echo $row->date, nbs(10), $row->author; ?></span>
</div>
<div class="clear"></div>
<? $str = str_word_count($row->post, 0);
if ($str >= 500) {
$row->post = html_entity_decode($row->post);
$row->post = $this->typography->auto_typography($row->post); // display?>
<div class="split"> <? echo $row->post = word_limiter($row->post, 480); ?>
<div class="tags"><? echo $row->tag; ?></div>*** These 3 lines seem to be where I am confused and getting the wrong display
<p><h3>More <?php echo anchor("main/blog_view/$row->id", ucwords($row->title)); ?> </h3></p>
<p>Trackback URL: <? echo base_url() . "trackbacks/track/$row->id"; ?></p>
<!-- tweet me -->
<?echo anchor("http://twitter.com/home?status=$twittermsg", 'Tweet'); ?>
This is my first attempt with join and I have very little experience getting the display with implode, if that is the right way to go.
Thank you in advance.
Try
<div class="tags"><? echo implode(', ', $row->tag); ?></div>
and remove the 2 rows before this one.

Categories