I'm writing a custom component for my work. I'm using hello component for building it. When I edit a form and save it I get this error:
Call to a member function bind() on a non-object
My code:
function save()
{
global $option;
JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_abc'.DS.'tables');
$row =& JTable::getInstance('abc', 'Table');
if(!$row->bind(JRequest::get('post')))
{
JError::raiseError(500, $row->getError() );
}
$row->message = JRequest::getVar( 'message', '','post', 'string', JREQUEST_ALLOWRAW );
if(!$row->store()){
JError::raiseError(500, $row->getError() );
}
switch($this->_task)
{
case 'apply':
$msg = 'Change Saved';
$link = 'index.php?option='.$option.'&task=edit&cid[]='.$row->id;
break;
case 'save':
$msg = 'Saved';
$link = 'index.php?option='.$option;
break;
default:
}
$this->setRedirect($link, $msg);
}
The problem is that it's unable to create an instance.
Please let me know if anyone knows a solution.
Thanks.
The problem is you calling the method 'bind' that doesn't exists on the variable $row.
You defined $row as: $row =& JTable::getInstance('abc', 'Table'); which means your problem starts right there. It's trying to fetch database content which fails. I suggest you change the parameters 'abc' and 'Table' to something real, it looks like sample data to me.
The following code will help you:
function addComment($option)
{
global $mainframe;
$row =& JTable::getInstance( 'comment' , 'Table' );
if (!$row->bind(JRequest::get( 'post')))
{
JError::raiseError(500, $row->getError() );
}
$row->comment_date = date ( 'Y-m-d H:i:s' );
$user =& JFactory::getUser();
if($user->id)
{
$row->user_id = $user->id;
}
if(!$row->store())
{
JError::raiseError(500, $row->getError() );
}
$link = JRoute::_( 'index.php?option='.$option.'&id='.$row->id . '&task=view' );
$mainframe->redirect( $link, 'Comment Added' );
}
My table name data to be fetched is jos_abc. The save function is in my_componet/controller.php. The class name of controller is XyzController:
class XyzController extends JController {
function __construct() {
//Get View
if(JRequest::getCmd('view') == '') {
JRequest::setVar('view', 'default');
}
$this->item_type = 'Default';
parent::__construct();
}
function save()
{
global $option;
JTable::addIncludePath(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_tripplanner'.DS.'tables');
$row1 =& JTable::getInstance('xyz', 'jos_abc');
if(!$row1->bind(JRequest::get('post')))
{
JError::raiseError(500, $row->getError() );
}
$row->message = JRequest::getVar( 'message', '','post', 'string', JREQUEST_ALLOWRAW );
if(!$row->store()){
JError::raiseError(500, $row->getError() );
}
switch($this->_task)
{
case 'apply':
$msg = 'Change Saved';
$link = 'index.php?option='.$option.'&task=edit&cid[]='.$row->id;
break;
case 'save':
$msg = 'Saved';
$link = 'index.php?option='.$option;
break;
default:
}
$this->setRedirect($link, $msg);
}
}
Even then I'm unable to save, I get "Call to a member function bind() on a non-object".
Related
http error occured while calling data from model using function
model
public function getProductCombo() {
$q = $this->db->get_where('products', array('type' => 'combo'));
if ($q->num_rows() > 0) {
foreach (($q->result()) as $row) {
$data[] = $row;
}
return $data;
}
}
controller
function sets() {
$this->sma->checkPermissions();
$this->load->helper('security');
$this->data['error'] = (validation_errors() ? validation_errors() :
$this->session->flashdata('error'));
// problem in this line also
$this->data['showcombo'] = $this->load->sales_model->getComboProduct();
$bc = array(array('link' => base_url(),
'page' => lang('home')),
array('link' => site_url('sales'),
'page' => lang('products')),
array('link' => '#', 'page' => "sets")
);
$meta = array('page_title' => "Add Sets", 'bc' => $bc);
$this->page_construct('sales/sets', $meta, $this->data);
}
First of all, No need to include the curly braces for $q->result
foreach ($q->result as $row)
{
$data[] = $row;
}
No need to use validation_errors in your php file.You can directly load your form page.Use validation_errors() in view page.
In your Controller, do this
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
Then in your formpage you can echo
<?php echo validation_errors(); ?>
change this line to
$this->data['showcombo'] = $this->load->sales_model->getComboProduct();
this
$this->data['showcombo'] = $this->load->sales_model->getProductCombo();
Because your
model name is
public function getProductCombo()
{
}
Firstly you load model in controller. And then called function, which you have defined in model..
$this->load->model('sales_model','sales'); // sales is alias name of model name
$this->data['showcombo'] = $this->sales->getComboProduct();
I am new in CodeIgniter and using CodeIgniter_2.1.3. I am following NETTUTS CodeIgniter tutorial. I want to develop a login system with codeIgniter which works well without md5() function [without encrypted password] . Then I create new table with encrypted password using md5() function. Then login code doesn't work. My code is ::
view/login_form.php
<?php
// form design
echo form_open("login/validate") . "<br/>";
echo form_input("username", "Username") . "<br/> <br/>";
echo form_password("password", "password") . "<br/> <br/>";
echo form_submit("submit", "Login") . "<Br/> <Br/>";
echo anchor("login/sign_up", "Create Account");
?>
controllers/login.php
<?php
class Login extends CI_Controller {
function index() { // function of loading login page
$data['main_content'] = "login_form"; // name of login page
$this->load->view("includes/templet", $data);
}
function validate() { // form validation
$this->load->model("membership_model"); // load "membership_model"
$query = $this->membership_model->validate_user(); // check validation
if( $query ) { // if data found
$data = array( // value which is to be inserted into session
"username" => $this->input->post("username"),
"is_logged_in" => true
);
$this->session->set_userdata($data); // insert value into session
redirect("site/members_area"); // go to predefined page
}
else {
// if data not found then go to login_form page
$this->index();
}
}
// create account
function sign_up() {
$data['main_content'] = "sign_up";
$this->load->view("includes/templet", $data);
}
// insert data into database
function create_member() {
$this->load->library("form_validation"); // load form_validation library
$this->form_validation->set_rules("username", "Username", "trim|required");
$this->form_validation->set_rules("password", "Enter Password", "trim|required|min_length[4]|max_length[32]");
$this->form_validation->set_rules("re_password", "Confirm password", "trim|required|matches[password]");
$this->form_validation->set_rules("email", "Email Address", "trim|required|valid_email");
if( $this->form_validation->run() == FALSE ) {
$this->load->view("sign_up");
}
else {
$this->load->model("membership_model");
if( $query = $this->membership_model->create_member() ) {
// redirect("site/members_area");
$data['main_content'] = "signup_success";
$this->load->view("includes/templet", $data);
}
else {
$this->load->view("sign_up");
}
}
}
}
?>
model/membership_model
<?php
class Membership_model extends CI_Model {
function validate_user() {
$this->db->where('username', $this->input->post('username'));
$this->db->where('password', md5($this->input->post('password')));
$query = $this->db->get("user");
if( $query->num_rows == 1 ) {
return true;
}
}
function create_member() {
$new_member_insert_data = array(
'username' => $this->input->post("username"),
'password' => md5($this->input->post("password")),
'email' => $this->input->post("email")
);
$insert = $this->db->insert("user", $new_member_insert_data);
return true;
}
}
?>
I think the column "Password" in your table is less than varchar(32), md5 requires 32 varchar type.
For md5 password
check the data base field, because md5 generate 32 charactors.. so change the table field to varchar(32)
$data=array(
'password' => md5($this->input->post('password')),
);
Just change this statement from
if( $query->num_rows == 1 )
to
if( $query->num_rows() == 1 )
that row() in your
model/membership_model.php
It works
I've been scouring the webs and potching with my code for hours now and can't seem to figure out why this isn't working.
I have a template library which scans a template.html for {#tags} and then runs the function associated to the tag to create data for that {#tag}'s content and then replaces {#tag} for the content generated, so I can have widget like parts to my template.
On my account/access page I have a login form and a registration form, now when the template library calls the widget_register() function, the form validation doesn't seem to do anything, the data is posted as I can see from the profiler, but the form validation doesn't seem to do anything with it
Account Controller
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Account extends CI_Controller {
public function index()
{
$this->load->helper('url');
#redirect('/');
}
public function access()
{
$this->load->helper('url');
#if($this->auth->loggedin()) redirect('/');
$this->template->compile_page();
}
public function widget_register($template)
{
$this->output->enable_profiler(TRUE);
$this->load->helper('url');
if($this->auth->loggedin()) redirect('/');
if ($this->input->post('register_submit'))
{
$this->load->model('auth_model');
$this->form_validation->set_rules('register_nickname', 'Nickname', 'required|min_length[3]|max_length[75]');
$this->form_validation->set_rules('register_email_address', 'Email Address', 'required|valid_email|is_unique[users.email]');
$this->form_validation->set_rules('register_confirm_email_address', 'Confirm Email Address', 'required|valid_email|matches[register_email_address]');
$this->form_validation->set_rules('register_password', 'Password', 'required|min_length[5]');
$this->form_validation->set_rules('register_confirm_password', 'Confirm Password', 'required|min_length[5]|matches[register_password]');
if($this->form_validation->run() !== false)
{
echo 'validation successful';
$nickname = $this->input->post('register_nickname');
$email = $this->input->post('register_email_address');
$generate_salt = $this->auth->generate_keys();
$salt = $generate_salt['1'];
$this->load->library('encrypt');
$generate_password = $salt . $this->input->post('register_password');
$password = $this->encrypt->hash($generate_password);
$generate_series_key = $this->auth->generate_keys();
$user_series_key = $generate_series_key['1'];
$this->db->query('INSERT INTO users (nickname, email, password, salt, register_date) VALUES ( "'.$nickname.'", "'.$email.'", "'.$password.'", "'.$salt.'", "'.time().'")');
}
else
{
echo 'invalid';
echo validation_errors();
}
}
$this->load->helper('form');
$view_data = array();
$view_data['form'] = form_open('account/access');
$view_data['input_nickname'] = form_input(array('name' => 'register_nickname', 'value' => set_value('register_nickname'), 'id' => 'register_nickname', 'class' => 'common_input', 'size' => '55'));
$view_data['input_email'] = form_input(array('name' => 'register_email_address', 'value' => set_value('register_email_address'), 'id' => 'register_email_address', 'class' => 'common_input', 'size' => '55'));
$view_data['input_confirm_email'] = form_input(array('name' => 'register_confirm_email_address', 'value' => '', 'id' => 'register_confirm_email_address', 'class' => 'common_input', 'size' => '55'));
$view_data['input_password'] = form_password(array('name' => 'register_password', 'value' => '', 'id' => 'register_password', 'class' => 'common_input', 'size' => '55'));
$view_data['input_confirm_password'] = form_password(array('name' => 'register_confirm_password', 'value' => '', 'id' => 'register_confirm_password', 'class' => 'common_input', 'size' => '55'));
$view_data['form_submit'] = form_submit('register_submit', 'Register');
$view_data['/form'] = form_close();
$view_data['validation_errors'] = validation_errors('<div class="error-box">', '</div>');
return $this->parser->parse(FCPATH.'themes/'.$this->settings->settings['system_settings']['theme'].'/widgets/'.$template.'.html', $view_data, TRUE);
}
function widget_login()
{
$this->load->helper('url');
// user is already logged in
if ($this->auth->loggedin())
{
return $this->load->view(FCPATH.'themes/'.$this->settings->settings['system_settings']['theme'].'/widgets/login/user.html', '', TRUE);
}
if($this->input->post('register'))
{
redirect('authentication/register');
}
// form submitted
if ($this->input->post('login_email_address') && $this->input->post('login_password'))
{
$this->load->library('form_validation');
$this->load->model('auth_model');
$this->form_validation->set_rules('login_email_address', 'Email Address', 'required|valid_email');
$this->form_validation->set_rules('login_password', 'Password', 'required|min_length[4]');
if($this->form_validation->run() !== false)
{
// validation passed verify from db
$remember = $this->input->post('remember') ? TRUE : FALSE;
if($remember == 'remember');
// check user exists and return user data
$user_data = $this->auth_model->user_exists($this->input->post('email_address'), TRUE);
if($user_data != FALSE)
{
// compare passwords
if ($this->auth_model->check_password($this->input->post('password'), $this->input->post('email_address')))
{
$this->auth->login($user_data->uid, $remember);
redirect('/');
}
else { $this->form_validation->set_custom_error('Incorrect password'); }
}
else { $this->form_validation->set_custom_error('There are no users with that email address'); }
}
}
// show login form
$this->load->helper('form');
$view_data = array();
$view_data['form'] = form_open();
$view_data['input_email'] = form_input('login_email_address', set_value('login_email_address'), 'id="login_email_address"');
$view_data['input_password'] = form_password('login_password', '', 'id="login_password"');
$view_data['input_remember'] = form_checkbox('remember', 'rememberme');
$view_data['form_submit'] = form_submit('login_submit', 'Login');
$view_data['register_button'] = form_submit('register', 'Register');
$view_data['/form'] = form_close();
$view_data['validation_errors'] = validation_errors('<div class="error-box">', '</div>');
return $this->parser->parse(FCPATH.'themes/'.$this->settings->settings['system_settings']['theme'].'/widgets/login/login.html', $view_data, TRUE);
}
function logout()
{
$this->load->helper('url');
$this->session->sess_destroy();
$this->load->helper('cookie');
delete_cookie('aws_session');
delete_cookie('aws_autologin_cookie');
redirect('/');
}
}
and the Template library
class Template {
private $settings;
private $_ci;
private $_controller = ''; # Controller in use
private $_method = ''; # Method in use
private $_is_mobile = FALSE; # Is the User agent a mobile?
private $cache_lifetime = '1';
private $page_output = "";
private $partials = array();
private $spts = array(); # Static page tags
function __construct()
{
$this->_ci =& get_instance();
$this->settings = $this->_ci->settings->settings;
$this->_controller = $this->_ci->router->fetch_class();
$this->_method = $this->_ci->router->fetch_method();
$this->_ci->load->library('user_agent');
$this->_is_mobile = $this->_ci->agent->is_mobile();
log_message('debug', "Template Class Initialized");
}
function build_page()
{
$page = $this->_ci->load->view(FCPATH.'themes/'.$this->settings['system_settings']['theme'].'/pages/'.$this->settings['page_settings']['template'].'.html', '', TRUE);
$this->page_output .= $page;
}
# MAIN PAGE FUNCTIONS END ------------------------------------------------------------------------------------------
public function check_static_tags()
{
if(preg_match_all('/{#[A-Z]{1,75}}/', $this->page_output, $matches))
{
$this->spts = $matches['0'];
$this->spts = array_diff($this->spts, array('{#CONTENT}')); # removes stp_content from array list
return TRUE;
}
return FALSE;
}
# Convert static tags
public function convert_static_tags()
{
foreach($this->spts as $key => $static_tag)
{
$static_tag = str_replace(array('{','}'), '', $static_tag);
$this->partials[$static_tag] = $this->build_widget($static_tag);
}
}
# Convert widget tags
function column_widget_tags()
{
if(preg_match_all('/{#COLUMN_[0-9]{1,11}}/', $this->page_output, $matches))
{
if(isset($this->settings['page_settings']['widgets']))
{
$columns = unserialize($this->settings['page_settings']['widgets']);
}
foreach($columns as $column_id => $widgets)
{
if(count($columns[$column_id]) > '0') // if the column contains widgets
{
$this->partials[''.$this->_stp.'_COLUMN_'.$column_id] = '';
foreach($widgets as $key => $widget_id)
{
// build the widget and add it to the $this->page_bits['column_id'] variable for replacing later in the compiler
$this->partials[''.$this->_stp.'_COLUMN_'.$column_id] .= $this->build_widget($widget_id);
}
}
else
{
$this->partials[''.$this->_stp.'_COLUMN_'.$column_id] = '';
}
}
}
}
# Build Widget
function build_widget($widget_id)
{
if(is_numeric($widget_id))
{
$widget_query = $this->_ci->db->query('SELECT * FROM widgets WHERE id = "'.$widget_id.'"'); # BIND STATEMENTS
}
elseif(preg_match('/#[A-Z]{1,75}/', $widget_id))
{
$widget_query = $this->_ci->db->query('SELECT * FROM widgets WHERE tag = "'.$widget_id.'"'); # BIND STATEMENTS
}
else
{
show_error('Could not get widget from database: '.$widget_id);
}
if($widget_query->num_rows() > 0)
{
$widget_info = $widget_query->row_array();
// loads widgets parent controller, builds the widget (class method) and returns it
$this->_ci->load->controller($widget_info['controller'], $widget_info['controller']);
$method_name = 'widget_'.$widget_info['method'];
$complete_widget = $this->_ci->$widget_info['controller']->$method_name($widget_info['template']);
return $complete_widget;
}
else
{
show_error('The requested widget could not be loaded: '.$widget_id);
}
}
# Replace Partials
function replace_partials()
{
$this->_ci->load->library('parser');
$this->page_output = $this->_ci->parser->parse_string($this->page_output, $this->partials, TRUE);
}
## METADATA
public function prepend_metadata($line)
{
array_unshift($this->_metadata, $line);
return $this;
}
# Put extra javascipt, css, meta tags, etc after other head data
public function append_metadata($line)
{
$this->_metadata[] = $line;
return $this;
}
# Set metadata for output later
public function set_metadata($name, $content, $type = 'meta')
{
$name = htmlspecialchars(strip_tags($name));
$content = htmlspecialchars(strip_tags($content));
// Keywords with no comments? ARG! comment them
if ($name == 'keywords' AND ! strpos($content, ','))
{
$content = preg_replace('/[\s]+/', ', ', trim($content));
}
switch($type)
{
case 'meta':
$this->_metadata[$name] = '<meta name="'.$name.'" content="'.$content.'" />';
break;
case 'link':
$this->_metadata[$content] = '<link rel="'.$name.'" href="'.$content.'" />';
break;
}
return $this;
}
# Embed page into layout wrapper
function layout()
{
$this->_ci->load->helper('html');
$this->append_metadata(link_tag('themes/'.$this->settings['system_settings']['theme'].'/css/layout.css')); # default stylesheet
$this->append_metadata('<link rel="shortcut icon" href="/favicon2.ico" />'); # default favicon
$template['template.title'] = $this->settings['page_settings']['title']; # Page title, can be overidden by the controller ?
$template['template.metadata'] = implode("\n\t\t", $this->_metadata); # Metadata
$template['template.body'] = $this->page_output; # The page
return $this->_ci->parser->parse(FCPATH.'assets/layout/L6_layout_wrapper.html', $template, TRUE);
}
# Run all functions to build page and set in output class
function compile_page($content_data = '')
{
$this->partials['#CONTENT'] = $content_data;
$this->build_page();
$this->column_widget_tags();
if($this->check_static_tags())
{
$this->convert_static_tags();
$this->replace_partials();
}
$output = $this->layout();
$this->_ci->output->set_header('Expires: Sat, 01 Jan 2000 00:00:01 GMT');
$this->_ci->output->set_header('Cache-Control: no-store, no-cache, must-revalidate');
$this->_ci->output->set_header('Cache-Control: post-check=0, pre-check=0, max-age=0');
$this->_ci->output->set_header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
$this->_ci->output->set_header('Pragma: no-cache');
# Let CI do the caching instead of the browser
#$this->_ci->output->cache($this->cache_lifetime);
$this->_ci->output->append_output($output);
}
}
Sorry for the incredibly long post, I'm really stumped here and didn't want to miss any code out, thanks in advance!
The following code is straight from the docs and should insert a row into the "test" table.
$row = &JTable::getInstance('test', 'Table');
if (!$row->bind( array('user_id'=>123, 'customer_id'=>1234) )) {
return JError::raiseWarning( 500, $row->getError() );
}
if (!$row->store()) {
JError::raiseError(500, $row->getError() );
}
My table class looks like this:
class TableTest extends JTable
{
var $user_id = null;
var $customer_id = null;
function __construct(&$db)
{
parent::__construct( '#__ipwatch', 'user_id', $db );
}
}
SELECT queries work fine, but not INSERT ones. Through debugging I find that the query being executed is UPDATE jos_test SET customer_id='1234' WHERE user_id='123', which fails because the row doesn't exist yet in the database (should INSERT instead of UPDATE).
While digging through the Joomla code I find this:
function __construct( $table, $key, &$db )
{
$this->_tbl = $table;
$this->_tbl_key = $key;
$this->_db =& $db;
}
.....
.....
function store( $updateNulls=false )
{
$k = $this->_tbl_key;
if( $this->$k)
{
$ret = $this->_db->updateObject( $this->_tbl, $this, $this->_tbl_key, $updateNulls );
}
else
{
$ret = $this->_db->insertObject( $this->_tbl, $this, $this->_tbl_key );
}
if( !$ret )
{
$this->setError(get_class( $this ).'::store failed - '.$this->_db->getErrorMsg());
return false;
}
else
{
return true;
}
}
_tbl_key here is "user_id" that I passed in my TableTest class, so it would appear that it will always call updateObject() when this key is set. Which is baffling.
Anyone have any insight?
function store( $updateNulls=false )
{
// You set user_id so this branch is executed
if( $this->$k)
{
$ret = $this->_db->updateObject( $this->_tbl, $this, $this->_tbl_key, $updateNulls );
}
// ...
Looking at the code it seems to me that store() check if the primary key field is present and if it use updateObject(). This means if you want to store a new user you can't specify the user_id.
I'm using _remap:
function _remap( $method )
{
// $method contains the second segment of your URI
switch( $method )
{
case 'hello':
$this->index();
break;
}
}
I want to change the url http://localhost/blog to http://localhost/blog/hello
my CI_Controller is:
class Blog extends CI_Controller {
function __construct()
{
parent::__construct();
}
function _remap( $method )
{
// $method contains the second segment of your URI
switch( $method )
{
case 'hello':
$this->index();
break;
}
}
/**/
function index()
{
$g_subject = $this->input->get('id', TRUE);
$query = $this->db->get_where('miniblog', array('id' => $g_subject));
foreach ($query->result() as $row)
{
$data = array(
'subject' => $row->subject,
'title' => $row->title,
'image_path' => $row->image_path,
'alt' => $row->alt,
'text' => $row->text,
'date' => $row->date,
);
}
$this->load->view('miniblog/blog', $data);
//add customer size to databe on customer
//$this->customer_size_model->show();
}
function ipv6()
{
$this->load->view('miniblog/ipv6');
}
}
How can I use this for any dynamic id and replace $row->subject with hello?
Instead of routing all passed methods to index, you could route it to another function and pass the method as the parameter to that function:
function _remap( $method ){
// $method contains the second segment of your URI
switch( $method ){
case 'index':
$this->index();
break;
default:
$this->all_encompasing_method($method);
}
}
function all_encompasing_method($url_param){
// here's my param
echo $url_param;
}