Confusing of CodeIgniter routes - php

This is my route:
$route['pages/show_create']['GET'] = 'pages/show_create';
$route['pages/create']['POST'] = 'pages/create';
And this is my controller:
public function show_create()
{
$data['title'] = 'Create new news';
$this->load->view('templates/header', $data);
$this->load->view('news/create');
$this->load->view('templates/footer');
}
public function create()
{
$data['title'] = 'Create new news';
$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');
}
}
I want to show the form by accessing news/show_create route but it just return 404. What's wrong with my code? Thanks

Codeigniter documentation is very easiest programming documentation. You can easily learn more about routing by using following link.
https://www.codeigniter.com/userguide3/general/routing.html
As i can see in your code you don't need to mentioned method type along with route.
Here i am assuming that you have got and PagesController class where you have created a method by using name show_create and for this you can set routing like below in your route class.If still you have confusion you can write here.
$route['news/show_create'] = 'pages/show_create';

Add this to your routes.
$route['news/show_create']['GET'] = 'pages/show_create';
I assumed your controller name is PageController.
This is the format.
$route['desired_route']['method'] = 'controller_name/function';

try this:
$route['news/show_create']='Controller_name/method_name';

It looks like you don't need routes. If they are removed, and assuming the controller is named pages, you can call the methods like so
http://example.com/pages/show_create
and
http://example.com/pages/create
If you truly want to show the form by accessing news/show_create then $route in Girraj's answer is the way to go.
$route['news/show_create'] = 'pages/show_create';

Related

Codeigniter form_open() load View file twice when passing variable from Controller to View

