codeigniter how to restrict number of url segments in a page - php

I am having a codeigniter function that does searching which is working fine but the issues arises when I am making a new search on a single page whereby on clicking search button the same url of the single page duplicates on the url bar thus taking me to a wrong link. see how it behaves in the below snippets;
http://localhost/newsapp/bulletins/view/31
http://localhost/newsapp/bulletins/view/view/31
http://localhost/newsapp/bulletins/view/view/view/31
http://localhost/newsapp/bulletins/view/view/view/view/31
here are the functionss;
public function livesearch() {
$keyword = $this->input->post('keyword');
$query = $this->news_model->get_live_items($keyword);
foreach ($query as $row):
echo "<li><a href='view/$row->id'>" . $row->title . "</a></li>";
endforeach;
}
This one displays the search results in a another page:
public function search_keyword()
{
$keyword = $this->input->post('keyword');
$data['results'] =$this->news_model->get_live_items($keyword);
$data["top_news"] = $this->news_model->topnews();
$data["latest_news"] = $this->news_model->latestnews();
$this->load->view('result_view',$data);
}
finally this where all the magics are happening;
function view($id)
{
$data['news'] = $this->news_model->get_one_news($id);
$data["top_news"] = $this->news_model->topnews();
$data["latest_news"] = $this->news_model->latestnews();
$data['content'] = 'single'; // template part
$this->load->view('includes/template',$data);
}

Your livesearch method should be
public function livesearch() {
$keyword = $this->input->post('keyword');
$query = $this->news_model->get_live_items($keyword);
foreach ($query as $row):
echo "<li><a href='" . base_url('bulletins/view/' . $row->id) . "'>" . $row->title . "</a></li>";
endforeach;
}

Try giving a full link like this
echo "<li><a href='".base_url()."view/$row->id'>" . $row->title . "</a></li>";
You are just including the view/$row->id so it is adding the url rather than generating the required url.

Related

function only returns one value multiple times

I have this function:
function get_content($text_to_match) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
But when I call it like:
<div>
<?php
for ($i = 1; $i < count(get_content("text_to_match")); $i++) {
echo '<article>' .
'<h3>' . get_content("text_to_match")["string1"] . '</h3>'.
'<p>' . get_content("text_to_match")["string2"] . '</p>' .
'</article>';
}
?>
</div>
I only get the first match in the DB repeated as many times as the number of found items.
Where have I gone wrong?
use this code then fetch data properly
while($content = mysql_fetch_array($cont))
{
return $content;
}
Your logic is at fault. You are calling get_content function to get all matches for the loop, as well as to get individual elements out of the list. This is:
bad logic - the 2nd use case doesn't make sense
excessive - you shouldn't need to run a database query just to output an already retrieved result
What you probably want to do is:
foreach (get_content('text_to_match') as $content) {
echo '<article>';
echo '<h3>' . $content['string1'] . '</h3>';
echo '<p>' . $content['string2'] . '</p>';
echo '</article>';
}
With a few modifications in combination with tips from #Anant and #Unix One's answer, I arrived at this working solution:
Function definition
function get_content($text_to_match, $multiple=false) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if ($multiple) {
$content_array = [];
while($content = mysqli_fetch_array($cont)) {
$content_array[] = $content;
}
return $content_array;
} else {
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
}
Function calls
<?php
/* multiple items */
foreach(get_content("text_to_match", true) as $content) {
echo '<article>' .
'<h3>' . $content["string1"] . '</h3>' .
'<p>' . $content["string2"] . '</p>' .
'</article>';
}
?>
<?php
/* one item */
echo get_content("text_to_match")["string"];
?>

join query with bonfire (codeigniter)

