Codeigniter 4 routes not working as expected, disorganizes views - codeigniter

I am new to CI4 and i've been battling this for weeks now. I mapped my routes, It is working fine without placeholders, but once i add placeholder, it disorganizes my view.
I have tried several changes to my knowledge but no good result
Routes.php
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Login');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
$routes->setAutoRoute(true);
$myroutes = [];
$myroutes['login'] = 'Login::index'; //working
$myroutes['logout'] = 'Login::logout'; //working
$myroutes['home'] = 'Home::dashboard'; //working
//User
$myroutes['add_user'] = 'User::create'; //working
$myroutes['view_users'] = 'User::user_list'; //working
//Client
$myroutes['addClient'] = 'Client::create'; //working
$myroutes['clients'] = 'Client::view'; //working
$myroutes['clientProfile/(:num)'] = 'Client::profile/$1'; //not working
$myroutes['rooms'] = 'Home::rooms'; //working
$myroutes['privileges/(:num)'] = 'Home::permissions/$1'; //not working
$routes->map($myroutes);
And here is my controller script. All other methods are working fine except for the profile method
Controller (Client.php)
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\ClientModel;
class Client extends BaseController
{
public $session;
public $clientModel;
public function __construct()
{
helper('form');
$this->clientModel = new ClientModel();
$this->session = \Config\Services::session();
}
public function create()
{
if (!session()->has('logged_user')) {
return redirect()->to('/login');
}
$data = [
'page_name' => 'Add Client',
'page_title' => 'Add Client | The Ashokas',
];
$data['validation'] = null;
$rules = [
'client_title' => 'required|min_length[2]|max_length[5]',
'first_name' => 'required|min_length[3]|max_length[16]',
'middle_name' => 'required|min_length[3]|max_length[16]',
'last_name' => 'required|min_length[3]|max_length[16]',
'relationship_status' => 'required',
'client_email' => 'required|valid_email|is_unique[clients.client_email]',
'mobile' => 'required|numeric|exact_length[11]',
'gender' => 'required',
'occupation' => 'required',
'workplace' => 'required',
'address' => 'required',
'kin_name' => 'required|min_length[3]|max_length[50]',
'kin_relationship' => 'required',
'kin_mobile' => 'required|numeric|exact_length[11]',
'kin_address' => 'required'
];
if ($this->request->getMethod() == 'post') {
if ($this->validate($rules)) {
$clientdata = [
'client_title' => $this->request->getVar('client_title'),
'first_name' => $this->request->getVar('first_name'),
'middle_name' => $this->request->getVar('middle_name'),
'last_name' => $this->request->getVar('last_name'),
'relationship_status' => $this->request->getVar('relationship_status'),
'client_email' => $this->request->getVar('client_email'),
'mobile' => $this->request->getVar('mobile'),
'gender' => $this->request->getVar('gender'),
'occupation' => $this->request->getVar('occupation'),
'workplace' => $this->request->getVar('workplace'),
'address' => $this->request->getVar('address'),
'kin_name' => $this->request->getVar('kin_name'),
'kin_relationship' => $this->request->getVar('kin_relationship'),
'kin_mobile' => $this->request->getVar('kin_mobile'),
'kin_address' => $this->request->getVar('kin_address'),
'join_date' => date('d-m-Y')
];
if ($this->clientModel->create($clientdata)) {
$this->session->setTempdata('success', 'Client added successfully',3);
return redirect()->to('/clients');
}else{
$this->session->setTempdata('error', 'Sorry! Unable to add client',3);
return redirect()->to(current_url());
}
}else{
$data['validation'] = $this->validator;
}
}
return view('client/add', $data);
}
public function view() {
if (!session()->has('logged_user')) {
return redirect()->to('/login');
}
$data = [
'page_name' => 'Clients',
'page_title' => 'All Clients | The Ashokas',
'clientele' => $this->clientModel->getAllClients()
];
return view('client/view', $data);
}
public function profile($client_id = null) {
if (!session()->has('logged_user')) {
return redirect()->to('/login');
}
$data = [
'page_name' => 'Client Profile',
'page_title' => 'Client Profile | The Ashokas',
];
return view('client/profile', $data);
}
}
Expected View
The view i got
Genius mind should please assist. Thanks in anticipation

