Active record db inserting in codeigniter - codeigniter

I'm working on a project (using codeigniter) where I use a lot of Active record .
The problem i'm facing is the following :
I receive an array of data and i have to fill few tables by using :
$this->db->insert('db_name', $data);
Now sometime $data contains elements not available inside the table so instead i have to do something like :
unset($data['action']);
unset($data['date']);
Before inserting or I just build another array that contains the exact same element of a specific table .
$arr = array( 'x' => $data['x'])
I already used Kohana before and i know when you insert using the ORM it just ignores elements not available in a specific table .
Is there something like that in Codeigniter ?
PS) Without using any external library

CI ActiveRecord is not an ORM. If you want to use an ORM with codeignter, your only option is to use a third-party library: http://datamapper.wanwizard.eu/
You can always loop through the array before sending it to the db and unset data that doesn't contain anything (if in fact the delineator is an empty element):
foreach($data as $k => $v){
if($v == ''){
unset($data[$k]);
}
}
Otherwise, you could create switch spaghetti to unset the elements based on the db and the page sending the data:
switch ($page){
case "page1":
unset($data['blah']);
break;
....
}

As far as I'm aware the built-in feature like that doesn't exist in CI's Active Record (by the way, it is not an ORM).
If unsetting the array elements manually is too much of a hassle, the auto proccess would look like:
function my_insert ($table, $data) {
$query = $this->db->query('SHOW columns FROM '.$table);
$columns = array();
foreach ($query->result_array() as $row) {
$columns[] = $row['Field'];
}
foreach ($data AS $key => $value) {
if (!in_array($key, $columns)) {
unset($data[$key]);
}
}
$this->db->insert($table, $data);
}
It's not tested and some other checks may be needed, but that should help you to take off.

Related

Cache eloquent model with all of it's relations then convert it back to model with relations?

I am trying to optimize a project that is working pretty slow using caching. I'm facing a problem that I don't quite understand how to cache full eloquent models with their relationships and later on covert them back to a model with all relations intact. Here's a fragment of my code
if (Cache::has($website->id.'_main_page')) {
$properties = (array) json_decode(Cache::get($website->id.'_main_page'));
$page = Page::hydrate($properties);
}else{
$expiresAt = now()->addMinutes(60);
$page = Page::with(['sections', 'pageSections.sectionObjects'])->where('website_id', $website->id)->where('main', 1)->first();
Cache::put($website->id.'_main_page', $page->toJson(), $expiresAt);
}
Problem is, hydrate seems to be casting this data as a collection when in fact it's suppose to be a single model. And thus later on I am unable to access any of it's properties without getting errors that they don't exists. $properties variable looks perfect and I would use that but I need laravel to understand it as a Page model instead of stdClass, I also need all of the relationships to be cast into their appropriate models. Is this even possible? Any help is much appreciated
Is there any reason you can't use the cache like this
$page = Cache::remember($website->id.'_main_page', 60 * 60, function () use ($website) {
return Page::with(['sections', 'pageSections.sectionObjects'])
->where('website_id', $website->id)
->where('main', 1)
->first();
});
Conditional
$query = Page::query();
$key = $website->id.'_main_page';
if (true) {
$query = $query->where('condition', true);
$key = $key . '_condition_true';
}
$query::with(['sections', 'pageSections.sectionObjects'])
->where('main', 1)
$page = Cache::remember($key, 60 * 60, function () use ($query) {
return $query->first();
});

`Row `1` must be array` in laravel

I am trying to import csv file in laravel with help of maatwebsite . I have query which is bringing data from two table both have relation with each other. it is exporting only one table data when I try to fetch data of both tables it gives me an error of Row1must be array
$data = SaleOrder::where('id',$id)->with('customers')->get()->toArray();
return Excel::create('Packlist Sale Order '.$id, function($excel) use ($data) {
$excel->sheet('mySheet', function($sheet) use ($data)
{
foreach($data as $customer)
{
$sheet->fromArray($customer['customers']);
}
$sheet->fromArray($data);
});
})->download('xlsx');
I want fetch data of both tables in csv file
You are using a with('customers') which means $data is a multi dimensional array with customers already in it, and likely breaking $sheet->fromArray($data);
If you remove the with('customers') from your query and do this:
foreach($data as $salesOrder)
{
$sheet->fromArray($salesOrder->customers()->get()->toArray());
}
This will load it on demand and leave it out of $data.

How to set form data for a Joomla subform?

