Laravel foreach only getting first value - laravel

I am doing a peer marking system which requires a function that lecturer adds id list and when students enroll in a course, he enters his id needed to match the id on lecturer id list.
Controller
public function store(Request $request)
{
$this->validate($request, [
'course_code' => 'required',
'studentid' => 'required'
]);
$enrollment = new Enrollment;
$enrollment->user_id = auth()->user()->id;
$enrollment->course_id = $request->course;
$enrollment->user_StudentID = $request->studentid;
$input_course_id = $request->input('course_code');
$input_studentid = $request->input('studentid');
$course = Course::find($enrollment->course_id);
$course_identifiers = $course->identifiers;
// Need all the data in the database course table for comparison
//$course represents the contents of the course table in all databases, then you need to loop first, then judge
//$course stands for list $signleCourse for each piece of data
foreach ($course_identifiers as $course_identifier) {
// if ($course_identifier->studentid == $input_studentid )
if ($input_studentid == $course_identifier->studentid) {
if ($request->course == $input_course_id) {
//if true,save and redirect
$enrollment->save();
return redirect('/enrollment')->with('success', 'Course Enrolled');
} else {
return redirect('/enrollment')->with('error', 'Please Enter Correct Confirmation Code');
//If false do nothing
}
} else {
return redirect('/enrollment')->with('error', 'Please Enter Correct Student ID');
//If false do nothing
}
}
}
It can only match the first value, but other values I enter cannot be recognized.

Turn off your redirects. It's really hard to understand the context of that code but it looks like if it fails to match it redirects so doesn't go through the second and subsequent values of $course_identifiers.

Related

Laravel Multiple Edit/Upload File

