Laravel validator 'in' issue for numbers in input - php

I need help in fixing an issue in which I am using laravel 'in' validator to match a given input against multiple comma separated string of values. Now the issue is when there is a number in the input and it does not matches with any of the comma separated values then it gives an exception:
preg_match() expects parameter 2 to be string, array given
However it should simply give error message in validator object that input field does not match. instead it gives above mentioned exception. Following is my code:
if (!empty($program)) {
$institution_id = $program->InstitutionId;
$roster_users = $program->usersRosters()->where('ProfileType', 'Student')->get();
if (!empty($roster_users)) {
$rostered_users_ids = implode(',', $roster_users->lists('id'));
}
if (!empty($roster_users)) {
$rostered_users_usernames = implode(',', $roster_users->lists('UserName'));
}
$teacher_roster_users = $program->usersRosters()->where('ProfileType', 'External Staff')->get();
if (!empty($teacher_roster_users)) {
$teacher_rostered_users_usernames = implode(',', $teacher_roster_users->lists('UserName'));
}
if (!empty($teacher_roster_users)) {
$teacher_rostered_users_data = $teacher_roster_users->lists('id', 'UserName');
}
}
$rules = [
'aasectionname.required' => '501 – AA section does not exist',
'aaid' => 'numeric|exists:users,id|in:' . $rostered_users_ids . '|aaidinstitutionmismatch:' . $institution_id,
'institutionid' => 'numeric|in:' . $institution_id,
'username' => 'exists:users,UserName|in:' . $rostered_users_usernames . '|usernameinstitutionmismatch:' . $institution_id,
'schoolid' => 'numeric',
'groupowner' => 'in:'.$teacher_rostered_users_usernames,
'remove' => 'in:0,1'
];
$messages = [
// InstitutionId
'institutionid.numeric' => '101 – Invalid Institution ID',
'institutionid.in' => '102 – Institution ID does not match Program',
// Usernames
'username.exists' => '201 – UserName does not exist',
'username.in' => '202 – UserName is not rostered to this program',
'username.usernameinstitutionmismatch' => '203 – User/Institution Mismatch - UserName is not assigned to this Institution',
// AAId
'aaid.numeric' => '301 – AA ID does not exist',
'aaid.exists' => '301 – AA ID does not exist',
'aaid.in' => '302 – AA ID is not rostered to this program',
'aaid.aaidinstitutionmismatch' => '303 – AA ID/Institution Mismatch – AAID is not assigned to this Institution',
// Mismatch
'bothmismatch' => '401 – AAID/UserName/SchoolID do not match (This is a combination of at least 2 of these items)',
// Teacher
'groupowner.in' => '501 – GroupOwner does not exist',
// Remove
'remove' => '601 – No Student record match to remove',
];
Excel::load($file, function($excel) use($program, $rules, $messages, $errors, &$errors_data, $teacher_rostered_users_data) {
global $totalmismatch;
$results = $excel->get();
$program_group_model = new ProgramGroup;
$option_model = new Option;
$group_default_status_id = key($option_model->getProgramsStatus(['Active']));
$groupVisibilityStatusId = $group_type = $option_model->getVisibilityOptions('Question Visibility','Private');
$data = [];
$lastSecId = null;
$groupSectionPreviousName = null;
$groupname = null;
$data['status'] = $group_default_status_id;
$data['program_id'] = $program->Id;
$groupname_lists = $program_group_model->with(['programs' => function ($query) use ($program){
$query->where('ProgramId','=',$program->Id);
}])->get()->lists('Name','Id');
foreach ($results as $key => $row) {
$inputs = $row->toArray();
$groupname = trim($inputs['usergroup']);
$errors = [];
// Stop reading the excel when aasectionname is empty
if (empty($groupname) || $groupname == null) {
$errors['remove'] = $messages['aasectionname.required'];
}
$validator = Validator::make($inputs, $rules, $messages);
if ($validator->fails()) {
$errors = $validator->messages()->toArray();
foreach ($errors as $error) {
foreach ($error as $e) {
$errors_data[] = [$key + 2, $e];
}
}
} else {
$aaid = intval($inputs['aaid']);
$groupowner_name = $inputs['groupowner'];
if (!empty($teacher_rostered_users_data[$groupowner_name])) {
$groupowner_id = $teacher_rostered_users_data[$groupowner_name];
$data['owner'] = $groupowner_id;
}
$remove = intval($inputs['remove']);
// Remove existing Student Roster
if (!empty($remove)) {
$removed = false;
$user_ids = is_array($aaid) ? $aaid : [$aaid];
$program_group = $program->programGroups()->where('Name', $groupname);
if (!empty($program_group)) {
$program_group = $program_group->first();
}
if (!empty($program_group)) {
$program_group = $program_group->users();
}
if (!empty($program_group) && !empty($user_ids)) {
$removed = $program_group->detach($user_ids);
}
if (!$removed) {
$errors['remove'] = $messages['remove'];
}
} else {
if (!in_array($groupname, $groupname_lists) || $groupSectionPreviousName != $groupname) {
$data['name'] = $groupname;
$data['group_id'] = array_search($groupname, $groupname_lists);
$data['group_type'] = $groupVisibilityStatusId;
$sectionId = $program_group_model->saveProgramGroup($data);
$data[$sectionId]['selected'][] = $aaid;
$groupname_lists[$sectionId] = $groupname;
} else {
$temp = array_flip($groupname_lists);
$data[$temp[$groupname]]['selected'][] = $aaid;
}
}
if ($totalmismatch === 2) {
$errors['bothmismatch'] = $messages['bothmismatch'];
}
foreach ($errors as $error) {
$errors_data[] = [$key + 2, $error];
}
}
$groupSectionPreviousName = $groupname;
}
$programAASectionModelForSectionUsers = new ProgramSectionUser();
$programAASectionModelForSectionUsers->saveProgramGroupUsers($data);
});
$rules
array:7 [
"aasectionname.required" => "501 – AA section does not exist"
"aaid" => "numeric|exists:users,id|in:28,29,32,33,25,24,27|aaidinstitutionmismatch:42"
"institutionid" => "numeric|in:42"
"username" => "exists:users,UserName|in:Kabeer,Ayaz,fddesaaweqq,fdawerascvdfc,haseeb,kamran,shahid|usernameinstitutionmismatch:42"
"schoolid" => "numeric"
"groupowner" => "in:externalstaff,rahat,uzma,sahar,haseebahmad,saimariaz,fredrick"
"remove" => "in:0,1"
]