I'm trying to create a Joomla (3.x) component and struggling with using subforms. There doesn't seem to be much documentation for using subforms besides e.g. https://docs.joomla.org/Subform_form_field_type
For my component I have one parent table and some associated database rows from a child table.
The idea is to display an edit form for that parent table using Joomla's XML syntax for forms and in that edit form also display a subform with multiple items (the associated rows from the child table).
I would like to be able to modify the parent table fields but also in one go the associated child table rows (of course one could just edit each row associated to the parent table individually but I'm guessing that would be a terrible user experience). Or am I approaching this thing the wrong way?
Now, I know how to implement/show a subform and also know how to show the parent table fields and populate those fields with the right data. But how do I populate or refer to the subform using the parent form?
I have this function inside my component model (which inherits from JModelAdmin).
protected function loadFormData()
{
$data = JFactory::getApplication()->getUserState('com_mycomp.edit.parent.data', array());
if (empty($data))
{
$data = $this->getItem();
// how to refer to subform fields inside $data?
}
return $data;
}
I know if a field is called name or title I can just change the $data object after $this->getItem(), e.g. $this->set('name', 'John Doe').
Let's say the field of type subform has a name attribute of books and I wanted to insert one or more rows, how would I refer to it? I've tried dot syntax in various forms, e.g.: $data->set('books.1.childfield') or $data->set('books.pages1.childfield'). But it doesn't seem to refer to the right form.
There is of course getForm function in the same model file, however I do not think a subform should be loaded independently of the containing parent form?
public function getForm($data = array(), $loadData = true)
{
$app = JFactory::getApplication();
$form = $this->loadForm('com_mycomp.parent', 'parent', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
EDIT:
Already answered my own question.
Never mind. I figured it out after taking a break for some time and trying again (inspecting the form inputs again and taking a deep breath).
This is the format used:
$data->set('nameofsubformfield',
[
'nameofsubformfield0' => [
'fieldwithinsubform' => 'value-of-field-within-subform'
]
]);
This seems to work! I'm using this within getItem function now. Just have to loop and put loop counter in place of the zero after nameofsubformfield. See code below for some context (function resides in parent model).
public function getItem($pk = null)
{
$data = parent::getItem((int)$pk);
if (empty($data))
{
return false;
}
$childModel = JModelLegacy::getInstance('child', 'MycompModel');
$rowChildren = $childModel->getChildrenByParentID((int)$data->get('id'));
$childArray = [];
for ($i = 0; $i < count($rowChildren); $i++)
{
$childArray['children'. $i] = [
'name' => $rowChildren[$i]['name']
];
}
$data->set('children', $childArray);
return $data;
}

How to manipulate the laravel query builder output data using php

Assume I have a simple laravel query builder.
$data = DB::table('users')->get();
(I want to use only query builder and not eloquent since the query will be very complex in reality)
and the table fields are userid, firstname, lastname, gender
before I pass the $data to my view I would like to modify the output data using PHP
Say I wanted to add the prefix Mr or Miss to firstname depending on the gender column or something like that.. (please don't suggest a pure sql solution since the complexity of the condition will be much more complex that just adding a prefix.. I had given this as a simple use case only)
Is it possible ?
just iterate the result
foreach ($data as $key => $value) {
if ($value->gender === 1) {
$value->lastname = 'Mr ' . $value->lastname;
} else if ($value->gender === 0) {
$value->lastname = 'Miss ' . $value->lastname;
}
}

Querying database with select2 based on selection from previous select2

I'm working on a symfony project (using Doctrine as well) and I'd like to implement a staggered search on one of the pages, per example:
User searches for an author in the first select2 box (which is pulling data from DB via Ajax), and once an item is selected, there is a second select2 box called title, which I would like to display only titles belonging to the selected author.
Here's the controller side code (both Ajax and controller) for the initial box. Any ideas how I could construct the query for the second select2?
The part that related to the initial select2 that queries the DB for the results and autosuggested items:
public function searchAjaxAuthorAction()
{
$em = $this->getDoctrine()->getManager();
$term = $this->get('request')->query->get('term');
$limit = $this->get('request')->query->get('page_limit', 1);
$rep = $em->getRepository('StephenPersianArtBundle:Main');
if($term){
$entities = $rep->createQueryBuilder('m')
->where('m.orig_author LIKE ?1')
->orderBy('m.orig_author', 'ASC')
->setParameter('1','%'.$term.'%')
->getQuery();
}else{
$entities = $rep->createQueryBuilder('m')
->groupBy('m.orig_author')
->getQuery();
}
$entities = $entities->execute();
$resultset = array();
foreach($entities as $entity){
if($entity->getOrigAuthor()){
$resultset[] = array(
//'id' => $entity->getId(),
'id' => $entity->getOrigAuthor(),
'text' => $entity->getOrigAuthor()
);
}
}
$return = json_encode($resultset);//jscon encode the array
return new Response($return,200,array('Content-Type'=>'application/json'));
}
There's also another part related to this that basically loads data into a table based on the item selected in the select2, but I don't consider this relevant for the issue I'm having as all this is happening before the final query is completed.
Any help will be much appreciated!

Resources