How do I monitor file system access in Laravel? - laravel

I'm trying to find a way to monitor basic information regarding the access of files on my applications filesystem. The files are stored using the public driver, and are available publicly through the appropriate symlink. I want to add a record to a databased whenever a file is accessed. Is there a way to accomplish this without creating a separate controller? Maybe a filesystem middleware type mechanism?

First, static files don't get handled by your PHP application (in this case Laravel), those are handled by your web server (Nginx, Apache, etc).
The usual configuration will only route the request to PHP if is a PHP request and will just serve the file if is a static file.
You could tell the web server to route all static files through a specific URL of your application and then in your controller serve that file and save the statistics, but I advice you against this, because static files are very efficient served by the web server and you would add a lot of work that affects the performance if you process them through a PHP application.
A solution
You could create a Laravel console command that gets call with each new line of the log file and use maybe SupervisorD to make sure the command is always called.
So, you could have something like this to call your command:
tail -F -n 1 /path/to/access.log | /usr/bin/php /path/to/application/artisan register:log
Where -F will handle the log rotation, -n 1 will use the first last line (or maybe you could try with -n 0) to make sure you don't consider old lines if for some reason the process gets restarted and register:log can be signature of your console command in Laravel.
That way, each new line in the access log will call your command with the log line as input.

Related

Laravel configuration usage for different servers in pure php file

I am new in Laravel and want to know such problem
I am running an web application on several server using Laravel.
But I have encountered with an issue.
When there is modification for the project, I need to sync with git on several servers.
But it has different settings for each server (eg: DB name, DB password...)
I have set it manually because I couldn't use .env or configuration file since the file is just pure php file.
The issue I want to solve is how can I get Laravel configuration data from pure PHP file(not controller or whatever).
It will be thankful if someone teach me solution.
You asked:
how can I get Laravel configuration data from pure PHP file
The answer would be this:
You just make some file in config/ folder of laravel app (or use the existing file like config/app.php)
You make an array of your key value pairs
<?php
return [
'some_key' => 'some_value',
...
and you simply call it with this code where ever you need it:
config('config_file.key');
for example
config('app.name');
would give you Laravel by default.

Play! Framework 2.1.3 pdf problems

so I am working on a school project in which we have designed a web application that takes in much user info and creates a pdf then should display that pdf to the user so they can print it off or save it. We are using Play! Framework 2.1.3 as our framework and server and Java for the server side. I create the pdf with Apache's PDFbox library. Every thing works as it should in development mode ie launching it on a localhost with plays run command. the issue is when we put it up to the server and launch with plays start command I it seems to take a snapshot of the directory (or at least the assets/public folder) which is where I am housing the output.pdf file/s (i have attempted to move the file elsewhere but that still seems to result in a 404 error). Initially I believed this to be something with liunx machine we were deploying to which was creating a caching problem and have tried many of the tricks to defeat the browser from caching the pdf
like using javascript to append on a time stamp to the filename,
using this cache-control directive in the play! documentation,
"assets.cache./public/stylesheets/output.pdf"="max-age=0",
then I tried to just save the pdf as a different filename each time and pass back the name of that file and call it directly through the file structure in the HTML
which also works fine with the run command but not the start.
finally I came to the conclusion that when the start command is issued it balls up the files so only the files that are there when the start command is issued can be seen.
I read the documentation here
http://www.playframework.com/documentation/2.1.x/Production
which then I noticed this part
When you run the start command, Play forks a new JVM and runs the
default Netty HTTP server. The standard output stream is redirected to
the Play console, so you can monitor its status.
so it looks like the fact that it forks a new JVM is what is causing my pain.
so my question really is can this be gotten around in some way that a web app can create and display a pdf form? (if I cannot get this to work my only solution
that I can see is that I will have to simulate the form with HTML and fill it out from there) --which I really think is a bad way to do this.
this seems like something that should have a solution but I cannot seem to find or come up with one please help.
i have looked here:
http://www.playframework.com/documentation/2.1.x/JavaStream
the answer may be in there but Im not getting it to work I am pretty novice with this Play! Framework still
You are trying to deliver the generated PDF file to the user by placing it in the assets directory, and putting a link to it in the HTML. This works in development mode because Play finds the assets in the directory. It won't work in production because the project is wrapped up into a jar file when you do play dist, and the contents of the jar file can't be modified by the Play application. (In dev mode, Play has a classpath entry for the directory. In production, the classpath points to the jar file).
You are on the right lines with JavaStream. The way forward is:
Generate the PDF somewhere in your local filesystem (I recommend the temp directory).
Write a new Action in your Application object that opens the file you generated, and serves it instead of a web page.
Check out the Play docs for serving files. This approach also has the advantage that you can specify the filename that the user sees. There is an overloaded function Controller.ok(File file, String filename) for doing this. (When you generate the file, you should give it a unique name, otherwise each request will overwrite the file from a previous request. But you don't want the user to see the unique name).

MVC allow an IIS default page in subfolder without breaking parent route

I need to bypass an MVC route for an application where the developer left - we're going to fully replace it, but for now if I can bypass this one route, it'll save us a ton of time.
The route is (e.g.) www.this.site/path/subpath
Since it's on IIS, I can take advantage of the default document and create the following folder / file structure: /path/subpath/index.htm
However if I do this, I'll "break" the parent www.this.site/path route (it throws a 403 - Forbidden: Access is denied) because I now have an actual file folder where the /path/ route was.
Is there a way to get around this / have IIS defer to MVC on /path/ but still handle the child html file?
thanks. Again, this is not intended as a long term solution but a work-around until we can replace the app entirely.
Perhaps a better workaround would be to use the IIS AAR module and it's reverse proxy functionality out the app.
To do so:
a) stand up the app at it's own site the proper path -- so it should work at something like http://localhost:1234/path/subpath/index.htm
b) install IIS AAR module and enable the reverse proxy functions using the WebPI and the IIS management tools
c) Ignore the /path/subpath route in your app
d) Add a virtual directory for /path/subpath to IIS
e) Configure that to reverse back to localhost:1234 or whatever port you configured the site
This will keep the legacy app completely separate while keeping the public facing URLs looking correct for the rest of the world.