This looks like your javascript and css paths are relative to the current folder in your html header. while you are in /path1/path2 this two level structure works fine but when you have /path1/path2/1 this is three level structure and it fails with relative js and css files.
Change them to absolute paths.
You probably have something like this
<link rel="stylesheet" type="text/css" href="../../somefolder/mycss.css">
Change it to this
<link rel="stylesheet" type="text/css" href="/appfolder/somefolder/mycss.css">
Do same thing for javascript files and images too.

Try adding base_url function to create an absolute path like this
<link href="<?= base_url('path/of/your/css.css') ?>" rel="stylesheet">
Note that path/of/your/css.css is stored at public folder

Related

Images not displaying on view

I am failing to locate where I am missing something. My application is uploading some files into the server. However, when I retrieve the files (images), all the links are broken and I am failing to pick up where the error is.
index() method to send the services to the view:
public function index()
{
$services = Service::all();
foreach($services as $service) {
$service->feature_image = Storage::url($service->feature_image);
}
return view('services.index')->with([
'services' => $services,
]);
}
store method:
public function store(Request $request)
{
$validate = Validator::make($request->all(), [
'title' => 'required|string',
'feature_image' => 'required|file|mimes:png,jpg,jpeg',
'description' => 'required|string|min:30|max:150',
'merchant_id' => 'required|string',
]);
if( $validate->fails() ){
return response($validate->errors(), 400);
}
//image storing before
try {
$image = $request->feature_image;
$extension = $image->extension();
if (! in_array($extension, ['jpg', 'jpeg', 'png'])) {
throw new Exception('File format not supported');
}
$imageName = time().'_'.rand(1000, 9999).'.'.$extension;
$imageName = $request->file('feature_image')->storeAs(
'feature_images',
$imageName,
'local'
);
$service = new Service();
$service->name = $request->title;
$service->feature_image = $imageName;
$service->short_description = $request->description;
$service->merchant_id = $request->merchant_id;
$service->save();
} catch (Exception $e) {
return response()->with('error', $e->getMessage());
}
$services = Service::where('merchant_id', '=', $request->merchant_id )
->get();
return response()->json([
'services' => $services,
], 200);
}
View that's not displaying the images:
<td>
<img src="{{$service->feature_image}}" style="max-width:300px !important; max-height:100px !important; border-radius:none !important;" />
</td>
filesystems configuration:
'local' => [
'driver' => 'local',
'root' => storage_path('app/private'),
'visibility' => 'private',
],
'permissions' => [
'file' => [
'public' => 0644,
'private' => 0600,
],
'dir' => [
'public' => 0755,
'private' => 0700,
],
],
Images are uploading perfectly but just won't display
But, nothing showing on the view
In the database, image is stored as feature_images/1675377529_1402.png and on the frontend, application is trying to load https://my_domain/storage/feature_images/1675377529_1402.png
UPDATE
When I change the disk am writing to public, the images show
$imageName = $request->file('feature_image')
->storeAs(
'feature_images',
$imageName,
'public'
);

updateOrCreate() updating database using index

