codeigniter routes similar parameter - php

I'm trying to create a function album_create() that handles both insert and update process according to the parameters sent. this function needs routing to make the url prettier, so this is my routes.php:
$route['community/(\w.+)/album/create/(\w.+)'] = 'community/album_create/$1/$2';
$route['community/(\w.+)/album/create'] = 'community/album_create/$1';
$route['community/(\w.+)/album'] = 'community/album/$1';
and this is the php controller methods :
function album() {
// some code here
}
function album_create($parent_id, $post_id='') {
// some code here
}
unfortunately, only the second and third line of routing works, but the first line doesn't.
/community/12/album/create/9 // this url doesn't work
/community/12/album/create // this url works
/community/12/album // this url works
by doesn't work, I mean it only shows 404 Page Not Found
does anyone have an idea where the problem is??

Related

REST GET with parameter ignored, PHP Symfony 3 Mpdf

Working on a REST API for PDF processor using Mpdf(and tfox symfony bundle) on Symfony 3 Framework. I created two GET requests, one with no parameters for testing, and one with the parameter(URL of the HTML file) I want to read and then convert into PDF.
The Generic GET function:
/**
*
* #Rest\Get("/create")
*/
public function createPDFAction(){
$mpdfService = $this->get('tfox.mpdfport');
$html = "<h1> Hello </h1>";
$mpdf = $mpdfService->getMpdf();
$mpdf->WriteHTML($html);
$mpdf->Output();
exit;
}
The Second GET function with parameter:
/**
* #param $htmlSource
* #Rest\Get("/create/{htmlSource}")
*/
public function createPDFFromSourceAction($htmlSource){
$mpdfService = $this->get('tfox.mpdfport');
$html = file_get_contents($htmlSource);
$mpdf = $mpdfService->getMpdf();
$mpdf->WriteHTML($html);
$mpdf->Output();
exit;
}
The problem is, when I call the second function using browser or Postman the first function is always returned instead and I get the PDF with "Hello", if I remove the first GET function, I get error "no route found for GET/create"
I investigated:
The PDF URL is correct, I manually inserted it in first function and worked
No syntax error, I copied the same function without the parameters and worked
The Calls I do are:
http://localhost:8000/create This one works
http://localhost:8000/create?htmlSource=PATH-TO-FILE-LOCALLY This one doesnot work
If I put the PATH-TO-FILE-LOCALLY in function 1 manually it works fine
So I have 2 Questions:
Since I am new to REST and LAMP, should I use GET or others ? My goal is to read the HTML form that the user will fill into a variable and pass it to Mpdf which will convert it into PDF and return that PDF for viewing or download
Why only the first GET function is being read ?
Notes: I am developing on Linux, with PHPStorm, PHP 7, Symfony 3, localhost, the html file I am testing with is on my local machine
Side point: In case this is resolved, I am supposed to upload this to my clients server (which is Apache) - do you have any guides on how to do that and what should be the URLs changed to ?
Thank you all in advance
Updates:
I have changed the functionality to POST methods and it now works fine:
/**
* #Rest\Post("/mPDF/")
*/
public function createPDFAction(Request $request){
$source = $request->get('source');
if($source == ""){
return new View('No Data found', Response::HTTP_NO_CONTENT);
}
$mpdfService = $this->get('tfox.mpdfport');
$html = file_get_contents($source);
$mpdf = $mpdfService->getMpdf();
$mpdf->WriteHTML($html);
$mpdf->Output();
exit;
}
After publishing to Apache production server and some configuration tweaks the site is now live ! - but now I am facing a new issue which I will post a new question for with all the config info I have - basically POST method is returning {
"error": {
"code": 405,
"message": "Method Not Allowed"
}
}
http://localhost:8000/create?htmlSource=PATH-TO-FILE-LOCALLY
("/create/{htmlSource}")
These paths do not match.
First path consists of domain name, and route create, while second path has route "create" + slash + wildcard.
Query parameters are not defined within routing annotation. Instead, access them inside controller, using
public function createPDFFromSourceAction(Request $request)
{
$htmlSource = $request->query->get('htmlSource'); // query string parameter
$somethingElse = $request->request->get('somethingElse'); //POST request parameter
...
}
Symfony will pass Request object inside the controller for you.
As for your other question, GET requests are usually used for things that do not change the state of the application, and POST/PUT/PATCH/DELETE requests change the state. Since you are uploading something, use POST request.
For your 'side note' you should ask another question instead.

Laravel 5 - calling $request->path() in middleware causing Laravel to ignore changes made to the request URI?