I want to make my code more efficient in my Controller. This code is about to update file in the database and then delete the file were chosen, rather than use if-condition i will use switch statement and then call the updateFile function for each case of file name. But i have problem on my switch statement, it supposed to run for each case but doesn't.
private function updateFile($strFileName, $oldFileName){
if($request->file($strFileName)){
if($request->$oldFIleName){
Storage::delete($request->$oldFIleName);
}
$validatedData[$strFileName] = $request->file($strFileName)->store('post-files');
}
}
public function update(Request $request, Task $task)
{
//storing files request
$rules = [
'file_jamlak' => 'mimes:pdf,png,jpg|file|max:4096',
'file_kontrak' => 'mimes:pdf,png,jpg|file|max:4096',
'file_jamuk' => 'mimes:pdf,png,jpg|file|max:4096']
//validate rules in to new variable
$validatedData = $request->validate($rules);
//the switch
$file_name = $request->file();
switch($file_name){
case 'file_jamlak' : $this->updateFile('file_jamlak', 'oldJamlak');
}
//condition
//jamlak
if($request->file('file_jamlak')){
if($request->oldJamlak){
Storage::delete($request->oldJamlak);
// return $request->oldJamlak;
}
$validatedData['file_jamlak'] = $request->file('file_jamlak')->store('post-files');
$validatedData['jamlak'] = 1;
}
//kontrak
if($request->file('file_kontrak')){
if($request->oldKontrak){
Storage::delete($request->oldKontrak);
}
$validatedData['file_kontrak'] = $request->file('file_kontrak')->store('post-files');
$validatedData['kontrak'] = 1;
}
//add user id
$validatedData['user_id'] = auth()->user()->id;
//update eloquent
Task::where('id', $task->id)
->update($validatedData);
//dd($file_name);
return redirect('/admin/tasks')->with('success', 'New post has been updated!');
}
i think i made mistake on the $file_name, that it supposed to store file name but doesn't work. Please help me
Make sure you've file name in your case which you are checking against:
// ...
//the switch
$file_name = $request->file();
switch($file_name){
// make sure this name matches the name of the file you are submitting
// from the form on front end to be able to fall into this case
case 'file_jamlak' : $this->updateFile('file_jamlak', 'oldJamlak');
// ...

CodeIgniter 3 code does not add data to database into 2 different tables (user_info & phone_info)

The problem is when I entered a new name no data is added. A similar thing happen when I entered an already existing name. Still, no data is added to the database. I am still new to CodeIgniter and not entirely sure my query builder inside the model is correct or not.
In the Model, I check if the name already exists insert data only into the phone_info table. IF name does not exist I insert data into user_info and phone_info.
Controller:
public function addData()
{
$name = $this->input->post('name');
$contact_num = $this->input->post('contact_num');
if($name == '') {
$result['message'] = "Please enter contact name";
} elseif($contact_num == '') {
$result['message'] = "Please enter contact number";
} else {
$result['message'] = "";
$data = array(
'name' => $name,
'contact_num' => $contact_num
);
$this->m->addData($data);
}
echo json_encode($result);
}
Model:
public function addData($data)
{
if(mysqli_num_rows($data['name']) > 0) {
$user = $this->db->get_where('user_info', array('name' => $data['name']))->result_array();
$user_id = $user['id'];
$phone_info = array(
'contact_num' => $data['contact_num'],
'user_id' => $user_id
);
$this->db->insert('phone_info',$phone_info);
} else {
$user_info = array(
'name' => $data['name']
);
$this->db->insert('user_info', $user_info);
$user = $this->db->get_where('user_info', array('name' => $data['name']))->result_array();
$user_id = $user['id'];
$phone_info = array(
'contact_num' => $data['contact_num'],
'user_id' => $user_id
);
$this->db->insert('phone_info', $phone_info);
}
}
DB-Table user_info:
DB-Table phone_info:
Extend and change your model to this:
public function findByTitle($name)
{
$this->db->where('name', $name);
return $this->result();
}
public function addData($data)
{
if(count($this->findByTitle($data['name'])) > 0) {
//.. your code
} else {
//.. your code
}
}
Explanation:
This:
if(mysqli_num_rows($data['name']) > 0)
..is not working to find database entries by name. To do this you can use codeigniters built in model functions and benefit from the MVC Pattern features, that CodeIgniter comes with.
I wrapped the actual findByName in a function so you can adapt this to other logic and use it elswehere later on. This function uses the query() method.
Read more about CodeIgniters Model Queries in the documentation.
Sidenote: mysqli_num_rows is used to iterate find results recieved by mysqli_query. This is very basic sql querying and you do not need that in a MVC-Framework like CodeIgniter. If you every appear to need write a manual sql-query, even then you should use CodeIgniters RawQuery methods.

How can i seed with faker a random id or null in Laravel?

I am trying to seed a parent_id column with a random id of the same table or let it be null.
This i thought it will work:
...
'parent_id' => $faker->boolean() ? Page::all()->random()->id : null,
...
But i get the following error:
You requested 1 items, but there are only 0 items available.
Does anyone know how to do this?
Update1:
Using pseudoanime answer i tried the flowing :
$factory->define(Page::class, function (Faker\Generator $faker) {
...
$parent_id = null;
...
$has_parent = $faker->boolean(50);
Log::debug('$has_parent' . $has_parent);
if ($has_parent) {
$parents = Page::all();
Log::debug('$parents' . count($parents));
if ($parents->isEmpty()) {
Log::debug('isEmpty');
$parent_id = null;
} else {
Log::debug('$parents->random()' . print_r($parents->random(), true));
$parent_id = $parents->random()->id;
}
}
return [
...
'parent_id' => $parent_id,
...
];
}
From what i can see every time it is run Page::all(); return empty.
Any idea why that is?
Try this:
'parent_id' => $faker->boolean(50) ? Page::orderByRaw('RAND()')->first()->id : null,
Essentially we're saying, order by random, get the first and then get it's id.
boolean(50) should give you a 50% chance of true, so 50% false.
$factory->define(Page::class, function (Faker\Generator $faker) {
$ids = Page::pluck('id')->toArray();
return [
'parent_id' = empty($ids) ? null : $faker->optional(0.9, null)->randomElement($ids); // 10% chance of null
];
});
Given "Parent" as the parent model, I do this:
first seed the Parent;
seed the Child table using this code in the factory:
'parent_id' => $faker->optional()->randomElement(App\Parent::all()->pluck('id'))
It works because faker's randomElement() takes an array which you populate with all and only the 'id' values of the parent table.
The optional() faker's modifier does or doesn't put a NULL in the parent_id at random. As stated in faker's GitHub, optional() sometimes bypasses the provider to return a default value instead (which defaults to NULL).
You can also specify the probability of receiving the default value and the default value to return.
NB: you can't do anything if the Parent table isn't seeded. If so, consider the answer of dlnsk.
Your error is happening because your query to page (page:all()->random()) returns no results.
Basically your issue is that you care trying to create a parent to a page before a page is even created.
You can should try something like check if the Page::all() returns a non empty collection, if yes, then get a random element from there, if not, create a new element.
I personally would do something like create a class for null parent element & one that would do null & non-empty parent element.
$factory->defineAs(Page::class, 'ParentPage', function (Faker $faker) {
return [
//the rest of your elements here
'parent_id' => null
];
});
$factory->defineAs(Page::class, 'page', function (Faker $faker) {
$has_parent = $faker->boolean();
if($has_parent) {
$parents = Page::all();
if($parents->isEmpty()) {
$parent_id = factory(Page::class, 'ParentPage')->create()->id;
} else {
$parent_id = $parents->random()->id;
}
}
return [
//the rest of your elements here
'parent_id' => $has_parent? $parent_id : null
];
});
You can create regular pages like factory(Page::class, 'page')->times(50)->create(); in your seeder
The code above is not tested, but the logic should be correct.
public function run()
{
factory(\App\Comment::class, 30)->make()->each(function ($comment){
$comments = Comment::all();
if ($comments->count() == 0) {
$comment->parent = null;
} else {
$rand = random_int(1, $comments->count());
if ($rand >= 2 && $rand <= 5){
$comment->parent = null;
}elseif ($rand >= 12 && $rand <=17){
$comment->parent = null;
}elseif ($rand >= 22 && $rand <= 27){
$comment->parent = null;
}else{
$comment->parent = $rand;
}
}
$comment->save();
});
}

Laravel route : any slug takes all the requests

I have a route something like this. The $slug is a variable that is matched to the slugs stored in the database to add the pages dynamically to the website.
#slug variable for different values of page slug....
Route::get('/{slug?}', array(
'as' => 'page',
'uses' => 'AbcController#renderPage'
));
However, now I wish to add an admin side of the website and want routes to be prefixed with media-manager.
My problem is, whenever I make a call to another route in the file, the above mentioned route takes the request call and calls the renderPage method every time, no matter wherever the request is coming from.
This is my middleware where I check for whether request is coming from a URL like 'media-manager/*', if so I don't want to check for the language of the website and redirect it to the media-manager's page.
private $openRoute = ['media-manager/login', 'media-manager/postLogin', 'media-manager/media'];
public function handle($request, Closure $next)
{
foreach ($this->openRoute as $route) {
if ($request->is($route)) {
return $next($request);
}
}
// Make sure current locale exists.
$lang = $request->segment(1);
if(!isValidLang($lang)) {
$lang = getDefaultLang();
$segments = $request->segments();
array_unshift($segments, $lang);
$newUrl = implode('/', $segments);
if (array_key_exists('QUERY_STRING', $_SERVER))
$newUrl .= '?'.$_SERVER['QUERY_STRING'];
return $this->redirector->to($newUrl);
}
setLang($lang);
return $next($request);
}
This is the renderPage method where every time the request is being redirected, no matter what.
public function renderPage($slug = '')
{
if ($slug == 'login') {
return view ('site.login');
}
$page = Page::getBySlug($slug);
if(empty($page)){
return URL::to ('/');
}
if($slug == ''){//home page
$testimonial = DB::table('testimonial')->where('lang','=',$this->lang)->get();
$client_logo = DB::table('client_logo')->get();
return View::make('index', compact('data','page', 'testimonial', 'client_logo'));
}elseif($slug == 'services'){
return View::make('services', compact('page'));
}elseif($slug == 'portfolio'){
$categories = PortfolioCategory::getAll();
$portfolio = Portfolio::getAll();
return View::make('portfolio', compact('page', 'categories', 'portfolio'));
}elseif($slug == 'oshara'){
return View::make('oshara', compact('page'));
}elseif($slug == 'blog'){
$limit = 8;
$pageNum = 1;
$offset = ($pageNum-1)*$limit;
$totalPosts = BlogPost::totalPosts();
$totalPages = ceil($totalPosts/$limit);
$posts = BlogPost::getAll($offset, $limit);
$blog_posts = View::make('partials.blog_posts', compact('posts','pageNum','totalPages'));
return View::make('blog', compact('page', 'blog_posts', 'pageNum', 'totalPages'));
}elseif($slug == 'contact'){
$budgets = Budget::getAll();
return View::make('contact', compact('page', 'budgets'));
}
}
This is postLogin method in the controller that I want to call after user clicks on Login button on login page.
public function postLogin($request) {
# code...
//$request = $this->request;
$this->validate($request, [
'email1' => 'required|email',
'password' => 'required|string'
]);
if($user = User::whereEmail($request->email1)->first() ) {
if(Hash::check($request['password'], $user->getAttributes()['password'])) {
if(!$user->getAttributes()['is_active']) {
return redirect('/media-manager/login')->withErrors('Your Account is not Activated Yet!');
} else if($user->getAttributes()['is_deleted']) {
return redirect('/media-manager/login')->withErrors('Your Account is Banned!');
} else {
# Success
$cookie = Cookie::make('user_id', $user->getAttributes()['id'], 864000);
//echo "hello";
return view('site.media')->with('message', 'You have Successfully Logged In!')->withCookie($cookie);
}
} else {
return redirect('/media-manager/login')->withErrors('Your Login Information is Wrong!');
}
} else {
return redirect('/media-manager/login')->withErrors('Your Login Information is Wrong!');
}
}
Can any one please suggest me some way so that I can disable renderPage method on every call and have my normal routing perform perfectly.
In Laravel the first matching route is used. So I would guess you have your slug route defined above the others (at least above the media-manager ones), right?
So a simple solution would be to just put the slug route definition at the end of your routing file.
Another approach would be utilize conditions for the route. For more information you can read this or leave a comment!
Hope that helps!

How to check if the record exist using codeigniter

I'm creating a registration form using codeigniter. I understand that there is a validation for each field in CI but what I want to do is to validate a multiple field exist.
SELECT emp_id FROM emp_record WHERE firstname = 'firstname' AND lastname = 'firstname' AND birthdate = 'firstname'
If the query above find a match I want to alert on my view page that the record already exist.
Please help.
Appreciate it. Thanks.
Declare a custom callback function
function _check_firstname()
{
$firstname = $this->security->xss_clean($this->input->post('firstname'));
$array = array('firstname' => $firstname, 'birthdate' => $firstname);
$result = $this->db->select('emp_id')->from('emp_record')->where($array)->get();
if($result->num_rows())
{
$this->form_validation->set_message('_check_firstname', 'Record already exists');
return false;
}else
{
return true;
}
}
Set rules including (callback__check_firstname)
$this->form_validation->set_rules('firstname', 'First Name', 'trim|required|callback__check_firstname');
Now, when you'll check validation like
if ($this->form_validation->run()){
// passes
}
else{
// not passes, so show the view again
}
In the view, if you have something like this
<?php echo form_error('firstname') ?>
This will show the error message set in the custom callback function.
You could use num_rows() to do such things.
By using active record you can achieve this by doing the following
$qry = $this->db->select('emp_id')->from('emp_record')
->where('firstname', $firstname)
->where('lastname', $lastname)
->where('birthdate', $birthdate)
->get();
if ($qry->num_rows() > 0)
return TRUE;
else
return FALSE;
This will return TRUE if it finds at least one row in your database or FALSE if it finds nothing.
some people can/may have the same firstname,lastname and birthdate
But still if you want to have it that way you could create a callback validation
here is a snippet.
public function checkinput()
{
// you may want to sanitize the input
$data['fname'] = $this->input->post('fname');
$data['lname'] = $this->input->post('fname');
$data['mname'] = $this->input->post('fname');
//your model for checking data must return TRUE or FALSE
if($this->model->method_for_checking($data))
{
this->form_validation->set_message('checkinput', 'Duplicate data exists.');
return TRUE;
}else{
return FALSE;
}
}
Now you can use it on your validation rules i.e
$this->form_validation('fname','fname',callback_checkinput);
Other options are
Extend a form validation and create a validation rule there as not
to clutter the controller
Or ,After Submitting the form before inserting the data, you can check whether it is a duplicate and do the logical things their.

Resources