Related

Problem of Curly Brackets in my controller Php Symfony

I want to call my function but when I call it I have a problem with curly Brackets at the end of my code and i have this error Error SYMFONY ( {} ) in my Controller.
I have no idea where to put them for my code to work. I have this problem when I add my function that allows me to retrieve the
history of the action. The mentioned function goes as this:
$this->logHistory->addHistoryConnection($project->getId(), $user->getId(), 'Delete Local Suf', $sf_code);
Function Supp Suf
/**
* #Route("/creation/suf/supp", name="suf_supp")
*/
public function suf(
Request $request,
ShapesRepository $shapesRepository
) {
$params = $this->requestStack->getSession();
$projet = $params->get('projet');
$modules = $params->get('modules');
$fonctionnalites = $params->get('fonctionnalites');
$user = $this->getUser()->getUserEntity();
$manager = $this->graceManager;
$mapManager = $this->mapManager;
$countElements = $mapManager->getCount();
$shapes = $shapesRepository->findBy(array('projet' => $projet->getId()));
$adresseWeb = $this->getParameter('adresse_web');
$carto = $params->get('paramCarto');
$centrage = $params->get('centrage');
$cableColor = $params->get('cableColor');
$sf_code = '';
if ($request->get('suf') != '') {
$sf_code = $request->get('suf');
}
$suf = $manager->getSuf($sf_code);
$success = '';
$error = '';
$warning = '';
if ($request->query->get('success')) {
$success = $request->query->get('success');
} elseif ($request->query->get('error')) {
$error = $request->query->get('error');
} elseif ($request->query->get('warning')) {
$warning = $request->query->get('warning');
}
if ($request->isMethod('POST')) {
if ($request->request->get('sf_code') != '') {
$sf_code = $request->request->get('sf_code');
}
if ($request->get('val') != '') {
$val = $request->get('val');
}
$dir = $this->getparameter('client_directory');
$dossier = str_replace(' ', '_', $projet->getProjet());
$dir = $dir . $dossier . '/documents/';
$cable = $val[0];
$chem = $val[1];
$t_suf = $this->graceCreator->supprimeSuf($sf_code, $cable, $chem);
if ($t_suf[0][0] == '00000') {
$this->logHistorique->addHistoryConnection($projet->getId(), $user->getId(), 'Suppression Suf Local', $sf_code);
// $creator->delDirObjet( $st_code, $dir );
$data = new JsonResponse(array("success" => "create!"));
return $data;
} else {
$data = new JsonResponse(array("error" => "Error : " . $t_suf));
return $data;
}
return $this->render('Modifications/supSuf.html.twig', array(
'user' => $user,
'paramCarto' => $carto,
'cableColor' => $cableColor,
'suf' => $suf,
'adresseWeb' => $adresseWeb,
'centrage' => $centrage,
'shapes' => $shapes,
'projet' => $projet,
'modules' => $modules,
'fonctionnalites' => $fonctionnalites,
'countElements' => $countElements
));
}
}
Your only return statement is inside of an if condition. If the code does not pass the condition, it has nothing to return. The code must return something in all possible cases. If you are not still used to these practices, an IDE might guide you until it becomes a routine. PHPStorm is my personal preference.
BTW, I recommend you to switch from the array() syntax to the more globally accepted [] although you must be in PHP 5.4 or higher.