Using Laravel 5.2, and using a middleware, I need to remove a certain part from the URI of the request before it gets dispatched. More specifically, in a url like "http://somewebsite.com/en/company/about", I want to remove the "/en/" part from it.
This is the way I am doing it:
...
class LanguageMiddleware
{
public function handle($request, Closure $next)
{
//echo("ORIGINAL PATH: " . $request->path()); //notice this line
//duplicate the request
$dupRequest = $request->duplicate();
//get the language part
$lang = $dupRequest->segment(1);
//set the lang in the session
$_SESSION['lang'] = $lang;
//now remove the language part from the URI
$newpath = str_replace($lang, '', $dupRequest->path());
//set the new URI
$request->server->set('REQUEST_URI', $newpath);
echo("FINAL PATH: " . $request->path());
echo("LANGUAGE: " . $lang);
$response = $next($request);
return $response;
}//end function
}//end class
This code is working fine - when the original URI is "en/company/about", the resulting URI is indeed "company/about". My issue is this: notice that the line where I echo the ORIGINAL PATH is commented (line 8). This is done on purpose. If I uncomment this line, the code is not working; when the original URI is "en/company/about", the resulting URI is still "en/company/about".
I can only reach two conclusions from this: Either sending output before manipulating the request is somehow the culprit (tested - this is not the case), or calling the $request->path() method to get the URI has something to do with this. Although in production I will never need to echo the URI of course, and while this is only for debugging purposes, I still need to know why this is happening. I only want to get the URI of the request. What am I missing here?
Sidenote: The code originated from the first answer to this post:
https://laracasts.com/discuss/channels/general-discussion/l5-whats-the-proper-way-to-create-new-request-in-middleware?page=1
I don't think that line#8 is manipulating your output.
Here is the path() method from laravel's code:
public function path()
{
$pattern = trim($this->getPathInfo(), '/');
return $pattern == '' ? '/' : $pattern;
}
As you can see it is just extracting the pathInfo without editing the request itself.

Laravel resource controller testing gives NotFoundHttpException the second time

I am encountering a very strange thing while doing testing with Laravel 4. It looks like a bug but there's probably a logical explanation.
I have replicated the "bug" in a clean Laravel install and here's my code:
My resource controller /app/controllers/TestController.php:
(Created with php artisan controller:make TestController)
class TestController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
return Response::json(array());
}
// The end of the file is unchanged
In my app/routes.php:
Route::get('/', function()
{
return View::make('hello');
});
// Note the composed part of the URL.
// My problem isn't present if I just use `myapi` or `path` as a url
Route::resource('myapi/path', 'TestController');
Added in /app/test/ExampleTest.php:
public function testTest()
{
$res = $this->call('GET', 'myapi/path');
// Until here everything works right
$this->assertEquals(json_decode($res->getContent()), array());
// Now I call the same URL a second time
$res = $this->call('GET', 'myapi/path');
$this->assertEquals(json_decode($res->getContent()), array());
}
Now I run phpunit and here's what I get:
There was 1 error:
1) ExampleTest::testTest
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
/home/me/Web/laraveltest/bootstrap/compiled.php:5531
/home/me/Web/laraveltest/bootstrap/compiled.php:4848
/home/me/Web/laraveltest/bootstrap/compiled.php:4836
/home/me/Web/laraveltest/bootstrap/compiled.php:4828
/home/me/Web/laraveltest/bootstrap/compiled.php:721
/home/me/Web/laraveltest/bootstrap/compiled.php:702
/home/me/Web/laraveltest/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/laraveltest/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:332
/home/me/Web/laraveltest/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/laraveltest/app/tests/ExampleTest.php:25
In my other project I get a slightly different backtrace, but I have the impression that's the same problem: (but I have no idea of why the other is compiled and this one not)
2) UnitModelTest::testOther
Symfony\Component\HttpKernel\Exception\NotFoundHttpException:
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php:148
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1049
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:1017
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Routing/Router.php:996
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:775
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:745
/home/me/Web/my-project/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/Client.php:81
/home/me/Web/my-project/vendor/symfony/browser-kit/Symfony/Component/BrowserKit/Client.php:327
/home/me/Web/my-project/vendor/laravel/framework/src/Illuminate/Foundation/Testing/ApplicationTrait.php:51
/home/me/Web/my-project/app/tests/UnitModelTest.php:32
In both case the line given in the trace for the test file corresponds to the second call of the test.
As I noted in the comments of the routes.php file, if I use a simple url with no slash, the test passes without problem.
I have no problem when I use the api from the browser.
I found many topics related to the NotFoundHttpException on StackOverflow, but none looks like mine. This one is specifically present when testing and only trigger an error at the second call.
So what am I doing wrong here ? Or is it really a bug ?
The problem is that calls made with the same client will use the provided URI relatively. That means what you actually call is:
myapi/path
myapi/myapi/path
You can fix this if you add a preface the urls with a / to make them absolute to the root of the application.
public function testTest()
{
$res = $this->call('GET', '/myapi/path');
// Until here everything works right
$this->assertEquals(json_decode($res->getContent()), array());
// Now I call the same URL a second time
$res = $this->call('GET', '/myapi/path');
$this->assertEquals(json_decode($res->getContent()), array());
}
If you experience other issues like that it often helps to call
$this->refreshApplication();
(This would also create a new client and therefore solve this issue as well)
In my case this error happened because i change public directory name to public_html my solution was put this in the \App\Providers\AppServiceProvider register method.
public function register()
{
// ...
$this->app->bind('path.public', function() {
return base_path('public_html');
});
}

