skip to Main Content

I need to store my contacts table data which I get through user input like below array:

0 => array:5 [▶]
  1 => array:5 [▼
    0 => "John Doe"
    1 => "[email protected]"
    2 => "15551-234567"
    3 => "New York, NY"
    4 => "230"
  ]
  2 => array:5 [▼
    0 => "Jane Smith"
    1 => "[email protected]"
    2 => "15552345678"
    3 => "Los Angeles, CA"
    4 => "5201"
  ]
  3 => array:5 [▼
    0 => "Robert Johnson"
    1 => "[email protected]"
    2 => "8.80156E+13"
    3 => "Chicago, IL"
    4 => "4110"
  ]
  4 => array:5 [▶]
  5 => array:5 [▶]
  6 => array:5 [▶]
  7 => array:5 [▶]
  8 => array:5 [▶]
]

And I have anther input tag which I need to index the previous array to store in my contacts table.

  0 => "contact_name"
  1 => "Select Schema"
  2 => "contact_number"
  3 => "Select Schema"
  4 => "Select Schema"
]

I have used following lines of codes to index it and store it into database. But the problem is I got only first index data of every row.

Means if my tag array input comes contact_name , contact_number I need to get the $contactToBeInserted array as below:

  0 => array:2 [▼
    "contact_name" => "John Doe"
    "contact_number" => "15551-234567"
  ]
  1 => array:2 [▼
    "contact_name" => "Jane Smith"
    "contact_number" => "15552345678"
  ]

But I only get contact_name in $contactToBeInserted array.

   0 => array:1 [▼
        "contact_name" => "john doe"
      ]
      1 => array:1 [▼
        "contact_name" => "Robert"
      ]

Why’s that? Is there any efficient way to indexing the data and get the exact output I want?

public function saveReviewData(Request $request)
{
    $allowedTags = ['contact_name','contact_email','contact_number','contact_location'];
    $contactToBeInserted = [];

    foreach($request->tag as $tagIndex => $tag) 
    {
        if (!in_array($tag, $allowedTags)) 
        {
            continue;
        }

        foreach(array_slice($request->data, 1) as $index => $contactData) 
        {

            $contactToBeInserted[$index][$tag] = $contactData[$tagIndex];

            $this->validate($request, [
                'contact_number' => [
                    Rule::unique('contacts')->where(function ($query) {
                        $query->where('user_id', '=', Auth::user()->id);
                    })
                ],
            ]);

            $contact = new Contact();
            $contact->contact_name = $contactToBeInserted[$index]['contact_name'] ;
            $contact->contact_email = $contactToBeInserted[$index]['contact_email'] ;
            $contact->contact_number = preg_replace('/[^0-9]+/', '',  $contactToBeInserted[$index]['contact_number']);
            $contact->contact_location = $contactToBeInserted[$index]['contact_location'];
            $contact->user_id = Auth::user()->id;
            $contact->save(); 
        }

    }

    return redirect('contacts');
}

2

Answers


  1. The problem is that you are using two nested loops, but you are only considering the outer loop index $tagIndex to access the data in the inner loop $contactData. This results in overwriting the values.

    Use array_combine to use tags as key and each data as value.

    foreach ($request->data as $dataIndex => $data) {
        $combinedData = array_combine($request->tag, $request->data[$dataIndex]);
    }
    dd($contactsToBeInserted);
     
    

    After that, to check if all tags are allowed, use array_diff_key . If there are no differences, insert into the array.

    foreach ($request->data as $dataIndex => $data) {
         $combinedData = array_combine($request->tag, $request->data[$dataIndex]);
    
         // Check if all tags are in allowed tags
         if (!array_diff_key($combinedData, array_flip($allowedTags))) { 
             $contactsToBeInserted[] = $combinedData;    
         }
         dd($contactsToBeInserted);
    }
    
    Login or Signup to reply.
  2. To test my advice as native, runnable PHP, I’ve replaced some of the Laravel specific components with basic outputting.

    It seems logical to me that your "$allowedTags" are actually "$requiredTags". Meaning if any of these fields are missing, then the request should not attempt to save the contact. For this reason, compare the incoming array of tags against the required tags; if not fully satisfied, do not process the data payload.

    The next step is to iterate the rows in the data payload, and map the indexed values to the corresponding property names for each object to be saved.

    Code: (Demo)

    function saveReviewData($request)
    {
        $requiredTags = ['contact_name', 'contact_email', 'contact_number', 'contact_location'];
        
        $approvedKeys = array_intersect($request->tag, $requiredTags);  // remove irrelevant keys
        if ($approvedKeys != $requiredTags) { // is the mapping array missing required values
            throw new Exception(
                sprintf(
                    'Request did not include required tags: %s',
                    implode(', ', array_diff($requiredTags, $request->tag))
                )
            );
        }
    
        foreach ($request->data as $row) {
            /*
            $this->validate($request, [
                'contact_number' => [
                    Rule::unique('contacts')->where(function ($query) {
                        $query->where('user_id', '=', Auth::user()->id);
                    })
                ],
            ]);
            */
            $contact = (object) [];
            $contact->user_id = 1; // Auth::user()->id;
            foreach ($approvedKeys as $i => $k) {
                if ($k === 'contact_number') {
                    $row[$i] = preg_replace('/D+/', '', $row[$i]);
                }
                $contact->{$k} = $row[$i];
            }
            printf("Save: %sn---n", json_encode($contact));
        }
    }
    

    Making a request:

    $request = (object) [
        'data' => [
            1 => ["John Doe", "[email protected]", "15551-234567",  "New York, NY", "230"],
            2 => ["Jane Smith", "[email protected]", "15552345678", "Los Angeles, CA", "5201"],
            3 => ["Robert Johnson", "[email protected]", "8.80156E+13", "Chicago, IL", "4110"],
        ],
        //'tag' => ["contact_name", "Select Schema", "contact_number", "Select Schema", "Select Schema"],
        'tag' => ["contact_name", "contact_email", "contact_number", "contact_location", "Select Schema"]
    ];
    
    try {
        saveReviewData($request);
    } catch (Exception $e) {
        echo $e->getMessage();
    }
    

    Output:

    Save: {"user_id":1,"contact_name":"John Doe","contact_email":"[email protected]","contact_number":"15551234567","contact_location":"New York, NY"}
    ---
    Save: {"user_id":1,"contact_name":"Jane Smith","contact_email":"[email protected]","contact_number":"15552345678","contact_location":"Los Angeles, CA"}
    ---
    Save: {"user_id":1,"contact_name":"Robert Johnson","contact_email":"[email protected]","contact_number":"88015613","contact_location":"Chicago, IL"}
    ---
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search