laravel Trying to get property 'id' of non-object error

I was working on another person's code and when I deployed the laravel app the login page works but when I input the testing credentials it spits out this error
Trying to get property 'id' of non-object
in helpers.php line 159
at HandleExceptions->handleError(8, 'Trying to get property \'id\' of non-object', '/var/www/html/first-project/app/Helpers/helpers.php', 159, array('fields' => object(Collection), 'fieldsValues' => object(Collection), 'htmlFields' => array(), 'startSeparator' => '<div style="flex: 50%;max-width: 50%;padding: 0 4px;" class="column">', 'endSeparator' => '</div>', 'field' => object(CustomField), 'dynamicVars' => array('$RANDOM_VARIABLE$' => 'var15931958241638660037ble', '$FIELD_NAME$' => 'phone', '$DISABLED$' => '', '$REQUIRED$' => '"required" => "required",', '$MODEL_NAME_SNAKE$' => 'user', '$FIELD_VALUE$' => '\'+136 226 5660\'', '$INPUT_ARR_SELECTED$' => '+136 226 5660'), 'gf' => object(GeneratorField), 'value' => object(CustomFieldValue)))
in helpers.php line 159
The actual function referred to is the following
function generateCustomField($fields, $fieldsValues = null)
{
$htmlFields = [];
$startSeparator = '<div style="flex: 50%;max-width: 50%;padding: 0 4px;" class="column">';
$endSeparator = '</div>';
foreach ($fields as $field) {
$dynamicVars = [
'$RANDOM_VARIABLE$' => 'var' . time() . rand() . 'ble',
'$FIELD_NAME$' => $field->name,
'$DISABLED$' => $field->disabled === true ? '"disabled" => "disabled",' : '',
'$REQUIRED$' => $field->required === true ? '"required" => "required",' : '',
'$MODEL_NAME_SNAKE$' => getOnlyClassName($field->custom_field_model),
'$FIELD_VALUE$' => 'null',
'$INPUT_ARR_SELECTED$' => '[]',
];
$gf = new GeneratorField();
if ($fieldsValues) {
foreach ($fieldsValues as $value) {
if ($field->id === $value->customField->id) {
$dynamicVars['$INPUT_ARR_SELECTED$'] = $value->value ? $value->value : '[]';
$dynamicVars['$FIELD_VALUE$'] = '\'' . addslashes($value->value) . '\'';
$gf->validations[] = $value->value;
continue;
}
}
}
// dd($gf->validations);
$gf->htmlType = $field['type'];
$gf->htmlValues = $field['values'];
$gf->dbInput = '';
if ($field['type'] === 'selects') {
$gf->htmlType = 'select';
$gf->dbInput = 'hidden,mtm';
}
$fieldTemplate = HTMLFieldGenerator::generateCustomFieldHTML($gf, config('infyom.laravel_generator.templates', 'adminlte-templates'));
if (!empty($fieldTemplate)) {
foreach ($dynamicVars as $variable => $value) {
$fieldTemplate = str_replace($variable, $value, $fieldTemplate);
}
$htmlFields[] = $fieldTemplate;
}
// dd($fieldTemplate);
}
foreach ($htmlFields as $index => $field) {
if (round(count($htmlFields) / 2) == $index + 1) {
$htmlFields[$index] = $htmlFields[$index] . "\n" . $endSeparator . "\n" . $startSeparator;
}
}
$htmlFieldsString = implode("\n\n", $htmlFields);
$htmlFieldsString = $startSeparator . "\n" . $htmlFieldsString . "\n" . $endSeparator;
// dd($htmlFieldsString);
$renderedHtml = "";
try {
$renderedHtml = render(Blade::compileString($htmlFieldsString));
// dd($renderedHtml);
} catch (FatalThrowableError $e) {
}
return $renderedHtml;
}
its usage is as follows in the controllers. It is used many times in almost all controllers for example in the UserController.php file I think this is the calling method. I am not that well versed in laravel sorry for any noob mistakes in advance.
public function profile()
{
$user = $this->userRepository->findWithoutFail(auth()->id());
unset($user->password);
$customFields = false;
$role = $this->roleRepository->pluck('name', 'name');
$rolesSelected = $user->getRoleNames()->toArray();
$customFieldsValues = $user->customFieldsValues()->with('customField')->get();
$hasCustomField = in_array($this->userRepository->model(), setting('custom_field_models', []));
if ($hasCustomField) {
$customFields = $this->customFieldRepository->findByField('custom_field_model', $this->userRepository->model());
$customFields = generateCustomField($customFields, $customFieldsValues);
}
return view('settings.users.profile', compact(['user', 'role', 'rolesSelected', 'customFields', 'customFieldsValues']));
}
You have to change this line
From
$user = $this->userRepository->findWithoutFail(auth()->id());
To
$user = $this->userRepository->findWithoutFail(auth()->user()->id());
My first guess, change this $user = $this->userRepository->findWithoutFail(auth()->id()); to $user = $this->userRepository->findWithoutFail(auth()->user()->id);
Added auth()->user()->id;