I have a submit and update function for my form and in that form, the user can choose to add an additional row of inputs. These inputs will be saved in a new row, basically, one user can have several rows in the database. I have a problem with the update function, where if the user originally has two rows answered, in the update function if they still fill in two rows, both of the rows in the database will be updated, however, only the first row is getting updated. I tried accessing the key for the arrays and updating based on the array keys but it doesn't work.
Here is my whole controller:
<?php
namespace App\Http\Livewire;
use Illuminate\Support\Facades\Validator;
use App\Http\Livewire\Field;
use Illuminate\Http\Request;
use App\Helpers\Constant;
use App\Models\User;
use App\Models\Application;
use App\Models\Model1;
use App\Models\Model2;
use App\Models\Model3;
use App\Models\Model4;
use Livewire\Component;
use DB;
class ModelComponent extends Component
{
public $i = 1;
public $updateMode = false;
public $model2Rows = [];
public $model4Rows = [];
public $showDiv1 = false;
public $showDiv2 = false;
public $showDiv3 = false;
public $showDiv4 = false;
public $m1_field;
public $m1_field2;
public $m2_field;
public $m2_field2;
public $m3_field;
public $m3_field2;
public $m4_field;
public $m4_field2;
public function openDiv($divNum)
{
if($divNum == 1) {
$this->showDiv1 =! $this->showDiv1;
} else if($divNum == 2) {
$this->showDiv2 =! $this->showDiv2;
} else if($divNum == 3) {
$this->showDiv3 =! $this->showDiv3;
} else if($divNum == 4) {
$this->showDiv4 =! $this->showDiv4;
}
}
public function addMoreModel2Rows($i)
{
$i = $i + 1;
$this->i = $i;
array_push($this->model2Rows , $i);
}
public function addMoreModel4Rows($i)
{
$i = $i + 1;
$this->i = $i;
array_push($this->model4Rows , $i);
}
public function removeModel2Rows($i)
{
unset($this->model2Rows[$i]);
}
public function removeModel4Rows($i)
{
unset($this->model4Rows[$i]);
}
public function submit()
{
$user = auth()->user();
$application = Application::create([
'app_type_id' => 1,
'approval_status_id' => 1
]);
$application->users()->save($user);
$rules = [];
$validatedData = [];
if($this->showDiv1){
$rules = array_merge($rules, [
'm1_field' => 'required',
'm1_field2' => 'required',
]);
}
if($this->showDiv2){
$rules = array_merge($rules, [
'm2_field.0' => 'required',
'm2_field2.0' => 'required',
'm2_field.*' => 'required',
'm2_field2.*' => 'required',
]);
}
if($this->showDiv3){
$rules = array_merge($rules, [
'm3_field' => 'required',
'm3_field2' => 'required',
]);
}
if($this->showDiv4){
$rules = array_merge($rules, [
'm4_field.0' => 'required',
'm4_field2.0' => 'required',
'm4_field.*' => 'required',
'm4_field2.*' => 'required',
]);
}
$validatedData = $this->validate($rules);
if($this->showDiv1){
Model1::create([
'user_id' => $user->user_id,
'm1_field' => $validatedData['m1_field'],
'm1_field2' => $validatedData['m1_field2'],
]);
}
if($this->showDiv2){
foreach ($this->m2_field as $key => $value){
Model2::create([
'user_id' => $user->user_id,
'm2_field' => $validatedData['m2_field'][$key],
'm2_field2' => sanitize_money($validatedData['m2_field2'][$key]),
]);
}
}
if($this->showDiv3){
Model3::create([
'user_id' => $user->user_id,
'm3_field' => $validatedData['m3_field'],
'm3_field2' => $validatedData['m3_field2'],
]);
}
if($this->showDiv4){
foreach ($this->m4_field as $key => $value){
Model4::create([
'user_id' => $user->user_id,
'm4_field' => $validatedData['m4_field'][$key],
'm4_field2' => sanitize_money($validatedData['m4_field2'][$key]),
]);
}
}
$user->save();
alert('success','Your details are saved.');
return redirect()->route('website.landing');
}
public function update()
{
// get user info in session
$user = auth()->user();
$i = 0;
$model2 = Model2::where('user_id', $user->user_id)->get();
$model4 = Model4::where('user_id', $user->user_id)->get();
$rules = [];
$validatedData = [];
if($this->showDiv1){
$rules = array_merge($rules, [
'm1_field' => 'required',
'm1_field2' => 'required',
]);
}
if($this->showDiv2){
$rules = array_merge($rules, [
'm2_field.0' => 'required',
'm2_field2.0' => 'required',
'm2_field.*' => 'required',
'm2_field2.*' => 'required',
]);
}
if($this->showDiv3){
$rules = array_merge($rules, [
'm3_field' => 'required',
'm3_field2' => 'required',
]);
}
if($this->showDiv4){
$rules = array_merge($rules, [
'm4_field.0' => 'required',
'm4_field2.0' => 'required',
'm4_field.*' => 'required',
'm4_field2.*' => 'required',
]);
}
$validatedData = $this->validate($rules);
if($this->showDiv1){
EmploymentDetail::updateOrCreate(
[
'user_id' => $user->user_id,
],
[
'm1_field' => $validatedData['m1_field'],
'm1_field2' => $validatedData['m1_field2'],
]);
}
if($this->showDiv2){
foreach ($this->m2_field as $key => $value){
$partTime[$key]->updateOrCreate(
[
'user_id' => $user->user_id,
],
[
'm2_field' => $validatedData['m2_field'][$key],
'm2_field2' => sanitize_money($validatedData['m2_field2'][$key]),
]);
}
}
if($this->showDiv3){
Model3::updateOrCreate(
[
'user_id' => $user->user_id,
],
[
'm3_field' => $validatedData['m3_field'],
'm3_field2' => $validatedData['m3_field2'],
]);
}
if($this->showDiv4){
foreach ($this->m4_field as $key => $value){
if(!empty($model4[$i])){
$model4[$i]->updateOrCreate(
[
'user_id' => $user->user_id,
],
[
'm4_field' => $validatedData['m4_field'][$key],
'm4_field2' => sanitize_money($validatedData['m4_field2'][$key]),
]);
} else {
Model4::create([
'user_id' => $user->user_id,
'm4_field' => $validatedData['m4_field'][$key],
'm4_field2' => sanitize_money($validatedData['m4_field2'][$key]),
]);
}
}
}
alert('success','Your income are updated.');
return redirect()->route('borrower.joint_declaration');
}
public function render()
{
$income_informations = DB::table('income_informations')->get();
$showDiv1 = $this->showDiv1;
$showDiv2 = $this->showDiv2;
$showDiv3 = $this->showDiv3;
$showDiv4 = $this->showDiv4;
return view('livewire.model-component',
[
'income_informations' => $income_informations,
'showDiv1'=>$showDiv1,
'showDiv2'=>$showDiv2,
'showDiv3'=>$showDiv3,
'showDiv4'=>$showDiv4,
]);
}
}
I created a variable to store the arrays because I realized that if I simply use the model name and then do updateOrCreate() it will probably only update the first one. But the result of that update function is that it updates the first row in the database, then creates a new row for the additional row, but I want it to update the other rows in the database instead.
For more context, I followed through this tutorial for the adding input fields and saving function. Now I have trouble trying to do the update function.

