i want to import excel as json data in Codeigniter with generate id.
my model
public function generateImpId() {
$now = date('ymd');
$check = "SELECT COUNT(*) as count FROM OP_IMP_15 WHERE DATE(OP_IMP_15.created_at) = DATE(NOW())";
$querycheck = $this->db->query($check);
$id = $querycheck->row()->count;
return 'IMPDEMO'.$now.str_pad($id, 4, '0', STR_PAD_LEFT);
}
my controller
//count row
$lastRow = $objPHPExcel->setActiveSheetIndex($sheetnumber)->getHighestRow();
$countrow = $lastRow - 1;
//start loop excel from 2nd row. Row 1 is title row
for ($j=2; $j < $lastRow; $j++ ){
$myArray[] = array(
'site_id' => $objWorksheet->getCell('C'.$j)->getValue(),
'site_name' => $objWorksheet->getCell('D'.$j)->getValue(),
'id_site_doc'=> $objWorksheet->getCell('J'.$j)->getValue(),
'id_project_doc' => $objWorksheet->getCell('K'.$j)->getValue(),
//generate ID from model
'implementation_id' => $this->M_MRCR_A->generateImpId(),
...
the result
{ "site_id":"AR001",
"site_name":"Site AR 001",
"id_site_doc":"5df1b4223269f818adab55af",
"id_project_doc":"5da43895e619143bcff53ab1",
"implementation_id":"IMPDEMO2003310001",
"status":"implementation_created",
"endstate":false,
"created_by":"sgph_pm#mittapp.com",
"counter_mr":"0",
"tech_boq_ids":[
],
...
{ "site_id":"AR002",
"site_name":"Site AR 002",
"id_site_doc":"5df1b4223269f818adab55af",
"id_project_doc":"5da43895e619143bcff53ab2",
"implementation_id":"IMPDEMO2003310001",
"status":"implementation_created",
"endstate":false,
"created_by":"sgph_pm#mittapp.com",
"counter_mr":"0",
"tech_boq_ids":[
],
my expectation
to make "implementation_id" increment based on how many rows the data will be imported and format based on custom ID i'd made (i can't use uuid). ex:
i have 3 row to be imported, so the value of $implementation_id will be : IMPDEMO2003310001, IMPDEMO2003310002, IMPDEMO2003310003
Well since you already have the generated implementation_id value, and I have no idea what the generateImpId() function do, you could manually replace each generated implementation_id with the $j you have :
//count row
$lastRow = $objPHPExcel->setActiveSheetIndex($sheetnumber)->getHighestRow();
$countrow = $lastRow - 1;
//start loop excel from 2nd row. Row 1 is title row
for ($j=2; $j < $lastRow; $j++ ){
$implementation_id = $this->M_MRCR_A->generateImpId();
$implementation_id = substr($implementation_id, 0, -4) . str_pad($j-1, 4, '0', STR_PAD_LEFT); // since $j starts with 2
$myArray[] = array(
'site_id' => $objWorksheet->getCell('C'.$j)->getValue(),
'site_name' => $objWorksheet->getCell('D'.$j)->getValue(),
'id_site_doc'=> $objWorksheet->getCell('J'.$j)->getValue(),
'id_project_doc' => $objWorksheet->getCell('K'.$j)->getValue(),
//generate ID from model
'implementation_id' => $implementation_id,
...
You shoulnd't try to do everything in one single loop.
Maybe you should use a first iteration (for loop) to create the array, and then, a second iteration to fill this implementation_id field.
You can do this by getting the start implementation ID at the start of the loop and just increment it each time (PHP can cope with incrementing a string like this)...
$implementationID = $this->M_MRCR_A->generateImpId();
//start loop excel from 2nd row. Row 1 is title row
for ($j=2; $j < $lastRow; $j++ ){
$myArray[] = array(
// ...
//generate ID from model
'implementation_id' => $implementationID++,
that should give you values like...
IMPDEMO2003310001
IMPDEMO2003310002
IMPDEMO2003310003
Related
I have loop to store my data and it multiple the rows.
example
I have 3 rows with value of test1 and I need to add this rows to become 5
so I have 3 rows already
I add number in input field 2
I loop this 2 number and create new rows
previously 3 rows + 2 new rows = 5 rows in total
but currently I am getting 9 rows.
Code
foreach($request->input('barcodes') as $bb)
{
for ($i = 0; $i < $request->input('nonuiqueAmount'); ++$i) {
$barcode = new Barcode;
$barcode->product_id = $product->id;
$barcode->returned = false;
$barcode->serial_number = $bb['serial_number'];
$barcode->save();
}
}
In case you need a full code with logic here I shared it for you.
Any idea why I get more than my desire rows?
Solved
Thanks to u_mulder suggestion here is how I solved my issue
foreach($request->input('barcodes') as $bb)
{
$bbb = $bb['serial_number']; // added to get single serial number
}
for ($i = 0; $i < $request->input('nonuiqueAmount'); ++$i) {
$barcode = new Barcode;
$barcode->product_id = $product->id;
$barcode->returned = false;
$barcode->serial_number = $bbb; // changed
if($barcode->save()) {
$user = Auth::user();
$outlets = $user->outlets;
foreach($outlets as $outlet) {
DB::table('outlet_products')->insert([
'outlet_id' => $outlet->id,
'barcode_id' => $barcode->id,
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}
I am trying to insert multiple rows of data from select2 fields. Some of the fields in the rows may have multiple selections. My code works with just one row of data and one field having multiple selections as shown in the picture below. But with multiple rows, the insertion does not work as expected. Please good folks, I need your help.
public function save_staff()
{
$subjects = count($this->input->post('subject'));
$names = count($this->input->post('names'));
if($names > 0){
for($i=0; $i < $names; $i++){
for($p=0; $p < $subjects; $p++){
$names_array = array(
'names' => $this->input->post('names')[$i],
'sign' => $this->input->post('sign')[$i],
'subject' => $this->input->post('subject')[$p]
);
$this->db->insert($this->table, $names_array);
}
}
The code above works with just one row of data. And the data in the database is normalized as shown in the second image.. Adding another row of data with one field having multiple selections like the first, my code cannot handle it. How can I adjust code to get it right? The third image captures a screenshot of what my code can't handle.
Try to do this on your input:
<select name="subject[][]" class="form-control selectpicker" multiple>
Controller:
$a1 = $this->input->post('subject');
$count1 = count($a1);
for ($i=0; $i < $count1 ; $i++) {
$count2 = count($a1[$i]);
if(!empty($count2)){
for ($j=0; $j < $count2 ; $j++) {
$names_array = array(
'subject' => $a1[$i][$j]
);
$this->db->insert($names_array);
}
}
}
what does you $this->db->insert() function look like ?
you will probably need to reformat it to follow this:
INSERT INTO table_name
(
col_1,
col_2,
col_3
)
VALUES
( <--- first record being added
'test',
'someValue',
2
),
( <--- second record being added
'test_theSecond',
'someValue',
1234
);
I have a form repeater like this
form repeater image
which submits a code(should be same all through) a product name and a quantity in thousands. eg
code-1234 product-book Qty - 5000
code-1234 product-pen Qty -3000
code-1234 product-ruler Qty -2000
what i would like is to submit to db all the above data as a json with an incrementing id as per total number of items in this case 10,000 and the product name beside each id. The product name should end where its specific quantity end e.g when the ids reach 5000 the next id should be 5001 and the name to begin showing pen.
I have tried this `
//array submited from form
$array = $request->get('arrayName');
foreach ($array as $key => $value) {
$items[] = $value['no_of_items'];
$a_sum = array_sum($items);
$length = 15;
$string = bin2hex(openssl_random_pseudo_bytes($length));
$maxNumberOfItems = $a_sum;
for ($a = 0; $a <= $maxNumberOfItems; $a++) {
if ($a <= reset($items) && $a === $maxNumberOfItems) {
$a = reset($items);
}
echo +$a . " => " . $value['item'] . "<br> ";
$temp = bin2hex(openssl_random_pseudo_bytes($length));
$coupons[] = [
'id' => +$a,
'item' => $value['item'],
'code' => $temp,
'item_status' => 'in-store',
];
}`
It display the names correctly but does not auto increment id as explained above. The moment it reaches say 5000 the next item starts at 0 instead of 5001. Any help would be highly appreciated.
You may need to manually get the MAX(id) and do:
for ($a = $maxId; $a <= $maxNumberOfItems + $maxId; $a++)
I have a for loop, and will form two arrays in the loo
foreach ($data as $key => $value) {
........
........
$user_insert[] = [
'keyy' => $value,
'key' => $value,
....
...
...
];
$someArray1[] = [
/*'user_id' => $insert_id,*/
'key1' => $value1,
'keyy' => $value,
.......
........
];
}
the count of $user_insert[] array is 4, the count of $someArray1 is 15.
after this for loop, I need to insert $user_insert array data to the database and use that inserted_id to insert next array $someArray1
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
foreach ($someArray1 as $someArray) {
$someArray['user_id'] = $insert_id;
DB::table('table_name')->insert($someArray);
}
}
So the problem here is the data in the second loop is inserting 60 times(4 * 15). I need to insert only 15 rows.
The data($someArray1) is coming from the first for loop, but I need to add a user_id to that array which I get after the insert operation in second for loop.
So how can i insert only 15 rows.
I'm going to assume that you are able to access your $someArray1 using the $insert_id value to find the appropriate user data.
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Get the user information you need as $someArray1 should be user_id=>data
$userData = $someArray[$insert_id];
$userData['user_id'] = $insert_id;
// No need for an inner loop, just access the necessary properties of the loop you created earlier.
DB::table('table_name')->insert($userData);
}
Your tags indicate that you are using Laravel 5 too. If you are using the eloquent ORM, some of the insertion and ID retrieval can be cleaned up by creating Models for your DB tables.
Actually, each time you process a line from $user_insert, you loop over $someArray1 instead of fetching just the line you need.
The thing is to understand the line you need. As much as I can understand your piece of code, I would say the easiest (most readable) way of doing it is by using a for loop, not a foreach one :
for( $i = 0, $iMax = count( $user_insert ); $i < $iMax; ++$i ){
$insert_user = $user_insert[$i];
// Put your `$user_insert` insert code here
$someArray1[$i]['user_id'] = $insert_id;
DB::table('table_name')->insert( $someArray[$i] ); // Note the [$i] here
}
You also may do that with foreach by requesting indices :
foreach( $user_insert as $i => $insert_user ){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Now use $i requested above :
$someArray1[$i]['user_id'] = $insert_id;
DB::table( 'table_name' )->insert( $someArray1[$i] );
}
I have database that contains scores which are stored daily. I want to average each months scores for each user. So far I have this:
DB structure:
id | name | tscore | added
int| string | float(100 or less)| date(2014-01-01 16:34:22)
Code:
while($row = mysql_fetch_assoc($getChartData)){ // Data from MySQL
$added_date = explode(' ',$row['added']); // Date formate 2014-01-01 16:34:22
$chartData[] = array(
'id' => $row['name'],
'tscore' => $row['tscore'],
'added' => $added_date[0] // Here I take the month only
);
}
if($_POST['range'] == 'month'){
foreach($chartData as $key => $value){
$added = explode('-',$chartData[$key]['added']);
$count = 1;
foreach($chartData as $key2 => $value2){
$added2 = explode('-',$chartData[$key2]['added']);
if($chartData[$key]['id'] === $chartData[$key2]['id'] && $added[1] === $added2[1]){ // if user is the same and the month is the same, add the scores together, increment counter, and unset 2nd instance
$chartData[$key]['tscore'] = ((float)$chartData[$key]['tscore'] + (float)$chartData[$key2]['tscore']);
$count++;
unset($chartData[$key2]);
}
}
$chartData[$key]['tscore'] = ($chartData[$key]['tscore']/$count); // Average all the scores for the month.
}
}
The problem is this method is deleting all the elements of the $chartData array. What can I try to resolve this?
You should try to solve it with MySQL. Try something like this (replace 'your_scores_table' with your table name):
SELECT
Score.name,
AVG(Score.tscore) AS `avg`,
CONCAT(YEAR(Score.added), '-', MONTH(Score.added)) AS `year_month`
FROM
your_scores_table AS Score
GROUP BY
Score.name ASC,
YEAR(Score.added) DESC,
MONTH(Score.added) DESC
;
Your logic is wrong. You are looping through the same array twice. Which means that the following if will always evaluate to true which means that array item will always get unset
//This will always be true
if($chartData[$key]['id'] === $chartData[$key2]['id'] && $added[1] === $added2[1]){
It may be simpler for you to create another array where you keep your scores. Something like
$aScores = array();
$count = 1;
foreach($chartData as $key => $value){
//Add score to a different array
$aScores[$value['name']]['tscore'] = (($aScores[$value['name']]['tscore'] + $value['tscore']) / $count);
$count++;
}
Also I would look into the MySQL AVG function. You could use that to save you having to do it in PHP