I have a Model for Groups and another model for Notes (Notes and Posts are same things).
NotesController:
public function groupnotes()
{
if (!empty($this->data))
{
$data = $this->data;
$data['Note']['user_id'] = $this->Auth->user('id');
if ($this->Note->save($data))
{
PROBLEM HERE
}
}
if(empty($this->data['Note']['notes']))
{
PROBLEM HERE
}
GroupsController: (ViewCourse is used to view each group )
public function viewcourse($id=NULL)
{
$this->set('viewcourse', $this->Group->read(NULL,$id));
$this->set('course', $this->Group->find('all', array('conditions'=>array('Group.id'=>$id))));
}
Now when i create a post in a group it redirects me to "groupnotes" action and i want it to redirect me to viewcourse/id ... I am a bit confused how can i redirect the page to viewcourse/id ...
I tried doing it by adding this to groupnotes action
$this->redirect(array('controller'=>'groups', 'action' => 'viewcourse'));
but here i do not have the id.
What do you suggest?
This question might help you: What is the equivalent to getLastInsertId() in Cakephp?
$this->redirect(array(
'controller'=>'groups',
'action' => 'viewcourse/'.$this->Group->getLastInsertId())
);
EDIT:
I have only suggested that you go to the last inserted id of a group as a suggestion. Your question is a bit vague when you say "but here i do not have the id."
1. are you looking to go to any valid course id?
2. last entered course?
3. first entered course id?
Alternatively you could set a default course in your controller like so...
public function viewcourse($id=NULL)
{
if(!$id){
$id = $this->Group->find('first');
$id = $id['Group']['id'];
}
$this->set('viewcourse', $this->Group->read(NULL,$id));
$this->set('course', $this->Group->find('all', array('conditions'=>array('Group.id'=>$id))));
}
NOTE: Just a tip,
$this->set('course', $this->Group->find('all', array('conditions'=>array('Group.id'=>$id))));
Can be substituted with
$this->set('course', $this->Group->findById($id));
To make your code a bit leaner
Related
So I got a little problem. I'm currently learning how to handle laravel. I was okay until now. I`ve tried to create a small page. 4 Articles, 1 Basket, when I click a button, I just hand over the id and the name of the article via $_GET and put it into the basket. This is the controller i have for now:
class FileviewController extends BaseController {
protected $layout = "layouts.master";
public function getIndex() {
if(isset($_GET["article"])) {
Session::push("basket.items", filter_var($_GET["article"]));
$items = Session::all();
}
$articles = Article::with('manufacturer')->get();
}
$articles = Article::with('manufacturer')->get();
$this->layout->content = View::make("article.index", array("items" => $items, "articles" => $articles));
}
At first ive tried to use header() and redirect him on the current page without the parameeter ... didnt work for some reason:
if(isset($_GET["article_id"])) {
Session::push("basket.item_id", filter_var($_GET["article_id"]));
Session::push("basket.item_name", filter_var($_GET["article_name"]));
$items = Session::all();
$articles = Article::with('manufacturer')->get();
header('Location: http://10.36.155.40/laravel/public/article');
}
Didn't work out. Is there any other way to remove the variables from the URL after they have been processed? Because even if the user reloads, the variable is still there and will be added to the basket again. For obvious reasons, i have to avoid that.
I guess i just cant see the forest because of all the trees. Is there even an easier way to do that?
Any help is appreciated. :)
You should just redirect them using Laravels Redirect facade. Gone are the days of setting Location headers! Full docs located here. Here are a few examples:
return Redirect::to('/');
return Redirect::route('my.named.route');
return Redirect::back()->with('errorMessage', 'Get out of here!');
Here's my route :
Route::get('location/{id}/{title?}', array('as' => 'scouting_single', 'uses' => 'ScoutingController#get_single'));
The class is simple:
public function get_single($id, $title ='') {
$location = new Location;
if(is_numeric($id)) {
$location = $location->find($id);
if(isset($location)) {
$author = User::find($location->author);
$meta = $location->find($id)->metakeywords;
if($title == '') {
$slug = Str::slug($location->title);
return Redirect::to('location/'.$id.'/'.$slug);
}
return View::make('scoutingviews.view')->with('pagetitle', 'Location view')
->with('location', Location::find($id))
->with('author', $author)
->with('meta', $meta);
} else {
return Redirect::to('/')->with('message', 'That record is not available');
}
} else {
return Redirect::to('404');
}
}
Everything seems to work fine but after searching around it seems that others are doing it differently like saving the slugs to db, but I just want to include the id to the url... and make it optional to include the title slug. If the user removes the slug, it will redirect the user with the slug anyways.
I'm still learning laravel so please forgive the newbie question with regards to seo-friendliness, I just don't want /{id}/ and /{id}/{title} to count as duplicates
If you are worried about SEO, then having a URL slug in the database is the way to go. Having the ID in the URL isn't very helpful to search engines or users. This should also simplify your code as well. In addition to that, you should take a look at Eloquent relationships where you can attach your users to locations. Instead of having
$author = User::find($location->author);
You could have
$author = $location->author;
The relationship would be a User hasMany Locations, and Location belongsTo User. This is also assuming that users can have many locations.
I want to have a delete button underneath blogs entered just by the owner of the current profile, I have tried implementing a deleteMyBlog function but no joy so far. whats the best way to go about this?
Here is my view. I know I would need but some delete button here but I'm not sure how to fit around my current foreach loop:
<?foreach($blogs AS $viewData):
$delete = $viewData['id'];
{
$id = $viewData->id;
$title = $viewData->title;
$body = $viewData->body;
$username = $viewData->username;
$date = $viewData->date;
?>
<b> <?=$title?></b>
<p><?=$body?></p>
<p>posted by:<?=$username?></p>
<p>date: <?=$date?></p>
<?=anchor("blog/deleteMyBlog/$delete", 'delete')?>
<hr>
<?
}
?>
My model:
class Blogmodel extends CI_Model
{
public function __construct()
{
parent::__construct();
}
function deleteMyBlog($id)
{
$this->db->where(array('id' => $id));
$this->db->delete('blogs');
}
public function get_last_ten_entries()
{
$query = $this->db->get('blogs', 10);
return $query->result();
}
public function insert_entry()
{
$this->title = $this->input->post('title');
$this->body = $this->input->post('text');
$this->username = $this->session->userdata('username');
$this->date = date("Y-m-d");
$this->db->insert('blogs', $this);
}
}
Controller:
class Blog extends CI_Controller {
public function _construct()
{
parent::__construct();
$this->load->model('Blogmodel','Blog');
$this->load->model("profiles");
}
function deleteMyBlog($id) {
$this->blogs->deleteBlog($id);
redirect('blog');
}
public function index()
{
$username = $this->session->userdata('username');
$viewData['username'] = $username;
$this->load->model('Blogmodel');
if($this->input->post('act') =='create_post')
{
$this->Blogmodel->insert_entry();
}
$viewData['blogs'] = $this->Blogmodel->get_last_ten_entries();
$this->load->view('shared/header');
$this->load->view('blog/blogtitle', $viewData);
$this->load->view('shared/nav');
$this->load->helper('form');// Load the form helper.
// Lets set the stuff that will be getting pushed forward...
$data = array();
$data['form_open']=form_open();
$data['form_title'] = form_input(array('name' => 'title'));
$data['form_text'] = form_textarea(array('name' => 'text'));
$data['form_hidden'] = form_hidden('act','create_post');
$data['form_submit'] = form_submit('submit','Make Post');
$this->load->view('blog/blogview');
$this->load->view('blog/post', $data);
$this->load->view('shared/footer');
}
}
Thanks again guys
Simplest way is with assigning username to a variable, then with the SQL statement.
Delete from tbl where colname='$username'
That's the way I would do it, other people might have different methods. So all respect to those who would use somethin different
You're getting the error because of this bit:
<?foreach($blogs AS $viewData):
$delete = $viewData['id'];
It should be this:
$delete = $viewData->id;
You're using the exact same data a line later correctly, why are you trying to use $viewData which is an object as an array here, but an object 2 lines later. Other than that the rest of what you're doing there should work fine but it is rather dangerous in practice. If I go to your site and type the url to that controller function with a blogId at the end that blog goes away, at no point are you checking that the user actually should be allowed to delete that blog. Obscurity != Security. Meaning that just because you think people won't find the link doesn't mean they won't.
Personally I save the userId of a logged in user to the session and save the session to the database. Then when I do anything to user records I do a check to ensure the user making the change has the authorization to make that change.
So your delete function would be something like this:
function deleteMyBlog($id)
{
$this->db->where('username',$this->session->userdata('username');
$this->db->where('id',$id);
$this->db->delete('blogs');
}
Also you should be using userId's not usernames for saving to other tables, the indexes work better on numerical ID's as far as I know and it's less overall data in the tables. Saving userId 342 to your blogs table takes up less space than saving username bobsyouruncle3421.
For the record, I know this isn't part of the question but actually deleting things from the database has downsides. Not the least of which is screwing up the indexing and slowing down queries in the long run. A far better solution is adding a status or active column to any tables you may want to delete from and giving them a value of 1 for active and 0 for deleted. Then instead of actually deleting the item you change it's active column to 0. When displaying items you add a check for active = 1 to the display query.
This serves two purposes, first you don't mess up the indexing, the record is never removed just modified so the indexes remain intact. Second and nearly important is you never have the possibility of accidentally deleting something you didn't mean to delete, it is never really gone. So you could "undelete" anything at any time.
new to CodeIgniter and MVC/OOP as well. My current problem that I am trying to work through involves 2 tables.
Gallery Table
id
name
clientID
Client Table
id
Name
The gallery['clientID'] references the client['id'] so I can retrieve the name. Currently my gallery_model.php file looks like
class Gallery_model extends CI_Model
{
public function __construct()
{
$this->load->database();
}
//Get all in progress galleries from client
public function get_progress($id = FALSE , $clientRef = '205')
{
if($id == FALSE) {
$query = $this->db->get_where('gallery', array('clientRef' => $clientRef, 'finish' => '0' ));
return $query->result_array();
}
}
//Get all proofed galleries from client
public function get_proofed($id = FALSE , $clientRef = '205')
{
//get all galleries from client
if ($id == FALSE) {
$query = $this->db->get_where('gallery',array('clientRef' => $clientRef, 'finish' => '1'));
return $query->result_array();
}
}
//get the gallery selected
public function get_gallery($id , $clientRef = '205')
{
//This returns individual galleries
$query = $this->db->get_where('gallery', array('id' => $id));
return $query->row_array();
}
}
My controller looks like:
public function index()
{
//Proofed Albums
$data['gallery'] = $this->gallery_model->get_proofed();
//Albums that are in progress
$data['in_progress'] = $this->gallery_model->get_progress();
$this->load->view('templates/header',$data);
$this->load->view('gallery/index',$data);
$this->load->view('templates/footer');
}
Then the view's out put is
$gallery['name'] - $gallery['clientId']
What is the best practice for something like this. I know it's probably simple, but I want to start out doing this correctly. Should I use $this->db->join();
Thanks in advance for the help on this.
Following up on William's answer, you can do a join using CI's Active Record
$this->db->from('gallery')->join('client', 'gallery.id = client.id')->get()
Using $this->db->join() is indeed the best (and the only way done via Active Records without adding your own SQL) way to get information from several tables all in one query.
You're probably already aware of this, but just in case (and for the benefit of future people visiting this page), the CodeIgniter User Guide has a nice page detailing how to use Active Records.
The default of Inner Join should be fine for your purposes. If you have gallery entries without clients linked to them and you want them to be included in the results, then you may want to consider the other types of join, which you can read about here.
After completing the tutorial from the codeigniter user guide I ran into a problem I was forcing for the last two hours. I am trying to add functionality to delete a post, selected by ID, I am new to PHP and couldn't find any solution for my problem:
The Controller
public function delete($id){
$id = $this->uri->segment(3);
$data['title'] = 'Delete an item';
if($this->news_model->delete_news($id)){
$this->load->view('templates/header', $data);
$this->load->view('news/success');
$this->load->view('templates/footer');
}else{
}
}
The Model
public function delete_news($id){
$this->db->where('id',$id)->delete('news');
return $this->db->affected_rows();
}
The Routing
$route['news/delete/(:num)'] = 'news/delete/$1';
I'm calling the function out of the index-page where all posts are shown with an anchor:
<p>Delete article</p>
and it calls the correct URL (http://localhost/webapp/index.php/news/delete/2) which should correctly execute and delete the post with the ID 2 from my news table.
I really can't understand where the mistake ism but by executing this, I get a 404.
What am I doing wrong?
In your function delete I don't see that you loaded the news_model. That could be the issue if it isn't auto-loading. Perhaps, start by verifying that the controller is talking to the model by inserting:
echo 'Hello Model';
in the delete_news function of your news_model.
EDIT:
Instead of
if($this->news_model->delete_news($id)){
//conditions
}
And
Have your model send a T/F based on it's execution. This will tell us if the error is in the SQL. By returning TRUE no matter what, we'll see if that model function even runs:
return TRUE;
Try to add the step (for error checking)
$del = $this->news_model->delete_news($id);
echo 'del';
if($del == TRUE){
//conditions
}
With the 404 - I'm also suspicious it's a routing issue. I'll take a look at that as well.