How to include two controller in url in codeigniter 3? - codeigniter

I want to include two controller in a url. Ex. domian.com/category/js/topic/promise. In this, category and topic are controllers and js is argument of category controller, and promise is argument of topic controller.
I have searched, and doesn't found any related example like it. So, How can I achieve this type of url which contains two controller url? I am using codeigniter 3.
/* code of category controller*/
class Category extends MY_Controller{
public function index($category = null){
if($category == null){
// here show all categories using model
}
else{
// show topics of given category
}
}
}
/* code of topic controller */
class Topic extends MY_Controller{
public function index($topic = null){
if($topic == null){
// here show all topics using model of the selected category
}
else{
// show data of selected topic
}
}
}

To use your Topic/index method with your desired url structure, you need to add the following to config/routes.php:
$route['category/(:any)/topic/(:any)'] = "topic/index/$2";
domain.com/category will then show all categories
domain.com/category/index/js will show all topics in a specific category
domain.com/topic will show all topics in all categories
and both domain.com/category/js/topic/promise and domain.com/topic/index/promise will then show a specific topic
If you also need to access the selected category in Topic/index, add it as an argument:
class Topic extends MY_Controller{
public function index($topic = null, $category = null){
if($topic == null){
// here show all topics using model of the selected category
}
else{
// show data of selected topic
}
}
}
And change the route to pass the category from the url onto the method:
$route['category/(:any)/topic/(:any)'] = "topic/index/$2/$1";

Related

Get all badges with user progress if any

