I'm inserting an array of multiple inputs. but when i dd it or create it doesn't insert or returning any values. How can i use create in this situation? I'm new to laravel.
foreach ($data['sku'] as $key => $val) {
$attrCountSKU = ProductsAttribute::where('sku', $val)->count();
if ($attrCountSKU > 0) {
return back()->with('error', 'SKU already exists for this product! Please input another SKU.');
}
$attrCountSizes = ProductsAttribute::where(['product_id' => $product->id, 'size' => $data['size'][$key]])->count();
if ($attrCountSizes > 0) {
return back()->with('error', 'Size already exists for this product! Please input another Size.');
}
$attribute = new ProductsAttribute;
$attribute->product_id = $product->id;
$attribute->sku = $val;
$attribute->size = $data['size'][$key];
$attribute->price = $data['price'][$key];
$attribute->stock = $data['stock'][$key];
dd($attribute);
dd($attribute->create());
}
You need to save the model, using the save() method.
Add this after setting all the attributes:
$attribute->save();
return $attribute->id // Will be set as the object has been inserted
You could also use the create() method to create and insert the model in one go:
$attribute = ProductsAttribute::create([
'product_id' => $product->id,
'sku' => $val,
'size' => $data['size'][$key],
'price' => $data['price'][$key],
'stock' => $data['stock'][$key],
]);
Laravel Docs: https://laravel.com/docs/5.8/eloquent#inserting-and-updating-models
Instead of $attribute->create() you should use $attribute->save() method.
Or with the create() method you can do like this
$flight = ProductsAttribute::create(
[
'product_id' => $product->id,
'sku' => $val,
'size' => $data['size'][$key],
'price' => $data['price'][$key],
'stock' => $data['stock'][$key],
]
);
Related
I need to fill an array with a dynamic list of products.
To do so, I'm using the following code:
$list_array = array(
$products[] = array(
'SKU' => '0001',
'Title' => 'Bread',
'Quantity' => '',
),
$products[] = array(
'SKU' => '0002',
'Title' => 'Butter',
'Quantity' => '',
)
);
return $list_array;
It works fine if I know every product in the array.
But in my use case I have no idea which products are in the array.
So I want to fill the array with dynamic data.
I came up with something this:
$products = get_posts( 'numberposts=-1&post_status=publish&post_type=product' );
foreach ( $products as $product ) {
$products[] = array(
'SKU' => $product->id,
'Title' => $product->post_title,
'Quantity' => '',
),
}
return $products;
I know there is something really wrong with the array. But I couldn't figure out what it is.
The code you submitted cannot work. The short syntax $a[] = ... is to append data to the $a array, for example:
$a = [];
$a[] = 1;
$a[] = 2;
// $a = [1, 2]
You can also do it in a more efficient way with a map function:
function reduce($product)
{
return array(
'SKU' => $product->id,
'Title' => $product->post_title,
'Quantity' => '',
);
}
return array_map('reduce', $products);
It will execute the function reduce and replace value for each element of you array. Complete doc here: https://www.php.net/manual/en/function.array-map.php
Your problem is that you are overwriting the $products array that you are looping over inside the loop. Change the name of the variable in the loop to fix that:
$list_array = array();
foreach ( $products as $product ) {
$list_array[] = array(
'SKU' => $product->id,
'Title' => $product->post_title,
'Quantity' => ''
);
}
return $list_array;
I am working on populating the database tables. The table have fields which some of them are enum.
Consider a user which have a field status , whose values can be active, inactive etc. Assume we can modify the configuration values and running the script the data can be populated accordingly.
Let us represent the user table whose status field as
'status' => array(
'active' => 3,
'inactive',
'deleted',
),
In this case assume we need to create 3 users with status , active. 1 user with status inactive and 1 with deleted.
The table may be having more enum fields. So the config can expand. Depending on the configuration and fields the values will be multiples.
Consider the below example.
Eg :
$config = array(
'table1name' => array(
'field1' => array(
'active' => 3,
'inactive',
'deleted',
),
'field2' => array(
'admin',
'user',
'editor'
),
....,
'more-fields' => array(
'more-values',
)
),
'table2name' => array(
'field1' => array(
'active',
'inactive',
'deleted',
),
)
);
In this case there need to populate table1 whose field field1 with active, inactive, deleted and roles with admin, user, editor etc. ( The active, inactive etc are provided just for example. It can be just values. )
The idea is to generate more users depending on the count if any provided.
Eg :
'status' => array(
'active' => 10,
'inactive' => 2,
'deleted' => 3,
),
'roles' => array(
'admin' => 2,
'user',
'editor'
)
....,
'more-fields' => array(
'more-values',
)
So that there will be
10 * 4 => active users (10 * 2 active admin / 10 active user, 10 active editor ) +
2 * 4 => inactive users ( 2 inactive admin , 1 user, 1 editor ) +
3 * 4 => deleted users in total.
I am struggling to build the algorithm for the same.
array(
'status' => array(
'active' => 10,
'inactive' => 2,
'deleted' => 3,
),
'roles' => array(
'admin' => 2,
'user',
'editor'
),
....,
'more-fields' => array(
'more-values',
)
)
// In this example you can see we have not covered the fields of the table when they are more than 1 on save.It looks we need to build the array with values first.
foreach ($config as $table => $fields) {
foreach ($fields as $field => $values ) {
foreach ($values as $key => $statusCount) {
if (is_string($key)) {
$model = new User();
$model->$field = $key;
$model->another = 'value';
$model->save();
} else {
for ($i = 0; $i< $statusCount; $i++) {
$model = new User();
$model->$field = $key;
$model->another = 'value';
$model->save();
}
}
}
}
}
UPDATE :
Changes made according to #the-fourth-bird answer https://stackoverflow.com/a/33354032/487878
Problem is it only look for 2 fields, the fields can be 1 or n.
Are you looking for a setup like this? (Not sure what the fields for the User can be, I used 'role' and 'admin' in this example.)
$fields = array(
'status' => array(
'active' => 10,
'inactive' => 2,
'deleted' => 3,
),
'roles' => array(
'admin',
'user',
'editor'
)
);
$roles = $fields['roles'];
$statuses = $fields['status'];
foreach ($roles as $role) {
foreach ($statuses as $status => $statusCount) {
for ($i = 0; $i< $statusCount; $i++) {
$model = new User();
$model->role = $role;
$model->status = $status;
}
}
}
// Update with dynamic properties
<?php
class table1name {
public function save() {}
}
class table2name {
public function save() {}
}
$config = array(
'table1name' => array(
'field1' => array(
'active' => 3,
'inactive',
'deleted',
),
'field2' => array(
'admin',
'user' => 2,
'editor'
),
'more-fields' => array(
'more-values' => 2,
),
'color' => array(
'blue' => 2,
'red'
),
),
'table2name' => array(
'field1' => array(
'active',
'inactive',
'deleted',
),
)
);
// Adjust data structure
// If the key is a string, turn the key into values for the given multiplier in the same array.
// Then unset the key.
foreach ($config as $table => $fields) {
foreach ($fields as $field => $values ) {
foreach ($values as $key => $statusCount) {
if (is_string($key)) {
for ($i = 0; $i< $statusCount; $i++) {
$config[$table][$field][] = $key;
}
unset($config[$table][$field][(string)$key]);
}
}
}
}
$cartesians = [];
// If you want all the possible combinations for for example the 'table1name', you need a cartesian product. Used the function from this page:
//http://stackoverflow.com/questions/6311779/finding-cartesian-product-with-php-associative-arrays
function cartesian($input) {
$input = array_filter($input);
$result = array(array());
foreach ($input as $key => $values) {
$append = array();
foreach($result as $product) {
foreach($values as $item) {
$product[$key] = $item;
$append[] = $product;
}
}
$result = $append;
}
return $result;
}
// Create the cartesian products for all the keys in the $config array.
foreach ($config as $key => $tables) {
$cartesians[$key] = cartesian($tables);
}
// Loop all the objects created by the cartesian function.
foreach ($cartesians as $objectName => $cartesian) {
foreach($cartesian as $key => $value) {
$model = new $objectName();
$model->$key = $value;
$model->save();
}
}
I never used generators in PHP. I understand the way to use it :
Foreach an array to do some tasks for each value like greping a specific line into a big file to remove some caracteres..
What I need :
I need to retrieve all bands from my dabatase. Sure I have the 'limit' argument to don't exceed the PHP's memory (there're 30 000 bands..).
I have to filters values and return a new array to the client into my REST API.
What I want to know :
Is it interesting for me to create a method into a trait called 'generator' to perform the code bellow ?
In all cases, I have to create a new array to return it into my method
$bands = Models\Bands::find($bandsParameters);
$json = [];
foreach ($bands as $band) {
$followers = $band->getFollowers();
$followersArr = [];
foreach ($followers as $follower) {
$followerImage = $follower->getImage();
$followerObj = (object)[
'id' => $follower->id,
'username' => $follower->username,
'image' => $followerImage->url,
'online' => $follower->online,
'createdOn' => $follower->createdOn,
'updatedOn' => $follower->updatedOn,
'lastLogin' => $follower->lastLogin,
];
$followersArr[] = $followerObj;
}
$info = $band->getInfo($bandInfoParameters)->getFirst();
$bandObj = (object)[
'id' => $band->id,
'name' => $band->name,
'style' => $band->styles,
'country' => $band->country,
'summary' => isset($info->summary) ? $info->summary : null,
'followers' => $followersArr,
'createdOn' => $band->createdOn,
'updatedOn' => $band->updatedOn,
'authoredBy' => $band->authoredBy,
'updatedBy' => $band->updatedBy,
];
$json[] = $bandObj;
}
return ['key' => 'bands', 'value' => $json];
I have a form for a hotel site, where I want to update its services, and the client wants to update multiple services at a time. However I'm lost as how to save it in the database with the model.
I already built my controller, it looks something like this:
$items = array(
array(
'id' => $this->input->post('id1', true),
'hotel_id' => $hotel_id,
'des_servicio' => $this->input->post('des_servicio1', true),
'est_activo' => $this->input->post('est_activo1', true)
),
array(
'id' => $this->input->post('id2', true),
'hotel_id' => $hotel_id,
'des_servicio' => $this->input->post('des_servicio2', true),
'est_activo' => $this->input->post('est_activo2', true)
),
array(
'id' => $this->input->post('id3', true),
'hotel_id' => $hotel_id,
'des_servicio' => $this->input->post('des_servicio3', true),
'est_activo' => $this->input->post('est_activo3', true)
)
);
$this->hotel_model->save_multiple($items);
[UPDATE]
this is how my new model looks like:
function save_multiple($items = array())
{
$this->db->insert_batch($this->__tabla, $items);
return $this->db->affected_rows();
}
My issue is that now it creates 10 rows (my original form has 10 fields) even if I only populate 3 fields. So in my database 3 services get stored, and also 7 blank rows. How can change this?
foreach $items //I get an error here
as $item
should be
foreach ( $items as $item )
Remember that input->post() returns false if the value is not set. So check to see if the value is set be for putting it in the array. Then when the model receives it. It saves them all. Or the other option is to create a new array in the model from the array that is passed in and then pass the new array to the insert_batch() function.
$items = array();
$id = $this->input->post('id1', true);
if( $id != false ) {
$items[] = array(
'id' => $id, true),
'hotel_id' => $hotel_id,
'des_servicio' => $this->input->post('des_servicio1', true),
'est_activo' => $this->input->post('est_activo1', true)
);
}
$id = $this->input->post('id2', true);
if( $id != false ) {
$items[] = array(
'id' => $id, true),
'hotel_id' => $hotel_id,
'des_servicio' => $this->input->post('des_servicio2', true),
'est_activo' => $this->input->post('est_activo2', true)
);
}
....
I have created a component in joomla 2.5 that creates a new article and adds that article to a menu item.
Creating the article is working fine, but I am having some trouble with creating the menu item.
I have the following code:
//add the article to a menu item
$menuTable = JTable::getInstance('Menu', 'JTable', array());
$menuData = array(
'menutype' => 'client-pages',
'title' => $data[name],
'type' => 'component',
'component_id' => 22,
'link' => 'index.php?option=com_content&view=article&id='.$resultID,
'language' => '*',
'published' => 1,
'parent_id' => '1',
'level' => 1,
);
// Bind data
if (!$menuTable->bind($menuData))
{
$this->setError($menuTable->getError());
return false;
}
// Check the data.
if (!$menuTable->check())
{
$this->setError($menuTable->getError());
return false;
}
// Store the data.
if (!$menuTable->store())
{
$this->setError($menuTable->getError());
return false;
}
The error seems to be with setting the parent_id and level. On debugging libraries/joomla/database/tablenested.php sets the parent_id and level to 0. This caused the following error on my administrator page:
Warning: str_repeat() [function.str-repeat]: Second argument has to be greater than or equal to 0 in /Applications/MAMP/htdocs/joomla_2_5/administrator/components/com_menus/views/items/tmpl/default.php on line 129
Try using JTableNested::setLocation($referenceId, $position = 'after'):
$table->setLocation($parent_id, 'last-child');
I also think that you need to rebuild the path:
// Rebuild the tree path.
if (!$table->rebuildPath($table->id)) {
$this->setError($table->getError());
return false;
}
If it still doesn't work, try to find out what MenusModelItem::save does that you don't.
$table->setLocation($parent_id, 'last-child');
is all that is needed to ensure that left/right values are created correctly for the new menu item. There is no need to rebuild the path as this is now handled by JTableMenu's store method.
Additionally, the convenience method "save" can be used to bind, check and store the menu item:
$menuItem = array(
'menutype' => 'client-pages',
'title' => $data[name],
'type' => 'component',
'component_id' => 22,
'link' => 'index.php?option=com_content&view=article&id='.$resultID,
'language' => '*',
'published' => 1,
'parent_id' => $parent_id,
'level' => 1,
);
$menuTable = JTable::getInstance('Menu', 'JTable', array());
$menuTable->setLocation($parent_id, 'last-child');
if (!$menuTable->save($menuItem)) {
throw new Exception($menuTable->getError());
return false;
}
Somehow $menutable does not update parent_id and level in database table so you have to manually update those two fields by joomla query.
$menuTable = JTable::getInstance('Menu', 'JTable', array());
$menuData = array(
'menutype' => 'client-pages',
'title' => $data[name],
'type' => 'component',
'component_id' => 22,
'link' => 'index.php?option=com_content&view=article&id='.$resultID,
'language' => '*',
'published' => 1,
'parent_id' => '1',
'level' => 1,
);
// Bind data
if (!$menuTable->bind($menuData))
{
$this->setError($menuTable->getError());
return false;
}
// Check the data.
if (!$menuTable->check())
{
$this->setError($menuTable->getError());
return false;
}
// Store the data.
if (!$menuTable->store())
{
$this->setError($menuTable->getError());
return false;
}
$db = $this->getDbo();
$qry = "UPDATE `#__menu` SET `parent_id` = 1 , `level` = 1 WHERE `id` = ".$menuTable->id;
$db->setQuery($qry);
$db->query();
This code worked for me
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_menus/tables/');
$menuTable =& JTable::getInstance('menu', 'menusTable');
$menuData = array(
'menutype' => 'client-pages',
'title' => 'mytrialmenu',
'type' => 'component',
'component_id' => 22,
'link' => 'index.php?option=index.php? option='com_content&view=article&id='.$resultID,
'language' => '*',
'published' => 1,
'parent_id' => 'choose some parent',
'level' => 1,
);
// Bind data
if (!$row->bind($menuData))
{
$this->setError($menuTable->getError());
return false;
}
// Check the data.
if (!$row->check())
{
$this->setError($menuTable->getError());
return false;
}
// Store the data.
if (!$row->store())
{
$this->setError($menuTable->getError());
return false;
}
I think the reason is menusTable extends JnestedTable which is required for manipulating lft and rgt fields in the menu table