PHP / Codeigniter Nestable List - php

Simple issue for someone to solve I hope, (I have re written this), I have a table with pages each page record has a parent_id I need to output all of the pages nested correctly under their parent page. I have managed to get the output to show two levels but I am now stuck at this point.
The eventual aim is to use JQuery Nestable to allow my user to re-order the pages and set new parents.
EDIT
Controller:
public function navigation() {
if($this->session->userdata('logged_in')) {
$session_data = $this->session->userdata('logged_in');
$data['auid'] = $session_data['user_user_id'];
$data['userName'] = $session_data['user_fullname'];
$data['gravatar'] = gravatar($session_data['user_email'], 30, FALSE);
$pages = $this->admin_m->getAllTopPages();
foreach ($pages as $p) {
$pid = $p->page_id;
$children = $this->admin_m->getAllChildPages($pid);
if($children) {
$p->children = $children;
}
}
$data['pages'] = $pages;
$data['current'] = 'navigation';
$this->load->view('admin/partials/header_v', $data);
$this->load->view('admin/partials/top-bar_v');
$this->load->view('admin/partials/side-bar_v');
$this->load->view('admin/navigation_v');
$this->load->view('admin/partials/footer_v');
} else {
redirect('admin/login', 'refresh');
}
}
Model:
public function getAllTopPages() {
$query = $this->db->get_where('yell_page', array('page_parent_id'=>'-1'));
return $query->result();
}
public function getAllChildPages($pid) {
$this->db->select('page_id, page_name, page_parent_id');
$this->db->from('yell_page');
$this->db->where('page_parent_id =', $pid);
$this->db->where('page_parent_id !=', '-1');
$query = $this->db->get();
return $query->result();
}
View:
<div class="panel-body">
<div class="dd" id="nestable_list_2">
<ol class="dd-list">
<?php
foreach($pages as $p) {
echo '<li class="dd-item" data-id="'.$p->page_id.'">';
echo '<div class="dd-handle">'.$p->page_name.'</div>';
echo '<ol class="dd-list">';
if(isset($p->children)) {
foreach($p->children as $obj) {
echo '<li class="dd-item" data-id="'.$obj->page_id.'"><div class="dd-handle">'.$obj->page_name.'</div></li>';
}
}
echo '</ol>';
echo '</li>';
}
?>
</ol>
</div>
</div>
I am getting somewhat closer but now the issue is that I only get data on two levels this could potentially be many more.

Related

CI Pagination Back to Posts Link

I'm learning CI and latest I've been tasked to do is pagination. So I followed this tutorial as it seemed relatively nicely made and explained. Link
The pagination works and its great. Now I wanted to make a read more under each post, making each post open separately with its full description. That also works, but when I click a link to go back to the pagination index, the list starts from the beginning, no matter which post I clicked. I'm not sure how to add the page I want the return link to take me back so I'll just post this here and hopefully it won't be too hard for someone to tell me.
If someone is confused what I'm after, just look at the last view readmore_paginate. In it, the last link should contain a number back
to the page, but idk how to put or what to put there.
Controller
public function paginate()
{
$config = array();
$config['base_url'] = base_url()."welcome/paginate";
$config['total_rows'] = $this->blog_model->countPosts();
$config['per_page'] = 2;
$config['uri_segment'] = 3;
$this->pagination->initialize($config);
$page = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0; //TERNARY OPERATOR (? = TRUE) (: = FALSE)
$data['results'] = $this->blog_model->fetchPosts($config['per_page'], $page);
$data['links'] = $this->pagination->create_links();
$this->load->view('header');
$this->load->view("p_content", $data);
$this->load->view('footer');
}
public function readMore_Paginate()
{
$id = $this->input->get('postid');
$data['post'] = $this->blog_model->getSpecificPost($id);
$this->load->view('header');
$this->load->view('readmore_paginate', $data);
$this->load->view('footer');
}
Model
public function countPosts()
{
return $this->db->count_all("Blogposts");
}
public function fetchPosts($limit, $start)
{
$this->db->select('*');
$this->db->from('Blogposts');
$this->db->join('Blogcategories', 'Blogposts.postcatid=Blogcategories.id');
$this->db->limit($limit, $start);
$query = $this->db->get();
if($query->num_rows() > 0)
{
foreach ($query->result() as $row) {
$data[] = $row;
}
return $data;
}
return false;
}
View p_content
<div class="col-md-8">
<table class="table">
<tbody>
<?php
foreach ($results as $key) {
echo "<tr><th><h2><kbd><font color='yellow'>".$key->postname."</font></kbd></h2><kbd><font color='lime'>".date("d M Y",strtotime($key->postdate))."</font></kbd> <kbd><font color='cyan'>".$key->catname."</font></kbd></th></tr>";
echo "<tr><td><blockquote>".mb_substr($key->postdesc, 0,80,'UTF-8')."...";?>
read more</blockquote>
<?php } ?>
</tbody>
</table>
<p><?php echo $links; ?></p>
</div>
View readmore_paginate
<div class="col-md-8">
<table class="table">
<tbody>
<?php
foreach ($post as $key) {
echo "<tr><th><h2><kbd><font color='yellow'>".$key['postname'].
"</font></kbd></h2><kbd><font color='lime'>".
date("d M Y",strtotime($key['postdate']))."
</font></kbd> <kbd><font color='cyan'>".
$key['catname']."</font></kbd></th></tr>";
echo "<tr><td><blockquote>".$key['postdesc']."</blockquote>"; ?>
Back to Posts
<?php }
?>
</tbody>
</table>
</div>
Controller
$page = $this->input->get('page') ?
$this->input->get('page') :
$this->uri->segment(3) ?
$this->uri->segment(3) :
0;
$data['results'] = $this->blog_model->fetchPosts($config['per_page'], $page);
$data['links'] = $this->pagination->create_links();
$data['page'] = $page; // add this
view p_content
read more</blockquote>
view readmore_paginate
Back to Posts