Laravel - cannot get url GET parameters

I am having an issue trying to make a GET request to a route and process the parameters passed in via the URL. Here are two routes I created in routes.php:
$router->get('/', function() {
$test = \Input::get('id');
dd($test);
});
$router->get('test', function() {
$test = \Input::get('id');
dd($test);
});
When I go to the first URL/route ('/') and pass in some data, 123 prints to the screen:
http://domain.com/dev/?id=123
When I go to the second ('test') NULL prints to the screen (I've tried '/test' in the routes.php file as well).
http://domain.com/dev/test?id=123
A few things to note here:
This installation of Laravel is in a subfolder.
We are using Laravel 5.
Any idea why one would work and the other would not?
First thing - Laravel 5 is still under active development so you cannot rely on it too much at this moment.
Second thing is caching and routes. Are you sure you are running code from this routes?
Change this code into:
$router->get('/', function() {
$test = \Input::get('id');
var_dump($test);
echo "/ route";
});
$router->get('test', function() {
$test = \Input::get('id');
var_dump($test);
echo "test route";
});
to make sure messages also appear. This is because if you have annotations with the same verbs and urls they will be used and not the routes you showed here and you may dump something else. I've checked it in fresh Laravel 5 install and for me it works fine. In both cases I have id value displayed
You can use
Request::path()
to retrieve the Request URI or you can use
Request::url()
to get the current Request URL.You can check the details from Laravel 5 Documentation in here : http://laravel.com/docs/5.0/requests#other-request-information and when you did these process you can get the GET parameters and use with this function :
function getRequestGET($url){
$parts = parse_url($url);
parse_str($parts['query'], $query);
return $query;
}
For this function thanks to #ruel with this answer : https://stackoverflow.com/a/11480852/2246294
Try this:
Route::get('/{urlParameter}', function($urlParameter)
{
echo $urlParameter;
});
Go to the URL/route ('/ArtisanBay'):
Hope this is helpful.

Codeigniter controller created when image not found

I have a problem in CodeIgniter, and that is that when an image is not found on the server, the instance of a controller is created (besides the one that called the view).
I know all this can sound confusing, so this is the code to observe what I'm saying. I did this changes to a clean 2.1.0 CI version:
Add a controller to override the 404 error page, I added this one:
// add application/controllers/Errors.php
Class Errors extends CI_Controller {
public function error_404() {
echo 'error';
}
}
// change routes.php
$route['404_override'] = 'Errors/error_404';
Use a controller that isn’t the default one with an unexisting image, I used this:
// add application/controllers/Foo.php
Class Foo extends CI_Controller {
public function index() {
echo '<img src="doesntexist.png" />';
}
}
I couldn’t figure out another way of debugging it, so I created a log to write the events on CodeIgniter.php:
// add on CodeIgniter.php line 356
$path = 'log.txt'; //Place log where you can find it
$file = fopen($path, 'a');
fwrite($file, "Calling method {$class}/{$method} with request {$_SERVER['REQUEST_URI']}\r\n");
fclose($file);
With this, the log that generates visiting the index function is the following:
Calling method Foo/index with request /test/index.php/Foo
Calling method Errors/error_404 with request /test/index.php/doesntexist.png
Which is the problem I have, an instance of the Error class is created.
that is that when an image is not found on the server, the instance of a controller is created
Not really. What I believe is happening is that, since you're using a relative path for the image (and calling it directly inside a controller, which is wrong because you're ouputting something before headers), your browser attach the image directly to the CI url, thus making this request to the server:
index.php/doesntexist.png
Which is (correctly) interpreted by CI as a request to a controller, which doesn't exists, and therefore it issues the error class.
You could do, in your actual code (I'd put the images in a view, though):
echo '<img src="/doesntexist.png" />'
using an absoluth path, or using the base_url() method from the url helper:
echo '<img src="'.base_url().'doesntexist.png" />
This should tell the server to fetch the right request (/test/doesntexist.png) and won't trigger that error.

Categories