Laravel Livewire Mixed Content error in production

I deployed a Laravel-Livewire on Digital Ocean and now I'm having a Mixed content problem when I try to upload a file.
Here is the error:
UploadManager.js:131 Mixed Content: The page at 'https://intake.freejiji.ca/clients/3/extensions' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://intake.freejiji.ca/livewire/upload-file?expires=1625251608&signature=9d98c598db4f6fccc01c009bcfc3051c6a97b56f4058f4d9489a8d30d6d497c2'. This request has been blocked; the content must be served over HTTPS.
The error happens when after I click "Select File" and chose the .csv file I want. Since I'mdoing this on a livewire component I'm not sure how to fix this so that the request goes over HTTPS instead of HTTP.
I was able to fix similar problems on the app by changing "asset()" with "secure_asset()"
and "route()" with "secure_url()" but in this case I'm not sure what to do.
Here is the whole "Import" component:
<?php
namespace App\Http\Livewire\Modals;
use Validator;
use Livewire\Component;
use App\Http\Traits\Csv;
use App\Models\AccountUser;
use Livewire\WithFileUploads;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;
class ImportExtensions extends Component
{
use WithFileUploads;
public $clientID;
public $showModal = false;
public $upload;
public $columns;
public $fieldColumnMap = [
'first_name' => '',
'last_name' => '',
'email' => '',
'password' => '',
'extension' => '',
'user_type' => '',
];
protected $rules = [
'fieldColumnMap.first_name' => 'required|max:255',
'fieldColumnMap.last_name' => 'required|max:255',
'fieldColumnMap.email' => 'required|max:255',
'fieldColumnMap.password' => 'required|max:255',
'fieldColumnMap.extension' => 'required|max:255',
'fieldColumnMap.user_type' => 'required|max:255',
];
protected $validationAttributes = [
'fieldColumnMap.first_name' => 'First Name',
'fieldColumnMap.last_name' => 'Last Name',
'fieldColumnMap.email' => 'Email',
'fieldColumnMap.password' => 'Password',
'fieldColumnMap.extension' => 'Extension',
'fieldColumnMap.user_type' => 'User Type',
];
public function updatingUpload($value)
{
Validator::make(
['upload' => $value],
['upload' => 'required|mimes:csv'],
)->validate();
}
public function updatedUpload()
{
$this->columns = Csv::from($this->upload)->columns();
$this->guessWhichColumnsMapToWhichFields();
}
public function import()
{
// Validate that you are importing any data
$this->validate();
$importCount = 0;
Csv::from($this->upload)
->eachRow( function ($row) use (&$importCount){
$eachRow = $this->extractFieldsFromRow($row);
// Validate each Row of the csv file
$validatedData = Validator::make([
'first_name' => $eachRow['first_name'],
'last_name' => $eachRow['last_name'],
'email' => $eachRow['email'],
'password' => $eachRow['password'],
'extension' => $eachRow['extension'],
'user_type' => $eachRow['user_type'],
],[
'first_name' => 'required',
'last_name' => 'required',
'password' => 'required|max:255',
'user_type' => 'required|in:user,admin',
'email' => 'required|email|unique:account_users',
'extension' => ['required', 'numeric', Rule::unique('account_users', 'extension')
->where(function($query)
{return $query->where("account_id", $this->clientID);
})],
],);
if($validatedData->fails()){
$this->notify(['error','Oops something went wrong!']);
}else{
AccountUser::create([
'user_id' => Auth::user()->id,
'account_id' => $this->clientID,
'first_name' => $eachRow['first_name'],
'last_name' => $eachRow['last_name'],
'email' => $eachRow['email'],
'password' => $eachRow['password'],
'extension' => $eachRow['extension'],
'user_type' => $eachRow['user_type'],
]);
$importCount++;
}
});
$this->reset();
$this->emit('refreshExtensions');
if($importCount!=0) $this->notify(['success','Successfully Imported '.$importCount.' Extensions']);
}
public function guessWhichColumnsMapToWhichFields()
{
$guesses = [
'first_name' => ['first_name', 'name'],
'last_name' => ['last_name'],
'email' => ['email'],
'password' => ['password', 'pass'],
'extension' => ['extension', 'ext'],
'user_type' => ['user_type', 'user', 'type'],
];
foreach ($this->columns as $column) {
$match = collect($guesses)->search(fn($options) => in_array(strtolower($column), $options));
if ($match) $this->fieldColumnMap[$match] = $column;
}
}
public function extractFieldsFromRow($row)
{
$attributes = collect($this->fieldColumnMap)
->filter()
->mapWithKeys(function($heading, $field) use ($row) {
return [$field => $row[$heading]];
})
->toArray();
return $attributes;
}
public function downloadTemplate()
{
$filename = 'extensions_template.xls';
$path = public_path('files/' . $filename);
return response()->download($path, $filename, [
'Content-Type' => 'application/vnd.ms-excel',
'Content-Disposition' => 'inline; filename="' . $filename . '"'
]);
}
}
If you get mixed content problem it is mostly about you fetching the assets or resources from different http scheme. Here you are using HTTP to fetch data in HTTPS site. Change all the links to have HTTPS link.
If you want to force all the routes to use https you can achieve this by using following code.
if(env('APP_ENV', 'production') == 'production') { // use https only if env is production
\URL::forceScheme('https')
}
The above should solve your problem as all contents now will load from https.