How to make pagination with Database category codeigniter?

I am new at codeigniter. I have a problem with codeigniter's pagination.
I tried to search google, youtube and codeigniter documentation but I didn't find anything.
I can implement a simple pagination but I need to create multi pagination with a database in one table.
Anyone that can help me please?
My database:
product:
id category title image
1 burger a a.jpg
2 burger b b.jpg
3 burger c c.jpg
4 pizza d d.jpg
5 pizza e e.jpg
6 pizza f f.jpg
The result that I want is pagination in one page
(pagination category burger by burger,pizza by pizza)
and my url is http://localhost/test-ci1/
Code in Model:
<?php
class Product_model extends CI_Model {
function get_burgers($category="", $limit, $start) {
$this->db->select('*');
$this->db->from('product');
if($category) {
$this->db->where('category',$category);
}
$this->db->limit($limit, $start);
$query = $this->db->get();
return $query->result();
}
function get_total($category="") {
$this->db->select('count(*) AS num_row');
$this->db->from('product');
if($category) {
$this->db->where('category',$category);
}
$this->db->limit(1);
$query = $this->db->get();
return $query->row()->num_row;
}
}
in the Controller:
<?php
class Site extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('product_model','product');
}
public function index()
{
$this->load->model('Product_model');
$page = ($this->uri->segment(3)) ? $this->uri->segment(3) : 0;
$data = array();
$per_page =2;
$data["pizza"] = $this->product->get_burgers('pizza', $per_page, $page);
$total_pizza = $this->product->get_total('pizza');
$limit= 2;
$link_pizza = 'http://localhost/test-ci1/pizza';
$data['pagination_pizza'] = $this->pagination($total_pizza,$limit,$link_pizza);
$data["burgers"] = $this->product->get_burgers('burger', $per_page, $page);
$total_burger = $this->product->get_total('burger');
$limit = 2;
$link_burger = 'http://localhost/test-ci1/index/burger';
$data['pagination_burger'] = $this->pagination($total_burger,$limit,$link_burger);
$this->load->view('home_page_view',$data);
}
private function pagination($total ,$per_page ,$link) {
$config['base_url'] = $link;
$config['total_rows'] = $total;
$config['per_page'] = $per_page;
$config['page_query_string'] = TRUE;
$this->pagination->initialize($config);
return $this->pagination->create_links();
}
}
and in my View:
<body>
<h1>Pizza</h1>
<ul>
<?php foreach($pizza as $val) { ?>
<li><?php echo $val->title; ?></li>
<?php } ?>
</ul>
<?php echo $pagination_pizza; ?>
<hr>
<h1>Burger</h1>
<ul>
<?php foreach($burgers as $val) { ?>
<li><?php echo $val->title; ?></li>
<?php } ?>
</ul>
<?php echo $pagination_burger; ?>
</body>
and my result:
Pizza
pizza1
burger2
12>
Burger
burger1
assasa
12>
As I can see you haven't developed your model pagination. You should add a function that does the pagination for you while extracting only the wanted rows from the database.
For your example something like this in your model will do:
function get_burgers($category="", $limit, $start) {
$this->db->select('*');
$this->db->from('product');
if($category) {
$this->db->where('category',$category);
}
$this->db->limit($limit, $start);
$query = $this->db->get();
return $query->result();
}
And in your controller instead of fetching just one burger you should
$data["burgers"] = $this->burger_model->get_burgers($category, $config["per_page"], $page);
And change your foreach in your view to iterate through the burgers

