I've never used a PHP framework, but I wanted to learn how to use one so I could more easily program for my company, so I chose CodeIgniter.
I am following the code igniter tutorial for a news section so I could learn how things work - but I am having some issues/questions.
Now, I am to the point in the tutorial that I have a form that submits and takes me to a success page. In normal PHP this is where I would just redirect the page to the view page of the news item submitted. In CodeIgniter I have a view function in my controller here
public function view($slug = NULL)
{
$data['news_item'] = $this->news_model->get_news($slug);
if (empty($data['news_item']))
{
show_404();
}
$data['title'] = $data['news_item']['title'];
$this->load->view('templates/header', $data);
$this->load->view('news/view', $data);
$this->load->view('templates/footer');
}
I'm not sure how to get the slug from the form when it is submitted.
Here is my create function (Basically the one that inserts the database info and redirects to news/success)
public function create()
{
$this->load->helper('form');
$this->load->library('form_validation');
$data['title'] = 'Create a news item';
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('text', 'Text', 'required');
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('news/create');
$this->load->view('templates/footer');
}
else
{
$this->news_model->set_news();
$this->load->view('news/success');
}
}
But I want this to redirect to the view page. To do that I need to have the slug I believe. So it should redirect to news/view/$slug - but I'm not sure how to do this.
My set_news model:
public function set_news()
{
$this->load->helper('url');
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$data = array(
'title' => $this->input->post('title'),
'slug' => $slug,
'text' => $this->input->post('text')
);
return $this->db->insert('news', $data);
}
You should use something like that:
redirect('news/view/'.url_title($this->input->post('title'), 'dash', TRUE));
Related
I'm new to PHP CodeIgniter and I'm creating my first app, I've created the controller, model and views to add records to my DB and so far so good,
The problem starts when I click 'submit' in my form,
as instead of redirecting to the same form again if there is an issue in the form or redirecting to the success page, it redirects to the same page but with the full path twice,
like this:
form page - localhost/index.php/news/create
expected results:
form data is valid ->localhost/index.php/news/success
form is invalid -> localhost/index.php/news/create (same page)
but instead it does this when I click submit:
localhost/index.php/news/localhost/index.php/news/create
as you can see, it takes the full path again and puts it afterwards the already existing url.
this is my code
routes.php
$route['news/create'] = 'news/create';
$route['news/(:any)'] = 'news/view/$1';
$route['news'] = 'news';
$route['(:any)'] = 'pages/view/$1';
$route['default_controller'] = 'pages/view';
$route['news/create'] = 'news/create';
main controller
public function view($page = 'home')
{
if ( ! file_exists(APPPATH.'views/pages/'.$page.'.php'))
{
// Whoops, we don't have a page for that!
show_404();
}
$data['title'] = ucfirst($page); // Capitalize the first letter
$this->load->view('templates/header', $data);
$this->load->view('pages/'.$page, $data);
$this->load->view('templates/footer', $data);
}
controller that has the function create of the form
class News extends CI_Controller {
public function create()
{
$this->load->helper('form');
$this->load->library('form_validation');
$data['title'] = 'Create a news item';
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('text', 'Text', 'required');
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('news/create');
$this->load->view('templates/footer');
}
else
{
$this->news_model->set_news();
$this->load->view('news/success');
}
}
}
model:
public function set_news()
{
$this->load->helper('url');
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$data = array(
'title' => $this->input->post('title'),
'slug' => $slug,
'text' => $this->input->post('text')
);
return $this->db->insert('news', $data);
}
Form
<h2><?php echo $title; ?></h2>
<?php echo validation_errors(); ?>
<?php echo form_open('news/create'); ?>
<label for="title">Title</label>
<input type="input" name="title" /><br />
<label for="text">Text</label>
<textarea name="text"></textarea><br />
<input type="submit" name="submit" value="Create news item" />
</form>
Thanks to #tobifasc for the answer,
The problem was in config.php
I replaced
$config['base_url'] = 'localhost';
to this:
$config['base_url'] = 'http://localhost/';
and everything is working properly now
It's happening because you have already view loaded and when your validation failed again you loaded your same view so you don't need to view again. Replace your News controller the create method by this code EX:
class News extends CI_Controller {
public function create()
{
$this->load->helper('form');
$this->load->library('form_validation');
$data['title'] = 'Create a news item';
$this->form_validation->set_rules('title', 'Title', 'required');
$this->form_validation->set_rules('text', 'Text', 'required');
if ($this->form_validation->run() === FALSE)
{
}
else
{
$this->news_model->set_news();
$this->load->view('news/success');
}
}
}
I have a codeigniter form which runs some basic validation and submits data to the database. But I want to additionally alter the post data of one of the fields to use the inflector helper in order to convert the posted data to camel case before submitting to the database. How do I do this?
Here is my current form:
<?php echo form_open('instances/create') ?>
<label for="content">Content</label>
<textarea name="content"></textarea><br />
<input type="submit" name="submit" value="Create" />
</form>
Here is my current controller:
public function create(){
$this->load->helper('form');
$this->load->library('form_validation');
$this->load->helper('inflector');
$data['title'] = 'Create an instance';
$this->form_validation->set_rules('title', 'Title', 'required');
//want to camelize the 'title' here
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('instances/create');
$this->load->view('templates/footer');
}
else
{
$this->instances_model->set_instances();
$this->load->view('instances/success');
}
}
and here's my model:
<?php
class Instances_model extends CI_Model {
public function __construct(){
$this->load->database();
}
public function get_instances($slug = FALSE){
if ($slug === FALSE){
$query = $this->db->get('extra_instances');
return $query->result_array();
}
$query = $this->db->get_where('extra_instances', array('slug' => $slug));
return $query->row_array();
}
public function set_instances(){
$this->load->helper('url');
$slug = url_title($this->input->post('title'), 'dash', TRUE);
$data = array(
'slug' => $slug,
'title' => $this->input->post('title'),
'content' => $this->input->post('content'),
'year' => $this->input->post('year'),
'credit' => $this->input->post('credit'),
'source' => $this->input->post('source')
);
return $this->db->insert('extra_instances', $data);
}
}
I know that you can camelize a variable with the following:
echo camelize('my_dog_spot'); // Prints 'myDogSpot'
and I know that you can run custom validation like this:
$this->form_validation->set_rules('username', 'Username', 'callback_username_check');
public function username_check($str)
{
if ($str == 'test')
{
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
return FALSE;
}
else
{
return TRUE;
}
}
But I'm lacking the knowledge of how to put this altogether to quickly change the POST data before submitting to the database.
Nothing too complicated, you can do it after you pass the validation, just before inserting your data array into the database:
$data = array(
'slug' => $slug,
'title' => camelize($this->input->post('title')),
// ...
This doesn't make sense to me with how MVC works in codeigniter.
I have a 'controller/Company.php' loads using example.com/company/
function index() {
$page = uri_string();
$data['title'] = ucfirst($page);
$this->load->view('templates/header', $data);
$this->load->view('templates/top_nav', $data);
$this->load->view($page, $data);
$this->load->view('templates/footer', $data);
}
This loads 'views/company.php' and displays form:
<h1 class="page-title"><?php echo $title; ?></h1>
<?php echo form_open('company/update', 'class="form-horizontal" role="form"'); ?>
<input name="company_name" type="text">
<?php echo form_error('company_name'); ?> //if empty display error
//rest of form and submit button
I then have an update function inside the Company controller:
function update() {
$this->form_validation->set_rules('company_name', 'Company Name', 'trim|required');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('company');
} else {
//update db, load model, post data, success, etc
}
}
My issues are:
If I just load the form view again then I lose my header, nav, footer, etc.
If I redeclare all 4 of those views, I lose the original data variables: $title, $page
If I use redirect('company'); to load the controller again then I would lose the submitted data and the form_error('company_name'); would be empty
I hope I'm missing something big because I have been staring at this all day and search for answers but can't find a tutorial of how all of this is suppose to work in the "real world" Thanks
Yes of course. Controller method act as single function in your project.
if i explain it more
<?php
public function one()
{
echo '1';
}
public function two()
{
echo '2';
}
In here function one don't know what is function two. So both functions are acting as Independent.
According to your question
you load this views in index()
$this->load->view('templates/header', $data);
$this->load->view('templates/top_nav', $data);
$this->load->view($page, $data);
$this->load->view('templates/footer', $data);
but in update() you load only
$this->load->view('company');
so in second function there are no header, navigation, and footer.
Answer for your Question is
<?php
if ($this->form_validation->run() == FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('templates/top_nav', $data);
$this->load->view('company');
$this->load->view('templates/footer', $data);
} else
{
//update db, load model, post data, success, etc
}
For question Two
you can use like this
<?php
if ($this->form_validation->run() == FALSE)
{
$page = uri_string();
$data['title'] = ucfirst($page);
$this->load->view('templates/header', $data);
$this->load->view('templates/top_nav', $data);
$this->load->view('company');
$this->load->view('templates/footer', $data);
} else
{
//update db, load model, post data, success, etc
}
I am pretty knew to code igniter / OOP but I am giving it a shot and a little stumped at this point.
I have 2 functions. One is the search which loads data from a model. The other is the save function.
My issue is, when running save() I am getting errors because its trying ti display the validation errors but we no longer have the data from the database that we got from the search() function.
I feel that it would be redundant to include all the details form the search back into this save function which is why I think I am doing something wrong.
public function search()
{
// Define some vars
$data['title'] = 'Submit Attrition';
$data['js_file'] = 'submit.js';
// Load our helper
$this->load->helper('form');
// Get the user and pass it to the model
$empQID = $this->input->post('empQID');
$data['userDetails'] = $this->submit_model->get_details($empQID);
$data['languages'] = $this->submit_model->get_languages();
$data['types'] = $this->submit_model->get_types();
$data['ratings'] = $this->submit_model->get_ratings();
$data['processes'] = $this->submit_model->get_processes();
// Send the data to the views
$this->load->view('templates/header', $data);
$this->load->view('submit/search', $data);
$this->load->view('templates/footer', $data);
}
/**
* Validate & save attrition submission
*
* #author Carl
* #return void
*/
public function save()
{
$data['title'] = 'Submit Attrition';
$this->load->library('form_validation');
$this->form_validation->set_rules('language', 'Supporting Language', 'required');
// Validation failed, show form w/ validation errors
if ($this->form_validation->run() === FALSE)
{
$this->load->view('templates/header', $data);
$this->load->view('submit/search', $data);
$this->load->view('templates/footer', $data);
}
else
{
// Success : Send data to model
$this->submit_model->save_attrition();
$this->load->view('templates/header', $data);
$this->load->view('submit/success', $data);
$this->load->view('templates/footer', $data);
}
}
I'm not sure I entirely understand your question, but I think I understand what you're trying to do. In CodeIgniter, you do something like this:
class MyController
{
// this controller action will load whether the form is submitted or not
// $user_id is set by the router
public function save($username)
{
// if the users not in the database, throw a 404 error
$user = $this->db->get_where('users', ['username' => $username]);
if(!$user) {
return show_404();
}
// if it's not a post request, then the form hasn't been submitted
// so don't bother validating it
if($router->fetch_method() === 'POST' && $form_validation->run() === TRUE)
{
$user['name'] = $this->input->post('name');
$this->db->update('users', $user);
$this->load->view('success_page');
// return so we don't render the form again
return;
}
// this will happen in all cases, __except__ when the form was submitted
// with valid data
$this->load->view('form');
}
}
I've skipped on details for brevity (like loading the relevant libraries), and because I can't remember all the CI syntax.
I was playing around with this code. http://programmersvoice.com/tag/code
And I noticed that the following line.
$this->load->model($this->models."pagemodel", 'pages');
I compare this with
$this->load->model("pagemodel", 'pages');
This is what codeigniter's document http://codeigniter.com/user_guide/general/models.html#loading suggest.
However method 2 takes longer time than the first one.
Could anyone explain what "$this->models." do please?
Thanks in advance.
The following is the whole code of pages.php in controllers/admin
<?php
class Pages extends Application
{
function Pages()
{
parent::Application();
$this->auth->restrict('editor'); // restrict this controller to editor and above
$this->load->model($this->models."pagemodel", 'pages'); // Load the page model
}
function manage()
{
$data = $this->pages->pages(); // List the pages
$this->table->set_heading('Title', 'Slug', 'Actions'); // Setting headings for the table
foreach($data as $value => $key)
{
$actions = anchor("admin/pages/edit/".$key['id']."/", "Edit") . anchor("admin/pages/delete/".$key['id']."/", "Delete"); // Build actions links
$this->table->add_row($key['title'], $key['slug'], $actions); // Adding row to table
}
$this->auth->view('pages/manage'); // Load the view
}
function delete($id)
{
$this->pages->delete($id);
$this->auth->view('pages/delete_success');
}
function add()
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('title', 'Page Title', 'required');
$this->form_validation->set_rules('content', 'Content', 'required');
if($this->form_validation->run() == FALSE)
{
$this->auth->view('pages/add');
}
else
{
$data['title'] = set_value('title');
$data['content'] = set_value('content');
$data['slug'] = url_title($data['title'], 'underscore', TRUE);
$this->pages->add($data);
$this->auth->view('pages/add_success');
}
}
function edit($id)
{
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
$this->form_validation->set_rules('title', 'Page Title', 'required');
$this->form_validation->set_rules('content', 'Content', 'required');
if($this->form_validation->run() == FALSE)
{
$data = $this->pages->page($id);
$this->auth->view('pages/edit', $data[0]);
}
else
{
$data['title'] = set_value('title');
$data['content'] = set_value('content');
$data['slug'] = url_title($data['title'], 'underscore', TRUE);
$this->pages->edit($id, $data);
$this->auth->view('pages/edit_success');
}
}
}
?>
I'm not totally sure about the following, since the current version of Codeigniter doesn't seem to populate the $this->models variable, but I think that:
$this->models contained the full path to the application models directory, and therefore loading is faster, since CI doesn't have to look in different folders (global & application)