With GroceryCrud, how can I put uploads above application root?

I'm using GroceryCRUD to act as a front end for a database containing news releases. Secretaries can go in and add/edit/delete news releases in the database easily now. Only qualified users are able to access the application root via an .htaccess password. The problem with this is that GroceryCRUD uploads assets such as photos are uploaded to the directory /www/approot/assets/uploads/ which is password protected since /approot/ is protected.
My ideal solution would be to set an upload directory outside of the application root which is where I'm running into trouble. By default this is how GroceryCRUD handles uploads:
$this->grocery_crud->set_field_upload('photo1','assets/uploads/');
I've tried changing it to something like this:
$this->grocery_crud->set_field_upload('photo1','/public/assets/uploads/');
I was hoping this / would make the path start from the document root instead of the application root, but it throws this error:
PHP Fatal error: Uncaught exception 'Exception' with message 'It
seems that the folder "/Users/myusername/www/approot//public/assets/uploads/"
for the field name "photo1" doesn't exists.
This seems to suggest that CI or GroceryCRUD just takes the second argument in set_upload field and just concatenates it onto the end of the site URL that is defined. Is there any way around this that doesn't involve creating a user login system?
Try using relative path.
$this->grocery_crud->set_field_upload('photo1','../assets/uploads/');
.. -> Go up one directory
I ended up implementing a login system outlined in this tutorial:
http://net.tutsplus.com/tutorials/php/easy-authentication-with-codeigniter/
It was quite simple to set up and suits my needs. I found ways to give access to the directory using httpd.conf directives but I feel like this was a more viable solution since I don't have direct access to server configuration files.
Maybe in the future GroceryCRUD will allow placement of uploads outside the application folder.

Serving Files in Zend Framework MVC

What is the best practice when serving files from the Zend Framework MVC? These files have to be served from the MVC as they are protected.
I know you can read in the file and place it into the Response object but this seems like a bad practice as you would be reading the entire file into memory then serving it. Right now I usually do:
header('Content-type: image/jpeg');
fpassthru(fopen($path, 'rb'));
exit;
But this also doesn't seem right as I'm stopping the execution of the script. Any suggestions?
I see nothing wrong with just exit(); What you will need to be careful of is any output buffering layers you may have on (gzip compression, etc). Large files could blow up those buffers pretty quick, so you'll want to close them out and potentially 'chunk' your output with a fopen/fread loop.
I would suggest building a super-simple script for retrieving files based on ticket system like in CMS you generate ticket to DB - filename, unique-hash and than redirect to the super-simple file-retieving script (file.php?hash=asd52ad3as1g5). It will get the hash from query and based on it fetch the real filename and push that to output as you have written using fpassthru. The hash need to be unique and hard to guess...
You could try using the X-Sendfile header. It is supported by lighttpd and newer versions of apache. Basically the webserver will replace the output of the script with the file you specified. The downside being that it is specific to the configuration of the webserver, so you may be on a host that doesn't support it.

Resources