I have a many to many relationship between users and achievements. Table layout is similar to this.
users
-id
-first_name
-last_name
-email
acheivements
-id
-type-name
-description
achievement_user
-id
-acievement_id
-user_id
-is_complete (boolean)
-percentage_complete (integer)
-completed_at
I can get the bulk of the stuff I want such as all achievements with type = badge for a user that are in the pivot table. I can also get a list of all the achievements that have type = badge. Where I am stuck is trying to get all achievements with type = badge along with is_complete, percentage_complete, completed_at for that given user. So if there are 8 total badges and they have started 3 of them I would want to return 8 records where 3 of them would have the information from the pivot table. I know I could grab all badges and loop through them to add on additional information but I know there is a eloquent way that would be easier.
Thank for any help.
This is in response to you recent comment.
To achieve what you want, I have introduced a new method on the User model called achievementsblock, which uses php array_map method.
I have not tested the code, but you should get the idea.
//in User model
public function achievements()
{
return $this->belongsToMany('App\Achievements')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//in User model
public function achievementsblock()
{
$all_achievements = Achievement::all();
return array_map(function($temp_achievement){
$achievement_ids = $this->achievements()->pluck('id');
$new_temp = new \stdClass();
$new_temp->type_name = $temp_achievement->type_name;
$new_temp->description = $temp_achievement->description;
if(in_array($temp_achievement->id, $achievement_ids)){
$user_achievement = $this->achievements()->where("achievements.id","=",$temp_achievement->id)->first();
$new_temp->is_complete = $user_achievement->is_complete;
$new_temp->percentage_complete = $user_achievement->percentage_complete;
$new_temp->completed_at = $user_achievement->completed_at;
}
else {
$new_temp->is_complete = 0;
$new_temp->percentage_complete = 0;
$new_temp->completed_at = null;
}
return $new_temp;
}, $all_achievements);
}
In your controllers, you can get the achievementsblock for a user as follows:
$user_achievement_blocks = User::first()->achievementsblock();
On your belongsToMany relationship, use the withPivot function as follows:
//in User model
public function acheivements()
{
return $this->belongsToMany('App\Acheivement')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//in Acheivement model
public function users()
{
return $this->belongsToMany('App\User')->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
You need to learn about whereHas method which lets you query on relationship while getting results
In User model
// create achievements relationship
public function achievements()
{
return $this->belongsToMany(Achievement::class)
->withPivot('is_complete', 'percentage_complete', 'completed_at');
}
//then query it like shown below.
$achievements= $user->achievements;
Read more here

Laravel slug performance eloquent

I have setup a route like this:
Route::get('/prod/{id}/{title?}', 'Web\GetItemController#getItem')->where('id', '[0-9]+')->name('prod.item');
This is to retrieve a item based on the id the title is only a optional parameter in order to make the url look somewhat nicer.
Then in the controller I fetch the item like this:
class GetItemController extends Controller
{
public function getItem($id, $title = null)
{
$item = new product();
$data = $item->getProdInfo($id);
// Show view with data...
}
}
So I should be able to fetch the item with or without the title parameter.
So a call like this would trigger the route "https://www.x.com/prod/3/sonic-free-games"
But is there any difference in performance using slug like I do above?
/prod/{id}/{title?} vs /prod/{id}

How to setup conditional relationship on Eloquent

I have this (simplified) table structure:
users
- id
- type (institutions or agents)
institutions_profile
- id
- user_id
- name
agents_profile
- id
- user_id
- name
And I need to create a profile relationship on the Users model, but the following doesn't work:
class User extends Model
{
public function profile()
{
if ($this->$type === 'agents')
return $this->hasOne('AgentProfile');
else
return $this->hasOne('InstitutionProfile');
}
}
How could I achieve something like that?
Lets take a different approach in solving your problem. First lets setup relationship for the various models respectively.
class User extends Model
{
public function agentProfile()
{
return $this->hasOne(AgentProfile::class);
}
public function institutionProfile()
{
return $this->hasOne(InstitutionProfile::class);
}
public function schoolProfile()
{
return $this->hasOne(SchoolProfile::class);
}
public function academyProfile()
{
return $this->hasOne(AcademyProfile::class);
}
// create scope to select the profile that you want
// you can even pass the type as a second argument to the
// scope if you want
public function scopeProfile($query)
{
return $query
->when($this->type === 'agents',function($q){
return $q->with('agentProfile');
})
->when($this->type === 'school',function($q){
return $q->with('schoolProfile');
})
->when($this->type === 'academy',function($q){
return $q->with('academyProfile');
},function($q){
return $q->with('institutionProfile');
});
}
}
Now you can access your profile like this
User::profile()->first();
This should give you the right profile. Hope it helps.
you can do this by use another method please check this:
a blog Post and Video model could share a polymorphic relation to a
Tag model. Using a many-to-many polymorphic relation allows you to
have a single list of unique tags that are shared across blog posts
and videos. First, let's examine the table structure:
https://laravel.com/docs/5.4/eloquent-relationships#many-to-many-polymorphic-relations
Looks like that should be $this->type rather than $this->$type - since type is a property, not a variable.

Laravel 5 - relationships and handling data

I have a system whereby you can create Documents of different types. Initially, I had a new Model for each Document, but I don't think this is the best way because it can get messy fast. So what I wanted to do is make a generic Documents model, and have individual documents come from this. I have come up with the following type of design
So a Document can have one DocumentA and one DocumentB. DocumentA and DocumentB can only ever be created once per project which is why I have this relationship. Now each form for each document has an upload button, where supporting documents can be uploaded alongside the generated document. So Documents can have one to many FileUploads.
This is where I am confused. A person visits my portal and selects the option to create DocumentA. A form is now displayed to them which looks something like the following
So they enter the data for DocumentA, upload supporting documents, and then click submit.
Now I am thinking about how this can be handled within Laravel.
From what I understand, it will be something like the following
public function store(Request $request, Project $project)
{
$document = new Documents();
$document->documentName = 'Something';
$document->documentA = new DocumentA();
$document->documentA->startDate = Input::get('startDate');
$document->documentA->endDate = Input::get('endDate');
$document->documentA->notes = Input::get('notes');
if (Input::hasFile('filePath')) {
$files = Input::file('filePath');
foreach($files as $file) {
$fileString = "";
$file->move(public_path('uploads'), $file->getClientOriginalName());
$fileString .= public_path('uploads') . '/' . $file->getClientOriginalName();
$document->fileUpload = new FileUploads();
$document->fileUpload->filename = $file->getClientOriginalName();
$document->fileUpload->mime = $file->getClientOriginalExtension();
$document->fileUpload->filepath = $fileString;
$document->fileUpload->documentId = $document->id;
}
}
$document->save();
return Redirect::route('projects.documentA.edit', compact('project', 'documents'));
}
Really, looking for advice as to whether I am designing this correctly, and whether I am handling it correctly within Laravel. I am going to end up with many different Documents, each of them accepting different input.
Any advice appreciated.
Thanks
you want to create different tables for each doc? like you showed above for A and B. It will become messy. Why do not you just manage this in one table by using some identifier col?
If you create one table for documents, one for fileUploads then you would create relationship between them like so
File upload model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
/**
* each file belongs to a document
*/
public function document()
{
return $this->belongsTo('App\Document', 'foreign_key', 'primary_key');
}
}
Document model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Document extends Model
{
/**
* document has multiple files
*/
public function files()
{
return $this->hasMany('App\File', 'foreign_key', 'primary_key');
}
}
Then you can access the records like this
$documents->files()->where('id', 1)->get();
//gives file associated with document id 1

Prestashop custom layout for specific category

Can I have a specific category layout for selected categories? The detail page will be the same, I need to get a custom tpl file.
Thanks for suggestions
Pretty easy to do: override the category controller to set the template.
class CategoryController extends CategoryControllerCore {
// array with the selected categories
private $customCategories = array(1, 3);
public function init() {
parent::init();
if (in_array($this->category->id, $this->customCategories)) {
$this->setTemplate(_PS_THEME_DIR_.'category-custom.tpl');
}
}
}
Here you wouldn't be able to change the selected categories from the back office, but it would be easy to do with a module.

Resources