When I Use Query Builder Function in codeIgniter, then Error message not shown.
Here Is a Controller
<?php
class Controller extends CI_Controller
{
public function demo()
{
$this->load->model("Model");
$data["name"] = $this->input->post("text");
$res = $this->Model->add_data($data);
echo $res;
}
}
?>
Here Is a Model
<?php
class Model extends CI_Model
{
public function add_data($data)
{
if ( ! $this->db->insert("table_name",$data))
{
$error = $this->db->error();
return $error["message"];
}
}
}
?>
Try this in your model
$data = array(
'title' => 'My title',
'name' => 'My Name',
'date' => 'My date'
);
$sql = $this->db->set($data)->get_compiled_insert('mytable');
echo $sql;
if (!$this->db->simple_query($sql)) {
$error = $this->db->error(); // Has keys 'code' and 'message'
}
echo'<pre>';print_r($error);die;
INSERT INTO mytable (title, name, date) VALUES ('My title', 'My Name', 'My date')
Array
(
[code] => 1146
[message] => Table 'db.mytable' doesn't exist
)
Put this in your model and display it :
In CodeIgniter 3 like #Viren Panchal said, use this : error();
In your example :
$this->db->db_debug = false;
$res = $this->Model->add_data($data);
if(!$res) {
$error = $this->db->error();
echo $error;
}
Related
how i want to show customer groups in my custome module, like "NOT LOGGED IN - General" or "NOT LOGGED IN - General - Wholesale - Retailer",
this is my code in grid
$this->addColumn(
'customer_group',
[
'header' => __('Customer Groups'),
'index' => 'customer_group',
'class' => 'customer_group',
'type' => 'options',
'renderer' => 'Rendy\ModuleWarehouse\Block\Adminhtml\Warehouse\Renderer\CustomerGroups'
]
);
and this is my code CustomerGroups
namespace Rendy\ModuleWarehouse\Block\Adminhtml\Warehouse\Renderer;
use Magento\Framework\DataObject;
class CustomerGroups extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
protected $_customerGroup;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Customer\Model\ResourceModel\Group\Collection $customerGroup,
array $data = []
) {
$this->_customerGroup = $customerGroup;
parent::__construct($context, $data);
}
/**
* Get customer groups
*
* #return array
*/
public function render(DataObject $row) {
$customerGroups = $this->_customerGroup->toOptionArray();
array_unshift($customerGroups, array('value'=>'', 'label'=>'Any'));
}
}
thank you
Ever get this solved? You could use \Magento\Customer\Model\GroupFactory in your construct:
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Customer\Model\GroupFactory $groupFactory
array $data = []
) {
$this->_groupFactory = $groupFactory;
parent::__construct($context, $data);
}
It is nice because you can then do in your render function:
$collection = $this->groupFactory->create()->getCollection();
foreach ($collection as $group) {
echo "group id ".$group->getId();
echo "group code ".$group->getCode();
}
I have this model function below which lets me join both tables. Printed results are at bottom of question.
<?php
class Forum_model extends CI_Model {
public function get_forums() {
$this->db->select('f.*, fc.*');
$this->db->from('forum_category fc', 'left');
$this->db->join('forum f', 'f.forum_id = fc.category_forum_id', 'left');
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result_array();
} else {
return false;
}
}
}
How ever when I go to look at in on my view it displays it like image below
The two General categories news, lounge should be displayed on the one panel. For some reason it displays the two general categories in own panel.
Question: How is it possiable to display the two categories together? I have tried $this->db->group_by('fc.category_forum_id')
Image
Controller
<?php
class Home extends MY_Controller {
public function __construct() {
parent::__construct();
$this->load->model('reports/thread_analytics_model');
$this->load->model('forum/forum_model');
}
public function index() {
$results = $this->forum_model->get_forums();
echo "<pre>";
print_r($results);
echo "</pre>";
$data['forums'] = array();
foreach ($results as $result) {
$data['forums'][] = array(
'forum_name' => $result['forum_name'],
'category_name' => $result['category_name']
);
}
$data['content'] = 'common/home_view';
$this->load->view('theme/default/template_view', $data);
}
}
View
<?php foreach ($forums as $forum) {?>
<div class="panel panel-home">
<div class="panel-heading"><h1 class="panel-title"><?php echo $forum['forum_name'];?></h1></div>
<div class="panel-body">
<table class="table">
<tbody>
<tr>
<td><?php echo $forum['category_name'];?></td>
</tr>
</tbody>
</table>
</div>
</div><!-- Panel -->
<?php }?>
Printed Results Image
A possible solution with your approach would be:
class Forum_model extends CI_Model {
public function get_forums() {
$arrGroupedData = array();
$this->db->select('f.*, fc.*');
$this->db->from('forum_category fc');
$this->db->join('forum f', 'f.forum_id = fc.category_forum_id', 'left');
$query = $this->db->get();
if ($query->num_rows() > 0)
{
foreach($query->result_array() AS $arrCategory)
{
$arrGroupedData[$arrCategory['forum_id']][] = $arrCategory;
}
return $arrGroupedData;
} else {
return false;
}
}
}
But in my opinion - you should probably split up your queries
1 query to get the forums and 1 query to get all categories from your forums
and stick it together in a tree structure
example for you
$forums = array();
$results = array(
array(
'forum_name' => 'general',
'category_name' => 'news1'
),
array(
'forum_name' => 'general',
'category_name' => 'news2'
),
array(
'forum_name' => 'latter',
'category_name' => 'news3'
),
);
foreach ($results as $result)
{
if(in_array($result['forum_name'],$forums))
{
$array = array($result['category_name']);
array_push($forums[$result['forum_name']],$array);
}
else
{
$forums[$result['forum_name']][] = array(
'forum_name' => $result['forum_name'],
'category_name' => $result['category_name']
);
}
}
echo '<pre>';
print_r($forums);
I have worked on a hook for validate my translated fields, based on this thread : https://stackoverflow.com/a/33070156/4617689. That i've done do the trick, but i'm looking for you guys to help me to improve my code, so feel free to comment and modify
class ContentbuildersTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Tree');
$this->addBehavior('Timestamp');
$this->addBehavior('Translate', [
'fields' => [
'slug'
]
]);
}
public function validationDefault(Validator $validator)
{
$data = null; // Contain our first $context validator
$validator
->requirePresence('label')
->notEmpty('label', null, function($context) use (&$data) {
$data = $context; // Update the $data with current $context
return true;
})
->requirePresence('type_id')
->notEmpty('type_id')
->requirePresence('is_activated')
->notEmpty('is_activated');
$translationValidator = new Validator();
$translationValidator
->requirePresence('slug')
->notEmpty('slug', null, function($context) use (&$data) {
if (isset($data['data']['type_id']) && !empty($data['data']['type_id'])) {
if ($data['data']['type_id'] != Type::TYPE_HOMEPAGE) {
return true;
}
return false;
}
return true;
});
$validator
->addNestedMany('translations', $translationValidator);
return $validator;
}
}
I'm not proud of my trick with the $data, but i've not found a method to get the data of the validator into my nestedValidator...
Important part here is to note that i only rule of my nestedValidator on 'translations', this is very important !
class Contentbuilder extends Entity
{
use TranslateTrait;
}
Here basic for I18ns to work
class BetterFormHelper extends Helper\FormHelper
{
public function input($fieldName, array $options = [])
{
$context = $this->_getContext();
$explodedFieldName = explode('.', $fieldName);
$errors = $context->entity()->errors($explodedFieldName[0]);
if (is_array($errors) && !empty($errors) && empty($this->error($fieldName))) {
if (isset($errors[$explodedFieldName[1]][$explodedFieldName[2]])) {
$error = array_values($errors[$explodedFieldName[1]][$explodedFieldName[2]])[0];
$options['templates']['inputContainer'] = '<div class="input {{type}} required error">{{content}} <div class="error-message">' . $error . '</div></div>';
}
}
return parent::input($fieldName, $options);
}
}
With that formHelper we gonna get the errors of nestedValidation and inject them into the input, i'm not confortable with the templates, so that's why it's very ugly.
<?= $this->Form->create($entity, ['novalidate', 'data-load-in' => '#right-container']) ?>
<div class="tabs">
<?= $this->Form->input('label') ?>
<?= $this->Form->input('type_id', ['empty' => '---']) ?>
<?= $this->Form->input('is_activated', ['required' => true]) ?>
<?= $this->Form->input('translations.fr_FR.slug') ?>
<?= $this->Form->input('_translations.en_US.slug') ?>
</div>
<?php
echo $this->Form->submit(__("Save"));
echo $this->Form->end();
?>
Here my fr_FR.slug is required when type_id is not set to Type::TYPE_HOMEPAGE, yeah my homepage has not slug, note that the en_US.slug is not required at all, because i only required 'translations.xx_XX.xxxx' and not '_translations.xx_XX.xxxx'.
And the last part of the code, the controller
$entity = $this->Contentbuilders->patchEntity($entity, $this->request->data);
// We get the locales
$I18ns = TableRegistry::get('I18ns');
$langs = $I18ns->find('list', [
'keyField' => 'id',
'valueField' => 'locale'
])->toArray();
// Merging translations
if (isset($entity->translations)) {
$entity->_translations = array_merge($entity->_translations, $entity->translations);
unset($entity->translations);
}
foreach ($entity->_translations as $lang => $data) {
if (in_array($lang, $langs)) {
$entity->translation($lang)->set($data, ['guard' => false]);
}
}
Here a .gif of the final result om my side : http://i.giphy.com/3o85xyrLOTd7q0YVck.gif
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();
Just want to validate my codeigniter dropdown form before adding the selected country to database. The problem is that it inserts default value 'selectcountry' into db instead of showing the message "Please choose your country." Please help me :)
Here is My Model:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Model_example extends CI_Model {
function __construct()
{
//Call the Model constructor
parent::__construct();
}
public function did_add() {
$data = array(
'country' => $this->input->post('country')
);
$query = $this->db->insert('example_table', $data);
if ($query) {
return true;}
else {
return false;}
}
}
Here is My View:
$this->load->helper("form","file","html","url");
echo $message;
echo validation_errors();
echo form_open("example/add");
echo form_label("Country:<br>","country");
$data = array(
"selectcountry" => "Select Country",
"CA" => "Canada",
"US" => "United States",
"ZW" => "Zimbabwe"
);
echo form_dropdown('country', $data, 'selectcountry');
echo br(1);
echo form_submit("Submit", "Add");
echo form_close();
Here is My controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Example extends MX_Controller {
public function index() {
$data["message"] = "";
$this->load->view("view_example",$data);
}
public function add() {
$this->load->library('form_validation');
$this->load->model('model_example');
$this->form_validation->set_rules('country', 'Country', 'required|callback_country_check');
if($this->form_validation->run()){
$this->model_example->did_add();
}
else {
$data["message"] = "";
$this->load->view("view_example",$data);
}
}
public function country_check()
{
if ($this->input->post('country') === 'selectcountry') {
$this->form_validation->set_message('country_check', 'Please choose your country.');
return FALSE;
}
else {
return TRUE;
}
}
}
In your view page change this line
$data = array(
"selectcountry" => "Select Country",
"CA" => "Canada",
"US" => "United States",
"ZW" => "Zimbabwe"
);
echo form_dropdown('country', $data, 'selectcountry');
to this
$data = array(
"" => "Select Country",
"CA" => "Canada",
"US" => "United States",
"ZW" => "Zimbabwe"
);
echo form_dropdown('country', $data, set_value('country'));
You wont need another call back function to check if value is empty.