Routing REST Codeigniter - php

I am creating a REST server and would like to create a url like so
DELETE /companies/3/employees/45
The endpoint should delete employee 45, which belongs to company 3.
How exactly would i go about creating a above URL using codeigniter.

Try the following:
In your routes.php add a new route:
$route['companies/(:num)/employees/(:num)'] = 'companies/employees/$1/$2';
Where companies is the controller and employees is the action.
and in your controller, write action something like:
//Use some kind of input validations for the Ids
public function employees($companyId = 0, $employeeId = 0)
{
if(strtolower($_SERVER['REQUEST_METHOD']) == 'delete')
{
//delete query here
}
}
This uses CI routing to get params, and uses superglobal $_SERVER to determine whether the Request Method being used for the call is DELETE.

first you need to make a rest app like this link
Then you can make a route like
$route["companies"]["delete"] = 'company/delete';
In your controller company
function delete ( ) {
foreach($this->input->post() as $item => $value){
${$item} = $value;//making variables $employee_id, $company_id
}
//logic to delete
}
You need to send that info by post or make almost the same sending it to get

Related

Replacing object ID by object name on URL on Laravel route

I am trying to make my URL more SEO friendly on my Laravel application by replacing the ID number of a certain object by the name on the URL when going to that specific register show page. Anyone knows how?
This is what I got so far and it displays, as normal, the id as the last parameter of the URL:
web.php
Route::get('/job/show/{id}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
Controller method
public function show($id){
$job = Job::findOrFail($id);
return view('website.job')->with(compact('job'));
}
Blade page where there is the link to that page
{{$job->name}}
You can overwrite the key name of your Job model:
public function getRouteKeyName()
{
return 'name';
}
Then in your route simply use {job}:
Route::get('/job/show/{job}', ...);
And to call your route:
route('website.job.show', $job);
So your a tag would look like this:
{{ $job->name }}
Inside your controller, you can change the method's signature to receive the Job automatically:
public function show(Job $job)
{
return view('website.job')
->with(compact('job'));
}
For more information, look at customizing the key name under implicit binding: https://laravel.com/docs/5.8/routing#implicit-binding
You need simply to replace the id by the name :
Route::get('/job/show/{name}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
In the controller action:
public function show($name){
//Make sure to replace the 'name' string with the column name in your DB
$job = Job::where('name', $name)->first();
return view('website.job')->with(compact('job'));
}
Finally in the blade page :
{{$job->name}}
2 options:
1) one is like #zakaria-acharki wrote in his comment, by the name of the job and search by the name for fetching the data
2) the second is to do it like here in stackoverflow
to build the url with the id/name
in this way you will make sure to fetch and show the relevant job object by the unique ID
the route:
Route::get('/job/show/{id}/{name}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
in the controller, update the check if the name is equal to the job name (in case it was changed) to prevent duplicate pages url's
public function show($id, $name){
$job = Job::findOrFail($id);
// check here if( $job->name != $name ) {
// redirect 301 to url with the new name
// }
return view('website.job')->with(compact('job'));
}
in the blade.php :
{{$job->name}}

Copy one row from one table to another

I need a little help and I can’t find an answer. I would like to replicate a row from one data table to another. My code is:
public function getClone($id) {
$item = Post::find($id);
$clone = $item->replicate();
unset($clone['name'],$clone['price']);
$data = json_decode($clone, true);
Order::create($data);
$orders = Order::orderBy('price', 'asc')->paginate(5);
return redirect ('/orders')->with('success', 'Success');
}
and i got an error :
"Missing argument 1 for
App\Http\Controllers\OrdersController::getClone()"
.
I have two models: Post and Order. After trying to walk around and write something like this:
public function getClone(Post $id) {
...
}
I got another error
Method replicate does not exist.
Where‘s my mistake? What wrong have i done? Maybe i should use another function? Do i need any additional file or code snippet used for json_decode ?
First of all, make sure your controller gets the $id parameter - you can read more about how routing works in Laravel here: https://laravel.com/docs/5.4/routing
Route::get('getClone/{id}','YourController#getClone');
Then, call the URL that contains the ID, e.g.:
localhost:8000/getClone/5
If you want to create an Order object based on a Post object, the following code will do the trick:
public function getClone($id) {
// find post with given ID
$post = Post::findOrFail($id);
// get all Post attributes
$data = $post->attributesToArray();
// remove name and price attributes
$data = array_except($data, ['name', 'price']);
// create new Order based on Post's data
$order = Order::create($data);
return redirect ('/orders')->with('success', 'Success');
}
By writing
public function getClone(Post $id)
you are telling the script that this function needs a variable $id from class Post, so you can rewrite this code like this :
public function getClone(){
$id = new Post;
}
However, in your case this does not make any sence, because you need and integer, from which you can find the required model.
To make things correct, you should look at your routes, because the url that executes this function is not correct, for example, if you have defined a route like this :
Route::get('getClone/{id}','YourController#getClone');
then the Url you are looking for is something like this :
localhost:8000/getClone/5
So that "5" is the actual ID of the post, and if its correct, then Post::find($id) will return the post and you will be able to replicate it, if not, it will return null and you will not be able to do so.
$item = Post::find($id);
if(!$item){
abort(404)
}
Using this will make a 404 page not found error, meaning that the ID is incorrect.

How to send multiple variable to a view in laravel when one or more variables are null

When a new user is registered and is redirected to profile page. All these $userconatact , $qualification and $profileimage variables are null. Home page is setup with if (condition) to have buttons to fill form or show available data to user. There are three forms and user has to fill these form one by one. All these variables or one of them could be null but I still want to send the null value to view. Is there any way to make this view happen.
class ProfileController extends Controller
{
public function showprofile($type=null, $id='id'){
$contactquery = Usercontact::where('user_id',Auth::user()->id)->select('*')->get();
$usercontact = $contactquery->toArray();
$qualificationquery = userqualification::where('user_id',Auth::user()->id)->select('*')->get();
$qualification = $qualificationquery->toArray();
$profileimagequery = Profileimage::where('user_id',Auth::user()->id)->select('id','user_id','profileimage')->get();
$profileimage = $profileimagequery->toArray();
return view('home')->withUsercontact($usercontact)->withQualification($qualification)->withProfileimage($profileimage);
}
}
I tried using if statements but if didn't work
return view('home')
if(!empty($usercontact)){->withUsercontact($usercontact)}
if(!empty($qualification)){->withQualification($qualification)}
if(!empty($profileimage)){->withProfileimage($profileimage);}
Is there any way to use if statements like this to make it easy.
1) Use compact which will automatically create key value pairs for you.
return view('home')->compact('usercontact','qualification','profileImage')
2) Here are a few other improvements to your code. You can use the Auth facade to access the logged-in user.
$usercontact = Auth::user();
3) Define relationships on your user model and access the qualifications by this. This will return a Collection.
$qualification = $usercontact->qualifications;
You can use compact to send data from your controllers to views.
return view('home')->compact('usercontact', 'qualification', profileimage');
Your code can be refactored as below.
public function showprofile($type=null, $id='id')
{
$usercontact = Usercontact::where('user_id',Auth::user()->id)->first();
$qualification = Userqualification::where('user_id',Auth::user()->id)->first();
$profileimage = Profileimage::where('user_id',Auth::user()->id)->select('id','user_id','profileimage')->first();
return view('home')->compact('usercontact', 'qualification', 'profileimage');
}
Note the Userqualification model name in the code according to the convention. Try to add relationships to your models to make your query easier.
Try this style to send data to view
return view('home',['Usercontact'=>$usercontact,'Qualification'=>$qualification,'Profileimage'=>$profileimage]);
In view you will be able to get data by array key

Yii deleteAll() records with condition

I've set up a log in process where a verification code is generated, and when successful, is then removed. However, i want to make sure that if there's multiple verification codes for the same user, upon log in success, delete all records for that user.
Here's my code
if ($model->validate() && $model->login()) {
//delete this verification code
$verificationCode->delete();
//delete all existing codes for user_id
VerificationCode::model()->deleteAll('user_id',$user->id);
Yii::app()->user->setReturnUrl(array('/system/admin/'));
$this->redirect(Yii::app()->user->returnUrl);
}
However, this seems to just delete all the records, regardless on different user_id's in table. Can anyone see where I'm going wrong?
If you want to delete record with specified attributes, the cleanest way for this is to use deleteAllByAttributes():
VerificationCode::model()->deleteAllByAttributes(['user_id' => $user->id]);
Seems you call the function delete() in wrong way ... try passing value this way
VerificationCode::model()->deleteAll('user_id = :user_id', array(':user_id' => $user->id));
For Yii2, the documented way is to use the function deleteAll().
I normally pass the arguments as an array, like so:
VerificationCode::deleteAll(['user_id' => $user->id]);
Also, you can use the afterDelete method, to make sure that everytime or everywhere someone deletes one verificationCode, your application will also delete every userVerificationCode. Put this in your verificationCode model class:
protected function afterDelete()
{
parent::afterDelete();
VerificationCode::model()->deleteAll('user_id = :user:id',[':user_id' =>$this->user_id]);
//... any other logic here
}
You can use below method for deleting all user_id entry from database:
$criteria = new CDbCriteria;
// secure way for add a new condition
$criteria->condition = "user_id = :user_id ";
$criteria->params[":user_id"] = $user->id;
// remove user related all entry from database
$model = VerificationCode::model()->deleteAll($criteria);
or you can use another method directly in controller action
VerificationCode::model()->deleteAll("user_id= :user_id", [":user_id"
=>$user->id]);
use below method for redirecting a URL
$this->c()->redirect(Yii::app()->createUrl('/system/admin/'));

CodeIgniter Restserver doesn't work with specific URL's

I am using this Restserver in combination with CodeIgniter.
It seems to work pretty well except when I use URL's like these;
mydomain.com/api/example/1234/
wherein 1234 is the ID I'm requesting.
Code like this doesn't seem to work:
class Example extends REST_Controller {
public function index_get() {
print($this->get("example"));
}
}
It doesn't seem to matter whether it is a GET or POST request. There must be a way I can just retrieve the ID from the URL..
The URL's segments should equal to these:
api = Controller
example = Resource
Parameters must be in key-value pairs:
id = Key
1234 = Value
It seems that your 1234 is treaded as a key, but with no value for it. Try to change your URL to the following: mydomain.com/api/example/id/1234/, which would translate to: mydomain.com/controller/resource/key/value/
There is also a very detailed tutorial here: http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/
EDIT:
Since your controller is in a sub-folder, your URL's segments should be constructed like this:
api/example = Controller
user = Resource // basically the method name + the http method e.g. user_get(), or user_post(). I just made 'user' up, for your app can be whatever it is that people will access via your api
Parameters must be provided as key-value pairs:
id = Key
1234 = Value
So then your URL would look like this: mydomain.com/api/example/user/id/1234/
in the case of a GET REQUEST you just define the parameters in the header of the function like this:
public function index_get($param) {
print($param);
}
if you want to make it optional then:
public function index_get($param="") {
if ($param=="") {
print("No Parameters!");
} else {
print($param);
}
}
If I want to send "POST" parameters, I just create a POST METHOD and receive them as such...
public function index_post() {
$params = $this->post();
if (isset($param['id'])) {
print($param['id']);
} else {
print("No Parameters!");
}
}

Categories