My Controller is something along the line of
public function create_room($id_1, $id_2) {
$data['id_1'] = $id_1;
$data['id_2'] = $id_2;
$data['query'] = $this->model->get_all();
$this->load->view('viewFilePath', $data);
$this->form_validation->set_rules // set the rules
if ($this->form_validation->run() === FALSE) {
$this->load->view('viewFilePath');
$this->session->set_flashdata('error', "errorMessage");
} else { (do the query)
}
My View
<?php echo form_open('theURL'.$id_1.'/'.$id_2.'/URLEnding');?>
The view is loading twice, most likely because I load the view once in both files.
Basically I want to:
Pass $id_1 and $id_2 from the opening URL to Controller function as parameters;
Query in Controller using $id_1 and $id_2;
Pass the query data to View.
Is there a way to achieve this without loading the view twice?
Update: I've tried these:
Removing load->view from create_room() (no $data passing from view to controller)
you can create another function store and move the following code to the new function. because this code will run when you submit the form. and in form open use the store function instead of the create form
$this->form_validation->set_rules // set the rules
if ($this->form_validation->run() === FALSE) {
$this->load->view('viewFilePath');
$this->session->set_flashdata('error', "errorMessage");
} else { (etc)
please change your code because view call two time so if you remove one call and other is move your second call in else part.
$data['id_2'] = $id_2;
$data['query'] = $this->model->get_all();
$this->form_validation->set_rules // set the rules
if ($this->form_validation->run() === FALSE) {
$this->load->view('viewFilePath');
$this->session->set_flashdata('error', "errorMessage");
} else {
$this->load->view('viewFilePath', $data);
(etc)

Laravel 4 database actions - controller or model

just started using Laravel but want to make sure I am using it correctly.
Most of my work is CMS based so read / write / update etc to a database.
An example of what I have done so far is an insertion into the DB:
On the view I have a form with a URL of 'addNewUser'.
In my routes I then do:
Route::post('addnewuser', array('uses' => 'UserController#addNewUser'));
My user controller 'addNewUser' method is (simplified):
public function addNewUser() {
$data = Input::all();
$rules = array(
'username' => 'required|alpha_dash|max:16|unique:users,username',
);
$validator = Validator::make($data, $rules, $messages);
if ($validator->fails())
{
Input::flash();
$errors = $validator->messages();
return Redirect::to('/register')->withErrors($validator)->withInput();
}
$user = new User;
$user->save();
return Redirect::to('/login')->with('successLogin', '1');
}
Is this correct? I have read somewhere that all DB interaction should be in the model?
Likewise when reading from the DB to display a foreach for example, I do the following directly in the view:
$builds = DB::table('blogs')->orderBy('id', 'desc')->get();
if ($builds) {
foreach ($builds as $build)
{
$safeURLSlug = stringHelpers::safeURLSlug($build->blogtitle);
echo "
// stuff
";
}
} else {
// no stuff
}
Should I be doing these sort of queries and showing of data directly in the view? or in a model / controller function etc?
Want to check im doing things 100% correct / the standard way of doing things before I get too involved.
I can see a few things that I personally would have done differently.
For example I usually put $rules as a class variable so it can be used in different functions related to your Users.
Have you tested your code yet? Any errors?
In your addNewUser function does it save any data? I know you have "simplified" above the code snippet but there should be $user->username = $data['username']; etc. in between creating your $user variable and running $user->save();, so if you excluded this on purpose then I don't see anything else with your model.
In your view code, $builds = DB::table('blogs')->orderBy('id', 'desc')->get(); should be done in your controller and passed to your view like so return View::make('example', array('builds' => $builds))
I'd also change
$builds = DB::table('blogs')->orderBy('id', 'desc')->get();
to
$builds = Blog::orderby('id','desc')->get(); if you have a Blog model, otherwise your code is fine.
You could move:
$rules = array(
'username' => 'required|alpha_dash|max:16|unique:users,username',
);
to User model as static variable, and instead of:
$validator = Validator::make($data, $rules, $messages);
you could use:
$validator = Validator::make($data, User::$rules, $messages);
But definitely you shouldn't get data from database in your View, this code should be in controller, for example:
$builds = DB::table('blogs')->orderBy('id', 'desc')->get();
return View::make('someview')->with('builds', $builds);
of course if you have Blog model, you should use here:
$builds = Blog::orderBy('id', 'desc')->get();
return View::make('someview')->with('builds', $builds);
It's also unclear what the following code does:
$safeURLSlug = stringHelpers::safeURLSlug($build->blogtitle);
but probably you could move it to your Blog model and use accessor to make the change:
public function getSafeSlugAttribute($value) {
return stringHelpers::safeURLSlug($this->blogtitle);
}
and now your view could look like this:
#foreach ($builds as $build)
{{{ $build->title }}} {{{ $build->safeSlug }}}
#endforeach
I suggest you take a look on Laravel Generators.
https://github.com/JeffreyWay/Laravel-4-Generators
Install and then run:
php artisan generate:scaffold customer
Laravel line command generator create a basic CRUD for you with controller, model, views and database migrations. That's good to safe time and keep your project with some default organization.

Cannot insert values into database using codeigniter

trying to insert form values into database using codeigniter but nothing heppens.
my form is comment_form.php is like,
<?php echo validation_errors(); ?>
<?php echo form_open('news/comment_form'); ?>
Name<input type="text" name="comment_name"></input><br />
Email<input type="text" name="comment_email"></input><br />
Comment<input type="text" name="comment_body"></input><br />
<input type="submit" name="submit" value="Comment it" ></input>
</form>
here's my controller comments.php
class Comments extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('comment_model');
}
public function create_comment()
{
$this->load->helper('form');
$this->load->library('form_validation');
//$data['title'] = 'Create a news item';
$this->form_validation->set_rules('comment_name', 'comment_name', 'required');
$this->form_validation->set_rules('comment_email', 'comment_email', 'required');
$this->form_validation->set_rules('comment_body', 'comment_body', 'required');
if ($this->form_validation->run() === FALSE) {
$this->load->view('templates/header', $data);
$this->load->view('news/comment_form');
$this->load->view('templates/footer');
} else {
$this->news_model->set_comment();
$this->load->view('news/success');
}
}
}
and this is my model comment_model.php
class Comment_model extends CI_Model
{
public function __construct()
{
$this->load->database();
}
public function set_comment()
{
//$this->load->helper('url');
//$slug = url_title($this->input->post('title'), 'dash', TRUE);
$datac = array(
'comment_name' => $this->input->post('comment_name'),
'comment_email' => $this->input->post('comment_email'),
'comment_body' => $this->input->post('comment_body')
);
return $this->db->insert('comments', $datac);
}
}
the problem is whenever i submitting the form it returns nothing, like nothing happened.please help.
In your comment_form.php change
echo form_open('news/create_comment');
to
echo form_open('comments/create_comment');
Why? Because the first parameter you give to form_open() is the action parameter. It will open a form tag like <form action="bla">. And news/create_comment is not the correct page you want to call. Your controller is named comments, that's why you put comments/create_comment.
In your comments.php change
$this->news_model->set_comment();
to
$this->comment_model->set_comment();
Why? Just simply pointing to the false model. Maybe a copypaste-error?
In your comment_model.php remove
$this->load->database();
And load it in your config.php (in the libraries array, add 'database').
Why? IMHO this is the more proper solution. You're probably gonna use your database pretty often, so why load that everytime?
If you still encounter problems, then we need more information. What exactly is not working. Do some debugging for us. After you call $this->news_model->set_comment() write var_dump($this->db->last_query());
this->news_model->set_comment()
Should be
this->comment_model->set_comment()
PS: sorry for the formatting. Mobile version doesn't read new lines.
Change :
$this->load->database();
echo form_open('news/comment_form');
$this->news_model->set_comment();
To:
$this->load->library('database');
echo form_open('news/create_comment');
$this->comment_model->set_comment();
It would be better if you load your database library in your autoload.php. Or in your controller's constructor.
In the set_comment function after $this->db->insert('comments', $datac); just echo the query using below command and try running the same query manually in the database, you may come to know the issue.
echo $this->db->last_query();
Get the posted values in controller instead of model and then pass them to model.
Controller function
public function create_comment()
{
$this->load->helper('form');
$this->load->library('form_validation');
$this->form_validation->set_rules('comment_name', 'comment_name', 'required');
$this->form_validation->set_rules('comment_email', 'comment_email', 'required');
$this->form_validation->set_rules('comment_body', 'comment_body', 'required');
if ($this->form_validation->run() === FALSE) {
$this->load->view('templates/header', $data);
$this->load->view('news/comment_form');
$this->load->view('templates/footer');
} else {
$data['comment_name'] = $this->input->post('comment_name'),
$data['comment_email'] = $this->input->post('comment_email'),
$data['comment_body'] = $this->input->post('comment_body')
$this->news_model->set_comment();
$this->load->view('news/success');
}
}
Model function
public function set_comment($data)
{
//$this->load->helper('url');
//$slug = url_title($this->input->post('title'), 'dash', TRUE);
$this->db->insert('comments', $data);
return $this->db->insert_id();
}
EDITS
The above code will work if you follow these steps.
Go to database.php in application/config and provide database connection settings like hostname , username , password and database name.
Then go to autoload.php in application/config and autoload the database library like this
$autoload['libraries'] = array('database');
Also remove the closing tags for input in your html form.
Try testing like this in controller before moving forward
$post = $this->input->post();
echo '<pre>';
print_r($post);
This will ensure you are receiving post data

Laravel : Variable layout for a single view

I wanted to know if there's a way to use variable layout for a single view in laravel.
I have a view of the login section. I want to show the login view in a lightbox by calling it via AJAX. I was thinking of using a different layout for the login view when it is called through ajax.
Something like this :
if($_GET["from"] == "ajaxLink") {
// use layout1
} else {
// use layout2
}
This obviously doesnt work. :)
Is there any way i can do this??
Thanks.
2 ways.
1. Blade layout
Controller:
$layout = Request::ajax() ? 'layout1' : 'layout2';
$data = array('layout' => $layout);
return View::make('index', $data);
View:
#layout($layout)
//rest of the code....
2. Controller layout
public function action_index()
{
$this->layout = Request::ajax() ? 'layout1' :'layout2';
$this->layout->nest('content', 'index');
}