PHP function errors not showing

I wasn't entirely sure how to search for this question, so if it has been asked before please send me in the right direction.
I have a validation function with an array. Inside my array I have set up errors to be displayed if one of the form fields doesn't validate. If the user fills a field out wrong, they should get an error of which field was wrong and the form should be still present. However, they get a blank page with only the generic error (the one I echo when I called the function) and not the field-specific error. Can someone please tell me where I went wrong?
$output_form = 1; //control if form displays - yes
$error_text = '';
//declare form elements (empty first load)
$fname = '';
$valid_fname = 0;
$fname_regex = '/^([A-Z]|[a-z]){2,15}$/';
$fname_error_message = 'First name must be 2-15 alphabetic characters only.<br>';
$lname = '';
$valid_lname = 0;
$lname_regex = '/^([A-Z]|[a-z]){2,15}$/';
$lname_error_message = 'Last name must be 2-15 alphabetic characters only.<br>';
$phone = '';
$valid_phone = 0;
$phone_regex = '/^\(\d{3}\)\d{3}-\d{4}$/';
$phone_error_message = 'Phone number must be in (xxx)xxx-xxxx format.<br>';
$city = '';
$valid_city = 0;
$city_regex = '/^([A-Z]|[a-z]){2,15}$/';
$city_error_message = 'City must be 2-15 alphabetic characters only.<br>';
$state = '';
$valid_state = 0;
$state_regex = '/^([A-Z]|[a-z]){2}$/';
$state_error_message = 'State must be 2 alphabetic characters only.<br>';
//data posted
if (isset($_POST['submit'])) {
if ($debug) {
echo "<pre>";
print_r($_POST);
echo "</pre>";
}//end debug
$fname = trim($_POST['fname']);
$lname = trim($_POST['lname']);
$phone = trim($_POST['phone']);
$city = trim($_POST['city']);
$state = trim($_POST['state']);
$phone_replace = preg_replace('/[\(\)\-\s]/', '', $phone);
function validate_form($fields, &$errors = []) {
$errors = [];
foreach ($fields as $name => $field) {
if (!preg_match ($field['regex'], $field['value'])) {
$errors[$name] = $field['error'];
$output_form = 1;
}
}
return empty($errors); //returns true/false
}
$fields = [
'fname' => ['regex' => $fname_regex, 'value' => $fname, 'error' => $fname_error_message],
'lname' => ['regex' => $lname_regex, 'value' => $lname, 'error' => $lname_error_message],
'phone' => ['regex' => $phone_regex, 'value' => $phone, 'error' => $fname_error_message],
'city' => ['regex' => $city_regex, 'value' => $city, 'error' => $city_error_message],
'state' => ['regex' => $state_regex, 'value' => $state, 'error' => $state_error_message],
];
$errors = [];
if (!validate_form($fields, $errors)) {
echo "<p>One of your fields is invalid. Please check and re-submit.</p>";
$output_form = 1;
return (false);
}
else {
$output_form = 0;
}
foreach($errors as $error) echo "<p>$error</p>";
Actually outputting stuff usually helps ;)