Can not save view as a variable to be used in template

I am trying to call a model from my controller, which in turn generates data from a view, saves it as content and returns it to the controller, which then adds it to a template I have.
Whats happening is that $content = $this->load->view('left/profile', $c_data); is printing the data instead of saving it in variable $content
Here is my code:
Controller:
function index($page = '1-Welcome to')
{
if (!$this->tank_auth->is_logged_in()) {
//display non-login page
redirect('/auth/login/');
} else {
//user information
$user['user_id'] = $this->tank_auth->get_user_id();
$user['username'] = $this->tank_auth->get_username();
//general page data
$main['title'] = $this->page_model->make_title(ucfirst($page));
//template data
$template['head'] = $this->load->view('templates/head', $main, TRUE);
//get left content
$c_data['make_profile'] = $this->left_model->make_profile($user);
//combine into one variable
$data['template'] = $template;
$data['page'] = $page;
$data['user'] = $user;
$data['left'] = $c_data;
print_r($data);
$this->load->view('main_template', $data);
}
}
Focus on $c_data['make_profile'] = $this->left_model->make_profile($user);
Here is make_profile
public function make_profile($user)
{
$user_id = $user['user_id'];
$query = $this->db->query(" SELECT location FROM user_profiles AS up
INNER JOIN avatars AS a
ON up.avatar_id = a.id
WHERE user_id='$user_id'");
$c_data['avatar_loc'] = $query->row_array();
$content = $this->load->view('left/profile', $c_data);
$content .= "hello";
return $content;
}
And here is my profile view:
<div id="profile">
<div id='avatar'><img src="<?php echo $avatar_loc['location'] ?>" alt="avatar_user"/></div>
<div id="profile_pop"></div>
</div>
Any idea why it isn't working? Thanks
Return the data from the view as a string:
$this->load->view('left/profile', $c_data, TRUE);
Read here (bottom of the page).

How to make a php function contain mysql commands

I want to create a simple menu function which can call it example get_menu()
Here is my current code.
<?php
$select = 'SELECT * FROM pages';
$query = $db->rq($select);
while ($page = $db->fetch($query)) {
$id = $page['id'];
$title = $page['title'];
?>
<?php echo $title; ?>
<?php } ?>
How to do that in?
function get_menu() {
}
Let me know.
Here is the function for that:
function get_menu(&$db)
{
$select = 'SELECT * FROM pages';
$query = $db->rq($select);
$menu = '';
while ($page = $db->fetch($query)) {
$id = $page['id'];
$title = $page['title'];
$menu .= '<a href="page.php?id=' . $id . '" &title="' . $title .'></a>'
}
return $menu;
}
.
Some Quick Corrections In Your Script:
You were missing = after id
You were missing & after title
Suggestion:
You can give your menu links a class and style as per your menu needs :)
get_menu() has to get reference to $db somehow. Probably the best and easiest way is to pass that reference as parameter:
function get_menu(MyDatabaseHandler $db) {
// code proposed by Sarfraz here
}
now here you already have a mistake:
<?php echo $title; ?>
notice the = after id
you can't be too careful
First, separate the part where you're doing something, and the one used to display things.
Second, the alternative syntax looks better for the display part.
<?php
function get_menu(){
$items = array();
$select = 'SELECT * FROM pages';
$query = $db->rq($select);
while ($page = $db->fetch($query)) {
$items[] = $page['id'];
}
return $items;
}
$menuItems = get_menu();
?>
<ul>
<?php foreach($menuItems as $item): ?>
<li><?php echo $item['title']; ?></li>
<?php endforeach;?>
</ul>
The code Sarfraz posted is going to create invalid anchor tags (i.e. links). They'll also be missing names. Here is the shorter/faster version:
function get_menu($db)
{
$result = $db->rq('SELECT id,title FROM pages');
$menu = '';
while ($page = $db->fetch($result))
{
$id = $page['id'];
$title = $page['title'];
$menu .= "<a href='page.php?id={$id}&title={$title}'>{$title}</a>\n";
}
return $menu;
}
To use that do this:
echo get_menu($db);
The error you were getting was probably resulting from not passing the database connection to the function.
NOTE: It's generally not a good idea to show database ID numbers to the user in the interest of security; slugs are much better for identifying pages and are SEO friendly. Also, there shouldn't be any need to pass the page title to page.php because if you've got the ID you can get that when you need it from the database. Here's the code with this in mind:
function get_menu($db)
{
$result = $db->rq('SELECT id,title FROM pages');
$menu = '';
while ($page = $db->fetch($result))
{
$menu .= "<a href='page.php?id={$page['id']}'>{$page['title']}</a>\n";
}
return $menu;
}
just put function get_menu() { above your code and } below
or like this??
function get_menu( $title, $id ) {
$menu = '';
$menu .= '<a href="page.php?id' . $id . '" title="' . $title .'></a>'
echo $menu;
}
------------------------
$select = 'SELECT * FROM pages';
$query = $db->rq($select);
while ($page = $db->fetch($query)) {
$id = $page['id'];
$title = $page['title'];
get_menu($title, $id );
}
function getMenu()
{
$select = 'SELECT FROM pages';
$query = $db->rq($select);
$menu = new Array;
while ($page = $db->fetch($query)) {
$menu[] = '';
}
return $menu;
}