is_unique for codeigniter form validation

I'm trying to figure out how I can use the is_unique rule from the Codeigniter form validation library in the following situation.
I'm trying to submit a edit user form and have the rule:
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|is_unique[users.user_name]');
What if other values in the form are being changed but this value stays the same. The form is going to see that this value already exists so how would I protect it from editing if this value isn't changed.
Using your code as an example, the is_unique validation rule works by looking for a field called user_name in your users database table. If the field with the same value exists it validates as false.
To make sure it runs only when the user submits a new value, you could check the posted value $this->input->post('user_name') against the value you pulled from the database to populate your form with. If they are the same, don't validate is_unique;
if($this->input->post('user_name') != $original_value) {
$is_unique = '|is_unique[users.user_name]'
} else {
$is_unique = ''
}
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean'.$is_unique);
There's a better way to go around it, I think, still using CodeIgniters' validation library...
Use edit_unique where you pass an extra parameter which is the id of the row you're editing.. See below.. I use it and works pretty fine for me.. hope it helps
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');
$something = $this->input->post('something');
$this->form->validation->set_rules('something','Something','xss_clean|is_unique['tbl'.users]');
if($this->form_validation->run()== FALSE){
}
Simple Way
Just Change isset to is_object in system/libraries/form_validation.php
public function is_unique($str, $field)
{
sscanf($field, '%[^.].%[^.]', $table, $field);
return is_object($this->CI->db) //default isset
? ($this->CI->db->limit(1)->get_where($table, array($field => $str))->num_rows() === 0)
: FALSE;
}
Here's an easy method that worked for me and uses well documented code (thanks to https://github.com/ivantcholakov for sharing it!). I found it referenced at https://github.com/bcit-ci/CodeIgniter/issues/3109#issuecomment-46346280
Download https://github.com/ivantcholakov/starter-public-edition-3/blob/master/platform/application/libraries/MY_Form_validation.php (MIT licensed) and save it to your application at application\libraries\MY_Form_validation.php
Delete these two lines from __construct():
$this->CI->load->helper('checkbox');
$this->CI->load->helper('email');
Delete all the functions except __construct() and unique().
At the end of the __construct() method of your controller add this line:
$this->load->library('form_validation');
As per the documentation of the unique() method update your validation rule to add a "unique" rule like this (e.g. if you already have required and trim rules):
…|required|unique[tablename.fieldname,tablename.(primaryKey-used-for-updates)]|trim...
Extend Form_validation.php library create class inside of application/libraries file name MY_Form_validation.php
<?php
class MY_Form_validation extends CI_Form_validation{
protected $ci;
public function __construct($config = array()){
parent::__construct($config);
$this->ci =& get_instance();
}
public function is_unique_update($str, $field){
$explode=explode('#', $field);
$field_name=$explode['0'];
$field_id_key=$explode['1'];
$field_id_value=$explode['2'];
sscanf($field_name, '%[^.].%[^.]', $table, $field_name);
if(isset($this->ci->db)){
if($this->ci->db->limit(1)->get_where($table, array($field_name => $str,$field_id_key=>$field_id_value))->num_rows() === 0){
$this->ci->form_validation->set_message('is_unique_update', 'The {field} field must contain a unique value.');
return false;
}
return true;
}
}
}
Now in your controller
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|is_unique_update[users.user_name#id#'.$id.']');
"#" I used for explode the string
where id is primary key of users table
and $id is the value of id.
Now you can use this is_unique_update validation in any controller.
This question is very old but maybe some new people experience this problem and this is the solution for it.
I bet your are using Modular Extensions (HMVC) and you have created a new library, MY_Form_validation. You did id for callbacks, so you have this line of code on your class in order to use callbacks:
$this->form_validation->CI =& $this;
Well, the solution to this is whenever you want to use "is_unique" you must delete this line of code "$this->form_validation->CI =& $this;" from the class. I have experienced this problem and i fix it this way, it works fine now.
If you realy want to use callbacks "$this->form_validation->CI =& $this;", then do it only on required "methods" / "functions" where you don't want to use is_unique.
This code helpful for unique validation to create and update function...
In controller
Add this form validation code in both create and update function
$this->form_validation->set_rules('order_no', 'Order no', 'required|callback_check_order_no');
Add this call back function in controller
function check_order_no($order_no) {
if($this->input->post('id'))
$id = $this->input->post('id');
else
$id = '';
$result = $this->Data_model->check_unique_order_no($id, $order_no);
if($result == 0)
$response = true;
else {
$this->form_validation->set_message('check_order_no', 'Order no already exist');
$response = false;
}
return $response;
}
In model
function check_unique_order_no($id = '', $order_no) {
$this->db->where('order_no', $order_no);
$this->db->where('status', "A");
if($id) {
$this->db->where_not_in('id', $id);
}
return $this->db->get('delivery_order')->num_rows();
}
I'm using codeigniter3 and it shows me error when I check username on updating the value, is_unique is not designed to work with update scenario
so using #Anthony Mutisya's answer, here is the complete solution
in your controller, add this line while validation username of the current user with the database
$this->form_validation->set_rules('user_name', 'User Name', 'required|trim|xss_clean|edit_unique[users.user_name.'.$id.']');
You can get that $id from your submited form.
Now, add the following function to /system/libraries/Form_Validation.php this file. System folder is present in your root of CodeIgniter3 folder.
/**
* edit_unique // for check on update value
*
* Check if the input value doesn't already exist
* in the specified database field.
*
* #param string $str
* #param string $field
* #return bool
*/
function edit_unique($value, $params) {
$CI =& get_instance();
$CI->load->database();
$CI->form_validation->set_message('edit_unique', "Sorry, that %s is already being used.");
list($table, $field, $current_id) = explode(".", $params);
$query = $CI->db->select()->from($table)->where($field, $value)->limit(1)->get();
if ($query->row() && $query->row()->id != $current_id)
{
return FALSE;
} else {
return TRUE;
}
}
It works perfectly fine in my case
CodeIgniter 4 has already solution for that,
$validation->setRules([
'email' => 'required|valid_email|is_unique[users.email,id,{id}]',
]);
$_POST = [
'id' => 4,
'email' => 'foo#example.com',
];
then the {id} placeholder would be replaced with the number 4, giving this revised rule:
$validation->setRules([
'email' => 'required|valid_email|is_unique[users.email,id,4]',
]);
Official Documentation
we must have to add table name for is_unique
for Exp.
is_unique[users.email]

Categories