Codeigniter transaction for all queries within a function

I have these following functions.
public function importExcelFile(){
$file = $_FILES['file']['tmp_name'];
$data = extract_excel_data($file);
$i = 0;
foreach($data['values'] as $dataValues) {
$categories = [];
$brands = [];
$models = [];
foreach($dataValues as $value){
if(array_filter($value)) {
/* If a row does not contain brand/category/model for the product then fetch the resp. info. from previous row */
if(empty(trim($value[0]))) {
$categories[] = $prev_cat;
} else {
$categories[] = strtoupper(trim($value[0]));
$prev_cat = strtoupper(trim($value[0]));
}
if(empty(trim($value[1]))) {
$brands[] = $prev_brand;
} else {
$brands[] = strtoupper(trim($value[1]));
$prev_brand = strtoupper(trim($value[1]));
}
if(empty(trim($value[2]))) {
$models[] = $prev_model;
} else {
$models[] = $value[2];
$prev_model = $value[2];
}
}
}
//insert device category
$this->insert_setups('category', $categories);
//insert brand
$this->insert_setups('brand', $brands);
// Check if branch already exists in the database
$check_branch = $this->global_model->getDetailByWhere('branch', array('name'=>$data['branch'][$i].' branch'))->result();
$branch_arr = [];
//insert branch
if(empty($check_branch)) {
$branch_arr = array(
'name' => $data['branch'][$i].' branch',
'location' => $data['branch'][$i],
'status' => 1,
'created_by' => $this->session->userdata('id'),
'created_on' => date('Y-m-d')
);
$this->global_model->insertData('branch', $branch_arr);
}
$branch_id = $this->global_model->getDetailByWhere('branch', array('name'=>$data['branch'][$i].' branch'))->row()->id;
$db_device_categories = [];
$db_brands = [];
// get categoris, brands
$db_device_categories = $this->arrangeArray('category', $where =array());
$db_brands = $this->arrangeArray('brand', $where =array());
//detail_print($db_brands);
// insert new models from database
foreach(array_unique($models) as $model_key=>$model){
$check_model = $this->global_model->getDetailByWhere('model', array('name'=>$model))->result();
$insert = [];
if(empty($check_model)){
$insert = array(
'name' => $model,
'item_type' => 1,
'category_id' => $db_device_categories[$categories[$model_key]],
'brand_id' => $db_brands[$brands[$model_key]],
'created_by' => $this->session->userdata("id"),
'created_on' => date('Y-m-d'),
);
$this->global_model->insertData('model', $insert);
}
}
$db_device_models = [];
// get models from database
$db_device_models = $this->arrangeArray('model', $where = array('item_type'=>1));
$categoriy_id = [];
$brand_id = [];
$model_id = [];
$opening_stock = [];
// arrange the exported array with respective id
foreach($dataValues as $values){
if(array_filter($values)) {
if(empty(trim($values[0]))) {
$category_id = $prev_cat;
} else {
$category_id = strtoupper(trim($values[0]));
$prev_cat = strtoupper(trim($values[0]));
}
if(empty(trim($values[1]))) {
$brand_id = $prev_brand;
} else {
$brand_id = strtoupper(trim($values[1]));
$prev_brand = strtoupper(trim($values[1]));
}
if(empty(trim($values[2]))) {
$model_id = $prev_model;
} else {
$model_id = $values[2];
$prev_model = $values[2];
}
$opening_stock[] = array(
'category_id' => $db_device_categories[$category_id],
'brand_id' => $db_brands[$brand_id],
'model_id' => $db_device_models[$model_id],
'imei' => (string)$values[3],
'cost_price' => isset($values[5]) ? $values[5] : 0,
'selling_price' => isset($values[6]) ? $values[6] : 0
);
}
}
$group_by_model = [];
// group the array by model_id
foreach(array_unique($models) as $model1){
$where = $db_device_models[$model1];
$group_by_model[] = array_filter($opening_stock, function($elements) use ($where){
return $elements["model_id"] == $where;
});
}
if(!$this->purchase_model->insertOpeningStock($group_by_model, $branch_id)){
$this->session->set_flashdata('error', 'Opening stock of devices insertion failed.');
redirect('purchase/uploadExcelFile');
}
$i++;
}
$this->session->set_flashdata('success', 'Opening stock of devices added successfully.');
redirect('purchase/uploadExcelFile');
}
private function arrangeArray($table, $where){
$list = $this->global_model->getDetailByWhere($table, $where)->result_array();
foreach($list as $item){
$name = $item['name'];
$arranged_list[$name] = $item['id'];
}
return !empty($arranged_list) ? $arranged_list : NULL;
}
private function insert_setups($table_name, $setups){
foreach(array_unique($setups) as $value){
$check_setup = $this->global_model->getDetailByWhere($table_name, array('name'=>$value))->result();
if(empty($check_setup)){
$insert = array(
'name' => $value,
'created_by' => $this->session->userdata("id"),
'created_on' => date('Y-m-d'),
);
$this->global_model->insertData($table_name, $insert);
}
}
}
What this function does is, it extracts data from the uploaded excel file and inserts the data to various tables accordingly. Now as you can see, there are multiple queries running in different locations inside the importExcelFile() method. So my question is, how do I use codeigniter transaction in such a way that all the queries inside this function are performed atomically. If any one query fails, all other query's work is rolled back. Also, is this code considered clean ?
P.S. I'm so sorry if my last question was inappropriate here.
this might be helpful to you.
transactions in codeigniter
$this->db->trans_begin();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
if ($this->db->trans_status() === FALSE)
{
$this->db->trans_rollback();
}
else
{
$this->db->trans_commit();
}