syntax error, unexpected token "<" (View: /Users/pathparakh/Projects/store/resources/views/product.blade.php) in laravel?

There are an error showing when i add #if ({{Auth::user()->utype}} == "ADM") Line of code in product.blade.php.
</head>
#if ({{Auth::user()->utype}} == "ADM")
<body>
</body>
#endif
This is my controller named ProductController.
public function index()
{
$products = Product::all();
return view('product', compact('products'));
}
public function create()
{
return view('product');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'brand' => 'required',
'detail' => 'required',
'size' => 'required',
'type' => 'required',
'price' => 'required',
'image' => 'required',
]);
$image = $request->file('image');
$new_name = rand().'.'.$image->getClientOriginalExtension();
$image->move(public_path('images'), $new_name);
$form_data = array(
'image' => $new_name,
'name' => $request->input('name'),
'size' => $request->input('size'),
'type' => $request->input('type'),
'price' => $request->input('price'),
'detail' => $request->input('detail'),
'brand' => $request->input('brand'),
);
Product::create($form_data);
return redirect()->route('product.index')->withSuccess('Done');
}
enter image description here
Please help me to solve the mistake.
You are already using blade directive, so no need to put {{}}, inside #if or any other directive try this
#if (Auth::user()->utype == "ADM")
<body>
</body>
#endif