I'm trying to do a join query in bonfire (which is great for the beginner i am btw)
I first tried to set a public function in the method, but after a while, i though it would be better to put it in the controller (maybe i'm wrong...?)
However, i guess my join request is valid, but i can't get it in my view...
Here is my controller:
class Patient extends Admin_Controller {
public function __construct() {
parent::__construct();
$this->load->model('post_model');
Template::set_block('search/search', 'search/search');
//Template::set('toolbar_title', 'Manage Your Blog');
Template::set_theme('custom', 'default');
Template::set_block('nav', 'nav');
}
public function detail($id = null) {
$this->load->helper('typography');
$this->load->model('operation_model');
$this->db->select('*');
//$this->db->from ('operation AS ope');
$this->db->from('operation');
$this->db->join('patient', "patient.zkp_pat = operation.zkf_pat ");
$query = $this->db->get();
$post = $this->post_model->find($id);
//Template::set('post', $query);
Template::set('post', $post);
Template::set_view('detail');
Template::render();
}
}
And my view file:
<code>
<div class="post">
<?php
echo ($post->nom . ' ');
echo ($post->prenom . ' ');
echo ($post->zkp_pat . ' ');
echo ($post->dob);
foreach ($query as $row) :
echo ($row->zkf_pat . ' ' );
echo "titre de l'opération: " . ($row->titre);
endforeach;
?>
</div>
</code>
Thanks for your advices and help !
I asked for help on the BF forum too, and somebody gave me the solution=>hopefully this will help somebody else. The issue was with the $query , which is a DB_result object.
http://www.codeigniter.com/user_guide/database/query_builder.html#selecting-data
to solve the problem i had to doo: $query->result()
Final code:
Controller:
public function detail ($id = null){
$this->load->helper('typography');
$this->db->from ('operation as ope');
$this->db->join ('patient',
"patient.zkp_pat = ope.zkf_pat " );
$this->db->where ('patient.zkp_pat', $id);
$query = $this->db->get();
$post = $this->post_model->find($id);
Template::set('query', $query);
Template::set('post', $post);
Template::set_view('detail');
Template::render()
}
And view file:
<div class="post">
<h2><?php e($post->nom); ?></h2>
<?php
echo ($post->nom . ' '); echo ($post->prenom . ' ');
echo($post->zkp_pat . ' ');
echo ($post->dob);
foreach ($query->result() as $row) :
echo '<div>'
echo " \n";
echo ($row->zkf_pat . ' ');
echo "titre de l'opération: " . ($row->titre);
?>
</div>
<?php
endforeach;
?>
</div>
$query->get()->result() returns an object with all fetched data,
whereas $query->get()->row()returns only a single result row, if the result has one row, it returns only the first one. The result is given as an object...
If you like my edit, please upvote, that would be very helpful !

CodeIgniter appending to the beginning of the view when it shouldn't be

When I call regularDashboard(), it appends to the beginning of my view. In my view I'm calling $reg from inside a formatted style. So it shouldn't be echoing out at the beginning of the view... Any ideas as to why this is happening?
public function dcr() {
// pass all dashboard accesses through this function
$username = $this->session->userdata("username");
$query = $this->db->get_where('users', array('username' => $username));
$userType = $this->session->userdata('userType');
if ($userType == 'regular') {
foreach ($query->result() as $row) {
$data = array('reg' => $this->regularDashboard(), 'firstname' => $row->firstname);
$this->load->view('dashboard', $data);
} public function regularDashboard () {
$userid = $this->session->userdata('userid');
$results = $this->db->query("SELECT * FROM users");
foreach ($results->result() as $row) {
if($userid != $row->userid) {
echo $row->firstname . " " . $row->lastname;
echo "<form method='GET' action='processing/lib/process-send-friend-request.php?'>";
echo '<input name="accepted" type="submit" value="Send User Request" /><br />';
echo '<input name="AddedMessage" placeholder="Add a message?" type="textbox" />';
echo '<br>Select Friend Type: ' . '<br />Full: ';
echo '<input name="full_friend" type="checkbox"';
echo '<input type="hidden" name="id" value="' . $row->idusers . '" />';
echo '</form>';
echo "<br /><hr />";
} elseif ($userid == $row->userid) {
echo $row->firstname . " " . $row->lastname;
echo "<br />";
echo "You all are currently friends";
}
}
}
Views are buffered. When you echo something directly in a controller, it is sent before the buffer is flushed (therefore before the output containing the view is sent to the browser), that's why it appears before anything.
You shouldn't to this (sending a direct output/echoing something outside of views), you risk getting into troubles as soon as you use anything related to headers (redirect, cookies, CI's sessions...)
UPDATE:
To fix it, just assign all those string to a variable (as jeff showed), and send that to the view:
$data['form'] = $row->firstname . " " . $row->lastname;
$data['form'] .= "<form method='GET' action='processing/lib/process-send-friend-request.php?'>";
$this->load->view('formview',$data);
There, you just echo $form and you'll have all your strings output correctly.
EDIT :
all above if you're inside a Controller. If you're in a Model, just assign everything to a variable and return it to the Controller:
function regularDashboard()
{
$form = $row->firstname . " " . $row->lastname;
$form .= "<form method='GET' action='processing/lib/process-send-friend-request.php?'>";
return $form;
}
In the controller:
$data['form'] = $this->model->regularDashboard();
$this->load->view('formview',$data);
If you allow me, I'd suggest writing the form directly into the view, without the hassle (and the structural error) of creating something that's supposed to be "presentation" outdside of views.
It seems that your issue is the use of echo from within regularDashboard(). Try setting a variable that contains the form markup and return it instead of using echo.
Here is an example:
function regularDashboard()
{
$html = "";
$html .= "<form>";
//Append the rest of the form markup here
return $html;
}

changing colors when link is clicked

If I have a menu set up in the header which I use for most of my pages as "include/header.php" how do I setup so when I click on a link, it goes to that page, and that link changes colors (and shows as active)? Would jquery be good? or PHP?
Thanks!
You could use PHP to add a class to the current button by comparing it's URL, and the current page URL from $_GET. Without knowing what your URL structure is like, I can't say much more than that.
For example, using an array with button text and URLs:
$links = array('Home' => 'home', 'About' => 'about');
foreach($links as $text => $page)
{
if($_GET['page'] == $page)
{
echo '' . $text . '';
}
else
{
echo '<a href="/index.php?page=' . $page . '>' . $text . '</a>';
}
}
This code will add a class of current to the button who's page matches the value in $_GET. This might not exactly fit your needs due to you probably having a different URL structure, among other things, but it gives a basic explanation and example of how to do this.
Use php, you could write a function before your include like so,
function activeLink ($page) {
if ($page = 'home') echo ' class="active"';
elseif ($page = 'about') echo ' class="active"';
elseif ($page = 'posts') echo ' class="active"';
}
And in your header file,
echo '<a href="#"' . activeLink($page) . '>Home</a>
<a href="#"' . activeLink($page) . '>About</a>
<a href="#"' . activeLink($page) . '>Posts</a>';
And on your actual page;
$page = 'home';
include('header');
This will do the trick.

Dynamic Background images advice

I am creating a site where users can upload there own background images, after upload they see each background they uploaded in a menu represented by a number, clicking on the number will in theory load in the new background, however I have noticed that does this calls in the view again as well (the view is already loaded from another function, is there a ways I can pass the data to the view without loading the view, can I do it with ajax? if so how?
My code currently
public function set_background() {
$this->load->model('image_model');
if($query = $this->image_model->get_background_by_id($this->uri->segments[3])) {
if($query) {
$data['new_background'] = $query;
}
}
$this->load->view('template/background-select', $data);
}
My Model:
public function get_background_by_id($background_id) {
$this->db->select('background_name');
$this->db->from('background');
$this->db->where('background_id', $background_id);
$query = $this->db->get();
return $query->result_array();
}
My View
<div id="background-select">
<?php
$count = 0;
if(isset($special)) {
foreach ($special as $row) {
$count ++;
print '<div class="select">';
print "<a class='background_btn' href='index.php/home/set_background/".$row['background_id']."'>$count</a>";
print '</div>';
if($count == 1) {
$background = $row['background_name'];
}
}
}
if(isset($generic)) {
foreach ($generic as $row) {
$count ++;
print '<div class="select">';
print "<a class='background_btn' href='index.php/home/set_background/".$row['background_id']."'>$count</a>";
print '</div>';
if($count == 1) {
$background = $row['background_name'];
}
}
}
if(isset($user_background)) {
foreach ($user_background as $row) {
$count ++;
print '<div class="select">';
print "<a class='background_btn' href='index.php/home/set_background/".$row['background_id']."'>$count</a>";
print '</div>';
if($count == 1) {
$background = $row['background_name'];
}
}
}
?>
</div>
<div id="wrapper" style=<?php echo"background:url(/media/uploads/backgrounds/".$background.");";?>>
The view gets loaded in originally here
public function index() {
// $this->output->enable_profiler(TRUE);
$data = array();
if($query = $this->category_model->get_all_online()) {
$data['main_menu'] = $query;
}
$this->load->model('image_model');
/*
* Sort out the users backgrounds, basically do a check to see if there is a 'special' background
* if there is not a 'special' background then IF the user is logged in and has a background of there
* own show that one, if not show a generic one, if they are not logged in show a bang one
*/
$image = array();
if ($query = $this->image_model->get_special_backgrounds()) {
$image['special'] = $query;
} elseif(!isset($image['special']) && !isset($this->session->userdata['user_id'])) {
if($query = $this->image_model->get_bang_background()) {
$image['generic'] = $query;
}
}
if(isset($this->session->userdata['user_id'])) {
if($query = $this->image_model->get_user_backgrounds($this->session->userdata['user_id'])) {
$image['user_background'] = $query;
}
}
$data = array_merge($data, $image);
$this->load->view('home/main_page.php', array_merge($data, $image));
}
Hope some can help thanks
This may be too much 'out of the box' and not faithful enough to your code to be useful, but here goes:
Given the description of what the code is supposed to do, you could always have your PHP output the list of background images into a JavaScript snippet on the view (To pseudocode very roughly: <script><?php echo phpArrayToJavaScriptArray($images, $varName); ?></script>), then have javascript dynamically create your list of background-changing links client-side and each click just change the background image with JavaScript (<a href="javascript:changeBackgroundImage('url')"> setting document.getElementById('wrapper')'s background image).
No Ajax necessary.
With that concept in mind, the simplest adjustment to your code I can concot in a hurry is this:
Instead of passing the IDs to the view, pass the URLs to the view (you'd have to adjust your querying accordingly, of course), and change:
"<a
class='background_btn'
href='index.php/home/set_background/" . $row['background_id'] . "'>"
. $count
. "</a>"
to something like
"<a
class='background_btn'
href=\"javascript:changeBackgroundImage('"
. htmlspecialchars($row['background_url'], ENT_QUOTES, 'utf-8')
. "')\">"
. $count
. "</a>"
The JavaScript function would be something like this:
<script language="javascript">
function changeBackgroundImage(url) {
var wrapper = document.getElementById('wrapper');
wrapper.style = "background-image:url(" + url + ")";
}
</script>
Mind, the lot of that is still pseudocode, I doubt it'll run out of the box, my JS is very rusty, and this is meant to be an idea-share more than an outright fix. :) But I hope that it'll help you tackle your issue!
Is that kind of approach feasible for you?

Categories