Get selected value from select_from_array field using laravel 5.2 Backpack

I am using Laravel 5.2 Backpack in my new project where I have a select_from_array field in my form, depending upon the selected value I want data to be displayed in another select_from_array field. Don't know how to do that. Please help me with this. This is my code
Controller.php
public function __construct()
{
if (Request::segment(3) == 'create') {
$parentField1 = [
'name' => 'cat_id',
'label' => 'Category',
'type' => 'select_from_array',
'options' => $this->categories(),
'allows_null' => false,
];
$parentField = [
'name' => 'subCat_id',
'label' => 'SubCategory',
'type' => 'select_from_array',
'options' => $this->subcategories(),
'allows_null' => false,
];
array_unshift($this->crud['fields'], $parentField1,$parentField);
}
public function categories()
{
$cat = Request::get('cat_id');
$currentId = 0;
if (Request::segment(4) == 'edit' and is_numeric(Request::segment(3))) {
$currentId = Request::segment(3);
}
$entries = Category::where('translation_lang', config('app.locale'))->where('parent_id',0)->orderBy('lft')->get();
if (is_null($entries)) {
return [];
}
$tab = [];
$tab[0] = 'Root';
foreach ($entries as $entry) {
if ($entry->id != $currentId) {
$tab[$entry->translation_of] = '- ' . $entry->name;
}
}
return $tab;
}
public function subcategories()
{
$currentId = 0;
if (Request::segment(4) == 'edit' and is_numeric(Request::segment(3))) {
$currentId = Request::segment(3);
}
$entries = Category::where('translation_lang', config('app.locale'))->where('parent_id','!=' ,0)->orderBy('lft')->get();
if (is_null($entries)) {
return [];
}
$tab = [];
$tab[0] = 'Root';
foreach ($entries as $entry) {
if ($entry->id != $currentId) {
$tab[$entry->translation_of] = '- ' . $entry->name;
}
}
return $tab;
}
I want the id of selected option in the subcategories() where I can use the id to get the data.
I think the best way for you is to create a custom field type for this particular purpose, that includes both selects. Follow this procedure. Start from the select2.blade.php file and add the javascript you need to achieve your goal (on change event on first select2, change the options in the next select2).

Categories