My frontend is backbone and frontend is codeigniter with Phil Sturgeon’s REST Controller.
I have one model: Publisher
and one collection: Publishers
App.Collections.Publishers = Backbone.Collection.extend({
model: App.Models.Publisher,
url: '/restpublisher'
});
my RestPublisher controller has:
function index_post(){
$this->response('in pulisher_post');
}
function index_delete(){
$this->response('in pulisher_delete');
}
function index_put(){
$this->response('in pulisher_put');
}
The problem is that on this.model.save(); the url that is fired is: http://pubhub.local/restpublisher/1111 where 1111 is the id.
problem is that i get 404. if i just simulate a put request to http://pubhub.local/restpublisher/ everything works fine and i guess i can get the params from request->put()
is there a way to solve this problem?
question 2: can someone please explain me why the name of the action should start with index?
why can't i just write action: publishers_post that on save of the collection will get the data?
Thanks a Lot!
Roy
I'll start with the second question: I guess it's just easier to parse, and it'll just be boilerplate anyway, so why not index_?
Now, to go on with the interesting part. If your work with models inside a collection, Backbone, as a default behavior, will use the collection's URL to build a default one for your model (collection.url/model.id). However, you can override this by setting a value for your model's URL: url: '/restpublisher'.
Source
Edit:
To give you the general idea of how it works, it's easier to quote Backbone's Model#url code:
url: function() {
var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
if (this.isNew()) return base;
return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
}
So basically, if you override the url attribute in your model, this function will be erased, and the behavior you don't want as well.
Related
I'm working on a project where I need to create clean URL for every products, see following pattern:-
example.com/Single_Product_Page
The original URL is example.com/browse/Single_Product_Page and I used following code:-
$route['(:any)'] = 'Products/browse/$1';
I've two page (1) example.com/Product
and (2) example.com/Products/Single_Product_Page
And it is working fine but now I'm unable to open Products page and when I tried to open it, It open Single_Product_Page
Please help me to solve this issue.
You need to update your routes similar to this example (which works OK on my site):
$route['products'] = 'controller/myfunction/argument';
$route['products/:any'] = 'controller/myfunction/another_argument/$1/1';
you can get more insight from the docs here
You can use a little hack to use just your controller name (and that's a must of course) but eliminate the need to write the method name and pass your parameters directly after the controller name so basically your url would look like this: http://localhost/controller/parameter and that would give you shorter urls as you intend but not an SEO friendly as you claimed.
You can use _remap in your controller and check if it matched a method process it normally or pass it to your index (which is your default method that's doesn't have to be written in your url) .. and now you won't need to use index in your url as you intended.
public function _remap($method)
{
if ($method === 'some_method_in_your_controller')
{
$this->$method();
}
else
{
$this->index($method);
}
}
Or you can depend on ajax for all of your crud operations and your url will be pretty much fixed all the time.
I have one issue to solve about some calculations in Laravel 5.1, and until now the best solution that I found is to create Two different controllers, one to handle calculation for a specific item:
Route::get('company/convert/{note}','ScenarioController#NoteConvert');
And one for all items:
Route::get('company/convert','ScenarioController#AllNotesConvert');
Both will use render the same view.
My question is: Is a good practice to do this ?
In my head one good solution is to use just one route and receive 1 specific note or all of them in some variable through the request.
Something like:
$http.get('/company/convert/',data)
Where data will receive 1 or all notes that will be converted.
P.S.: I'm using AngularJS to call this routes.
If you prefer having one method in your controller you have to change your route a bit:
Route::get('company/convert/{note?}','ScenarioController#NoteConvert');
And your method would be something like
public function NoteConvert($note=null)
{
if ($note == null) {
// do all convertions
return view()
}
// single convertion
...
}
This way NoteConvert method will be the one that will handle multiple and single convertions.
Don't forget to remove
Route::get('company/convert','ScenarioController#AllNotesConvert');
It won't be necessary anymore
Edit:
https://laravel.com/docs/5.2/routing#parameters-optional-parameters
the best way for me, will be to passe an optional parameter in the url and check it on the controller.
i think your task is to produce the data of all items and specific data with filter using note argument in the view.
i reccomend you to create the route like this
Route::controller('company', 'ScenarioController');
then create a controller with two function like this
public function getIndex()
{
return view('convert');
}
here convert is name view blade .
public function postFilter($note)
{
$x= // do what you want
return view('convert', compact('x'));
}
then add a filter in the blade using a checkbox and make the form action url as
"company/filter/{note}".
this is the better practice i think.
refer implicit routing here. https://laravel.com/docs/5.1/controllers
I am creating the API using slim framework. I faced the following problem.
I use one of the routes for given input.That is, json input: { "tagname": "tname"}. Route is
$app->post('/tag',function () use($app, $db){
//code
});
Now, I want to use the same route for another input.json: [{"tid": "1"},{"tid": "2"}]. Route is
$app->post('/tag',function () use($app, $db){
//code
});
How do solve it?
Slim's router can't call different functions for same path based on received content.
In your particular case the simplest way to deal with two different types of input data on one route would be something like this (I assume you are getting data as POST body with application/json which is not processed by Slim2)
$app->post('/tag',function () use($app, $db){
$payload = json_decode(file_get_contents('php://input'));
if(is_array($payload)) {
// code to deal with [{"tid": "1"},{"tid": "2"}]
} else {
// code to deal with { "tagname": "tname"}
}
});
But even easier and logically would be make /tag route for single and /tags for multiple. Or just require to send all tags as array - even single one.
you can pass extra parameter to perform another action in same route and separate your code with if condition
In my controller i used this way. i want to pass a variable data to my index function of the controller through redirect
$in=1;
redirect(base_url()."home/index/".$in);
and my index function is
function index($in)
{
if($in==1)
{
}
}
But I'm getting some errors like undefined variables.
How can i solve this?
Use session to pass data while redirecting. There are a special method in CodeIgniter to do it called "set_flashdata"
$this->session->set_flashdata('in',1);
redirect("home/index");
Now you may get in at index controller like
function index()
{
$in = $this->session->flashdata('in');
if($in==1)
{
}
}
Remember this data will available only for redirect and lost on next page request. If you need stable data then you can use URL with parameter & GET $this->input->get('param1')
So in the controller you can have in one function :
$in=1;
redirect(base_url()."home/index/".$in);
And in the target function you can access the $in value like this :
$in = $this->uri->segment(3);
if(!is_numeric($in))
{
redirect();
}else{
if($in == 1){
}
}
I put segment(3) because on your example $in is after 2 dashes. But if you have for example this link structure : www.mydomain.com/subdomain/home/index/$in you'll have to use segment(4).
Hope that helps.
Use session to pass data while redirecting.There are two steps
Step 1 (Post Function):
$id = $_POST['id'];
$this->session->set_flashdata('data_name', $id);
redirect('login/form', 'refresh');
Step2 (Redirect Function):
$id_value = $this->session->flashdata('data_name');
If you want to complicate things, here's how:
On your routes.php file under application/config/routes.php, insert the code:
$route['home/index/(:any)'] = 'My_Controller/index/$1';
Then on your controller [My_Controller], do:
function index($in){
if($in==1)
{
...
}
}
Finally, pass any value with redirect:
$in=1;
redirect(base_url()."home/index/".$in);
Keep up the good work!
I appreciate that this is Codeigniter 3 question, but now in 2021 we have Codeigniter 4 and so I hope this will help anyone wondering the same.
CI4 has a new redirect function (which works differently to CI3 and so is not a like for like re-use) but actually comes with the withInput() function which does exactly what is needed.
So to redirect to any URL (non named-routed) you would use:
return redirect()->to($to)->withInput();
In your controller - I emphasise because it cannot be called from libraries or other places.
In the function where you are expecting old data you can helpfully use the new old() function. So if you had a key in your original post of FooBar then you could call old('FooBar'). old() is useful because it also escapes data by default.
If however, like me, you want to see the whole post then old() isn't helpful as the key is required. In that instance (and a bit of a cheat) you can do this instead:
print'<pre>';print_r($_SESSION['_ci_old_input']['post']);print'</pre>';
CI4 uses the same flash data methods behind the scenes that were given in the above answers and so we can just pull out the relevant session data.
To then escape the data simply wrap it in the new esc() function.
More info would be very helpful, as this should be working.
Things you can check:
Is your controller named home.php? Going to redirect(base_url()."home"); shows your home page?
Make your index function public.
public function index($in) {
....
}
I've been developing a web app using symfony2 and now I added some Angularjs.
I have an input field, where you can filter products by name, the problem is the following, I've a controller in php, I do some queries, and then I render the view, passing the parameters, in this case I do something like this,
.......
return $this->render('default/index.html.twig',array( 'products' => $products));
My question is, if I wanted to filter those products by name using angular, how can I accomplish that? (I wanted something like phonecat-app in the official angular tutorial, where you can filter by name)
So far I've done this:
var StoreApp = angular.module('StoreApp', []);
StoreApp.controller('StoreCtrl', function($scope,$http){
$http.get('http://localhost:8000').success(function(data){
$scope.stores = data;
});
});
The problem is that I don't know which URL to put in the GET parameter, I've several tables in the database, and I don't know how to address them.
I'm using a local web server on port 8000, and Doctrine.
In order to filter the data on the client side using angular, you need to get the data from your symfony2 application into the angular scope with javascript.
There are multiple ways of doing this, the quick and dirty way is to render the products array from php directly in the angular ng-init attribute as explained in https://stackoverflow.com/a/28508012/1016372 .
In my opinion the best way to get the data into your angular application is creating a "RESTful endpoint" that exposes your product data in JSON format to your angular application. Using symfony2 you could create a controller that returns the product data if you make a query for http://localhost:8000/products with a controller similar to this snippet:
class ProductController
{
public function getProductsAction()
{
$products = $this->getRepository('Products')->findAll(),
return new JsonResponse($products);
}
}
Finally I could solve the problem.
Here is my controller,
public function getAllStoresAction()
{
$em = $this->getDoctrine()->getEntityManager();
$query = $em->createQuery('SELECT s FROM AppBundle\Entity\Store s');
$result = $query->getArrayResult();
return new Response(json_encode($result), 200);
}
then my app.js
var storeApp = angular.module('storeApp', []).config(function($interpolateProvider){
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});
storeApp.controller('StoreCtrl',function($scope,$http){
$http.get('/get-all-stores').success(function(data){
$scope.stores = data;
});
$scope.orderProp = 'name';
});
and my routing.yml
get_all_stores:
path: /get-all-stores
defaults: { _controller: AppBundle:Default:getAllStores}
I managed to get the data back, but the problem was that it returned me an empty array.
Searching a bit, I found out that I wasn't serializing the data, php does not do that automatically, so I used this getArrayResult(); and it worked fine!
Thanks for the help Peter Peerdeman