Error column not found, but I did not declare the column?

I'm inserting a record to a polymorphic imageable table, however it says column thread_id not found. I have not declared this thread_id column and I don't know where it's pulling it from. Here is the code it's trying to run.
protected static function bootRecordImage()
{
if (auth()->guest()) return;
foreach (static::getMethodToRecord() as $event) {
static::$event(function ($model) use ($event) {
$body = request()->body;
preg_match_all('/<img .*?(?=src)src=\"([^\"]+)\"/si', $body, $matches);
$images = $matches[1];
if($event == 'created') {
foreach ($images as $image) {
$model->images()->create([
'user_id' => auth()->id(),
'imageable_id' => $model->id,
'imageable_type' => get_class($model),
'path' => $image
]);
}
}
if($event == 'deleting') {
foreach ($images as $image) {
$model->images()->delete([
'user_id' => auth()->id(),
'imageable_id' => $model->id,
'imageable_type' => get_class($model),
'path' => $image
]);
if (File::exists(public_path($image))) {
File::delete(public_path($image));
}
}
}
});
}
}
My store method:
public function store(Request $request, Channel $channel, Spam $spam)
{
if (!auth()->user()) {
return back()->withInput()->with('flash', 'Sorry! You must be logged in to perform this action.');
}
if (!auth()->user()->confirmed) {
return back()->withInput()->with('flash', 'Sorry! You must first confirm your email address.');
}
$this->validate($request, [
'title' => 'required',
'body' => 'required',
'channel_id' => 'required|exists:channels,id',
'g-recaptcha-response' => 'required'
// yes it's required, but it also needs to exist on the channels model, specifically on the id
]);
$response = Zttp::asFormParams()->post('https://www.google.com/recaptcha/api/siteverify', [
'secret' => config('services.recaptcha.secret'),
'response' => $request->input('g-recaptcha-response'),
'remoteip' => $_SERVER['REMOTE_ADDR']
]);
// dd($response->json());
if (! $response->json()['success']) {
throw new \Exception('Recaptcha failed');
}
$spam->detect(request('title'));
$spam->detect(request('body'));
$thread = Thread::create([
'user_id' => auth()->id(),
'channel_id' => request('channel_id'),
'title' => request('title'),
'body' => request('body'),
//'slug' => str_slug(request('title'))
]);
return redirect('/forums/' . $thread->channel->slug . '/' . $thread->slug);
}
As you can see, no where is a thread_id mentioned, yet in the error it looks like it's trying to insert into a thread_id column that I've never declared.
Thanks for reading.
I put the polymorphic relation in the model and the trait. Remove it from the Model and you're good to go.

Resources