Populating accordion with database results help

I am building a system in which the user can build thre own navigation menu from a selection of catergories, the way it works is that is they click on 'Blog' they they can get an accordion titled 'Blog' and on expanding this they see all the blog titles, however as the moment, my application creates multiple accordions if there are multiple blog entries, so at the moment i have two blog entries and when the user slects 'Blog' they get to accordions, where as they should get one with all the titles in
Controller:
public function category($content_id) {
//$this->output->enable_profiler(TRUE);
if (intval($this->uri->segments[4])){
$content_id = $this->uri->segments[4];
} else {
$content_id = $this->uri->segments[7];
}
$data['content'] = $this->site_model->get_content($content_id);
$this->load->view("call", $data);
}
Model:
public function get_content($content_id) {
$this->db->select('*');
$this->db->from ('content');
$this->db->join('categories', 'categories.category_id = content.categories_category_id', 'left');
$this->db->where ('categories_category_id', $content_id);
$query = $this->db->get();
return $query->result_array();
}
View:
<?php
if(isset($content)) {
// var_dump($content);
foreach($content as $row) {
echo "<h2 class='$row[category_name]'><a href='#'>$row[category_name]</a></h2>";
echo "<div class='$row[category_name]'><a href='index.php/home/get_content/$row[content_id]' class='contentlink'>$row[content_title]</a></div>";
}
}
?>
How can I alter my code so for category the user selects only one accordion gets built put all the categories realted content is placed in that accordion?
Hope this makes sense.
If I understand correctly you should move the creation of the header out of your loop:
<?php
if(isset($content)) {
echo "<h2 class='$category_name'><a href='#'>$category_name</a></h2>";
foreach($content as $row) {
echo "<div class='$row[category_name]'><a href='index.php/home/get_content/$row[content_id]' class='contentlink'>$row[content_title]</a></div>";
}
}
?>
If you don't know the category name you could try something like this:
<?php
$first = true;
if(isset($content)) {
echo "<h2 class='$category_name'><a href='#'>$category_name</a></h2>";
foreach($content as $row) {
if ($first) {
echo "<h2 class='$row[category_name]'><a href='#'>$row[category_name]</a></h2>";
$first = false;
}
echo "<div class='$row[category_name]'><a href='index.php/home/get_content/$row[content_id]' class='contentlink'>$row[content_title]</a></div>";
}
}
?>

Categories