I am trying to create a single ZF2 installation with multiple websites under it, with each site being a separate module. So far, with using Hostname routing, it works, except that all of the sites share the same public folder.
Is there a way to configure each module to have its own public folder?
I have seen some other questions about this, but they have mostly dealt with the routing itself or been ZF1 specific, which kept the public folder within the module.
You can quite easily do what you want:
site1.com document root: ~/project/site1/public
site2.com document root: ~/project/site2/public
~/project/site1/public/index.php and
~/project/site2/public/index.php both contain:
<?php
// Set time zone.
date_default_timezone_set('Europe/Paris');
/**
* This makes our life easier when dealing with paths. Everything is relative
* to the application root now.
*/
define('ROOT_PATH', dirname(__DIR__.'../'));
chdir(dirname(__DIR__.'../'));
// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
return false;
}
// Setup autoloading
require 'init_autoloader.php';
// Run the application!
Zend\Mvc\Application::init(require '../config/application.config.php')->run();
You can have as many public folder as you want. Just put in index.php valid include of zf2 core and everything should work without any special modifications (what module to display can be specified by domain path or via global configuration you will put inside index.php).
Still I think is perfectly fine to have one public folder and change active modul per domain, also use some asset manager with configuration and content encapsulated inside module. Best for this is rwoverdijk/AssetManager.
Related
I'm building a PHP package and in it I have a folder (let's say /vendor/myvendor/packagename/src/Classes) which I want to autoload using PSR-4.
But I would also like to provide an option to copy that folder from its current location to the project root (let's say /packagename/Classes, something along the lines of Laravel's publish command).
So how could I go about autoloading it?
I would like Composer to first see if the folder exists under the app's root, and if it does then autoload that. Else fall back to the default location inside /vendor. Is that possible?
FWIW, this is Laravel specific package, which means that I could use Laravel's publish command to copy the entire folder where ever, but then
I would have to manually add the new location to autoload;
Even if I do, there would be namespace conflict between the old and new location.
I would like Composer to first see if the folder exists under the app's root, and if it does then autoload that. Else fall back to the default location inside /vendor. Is that possible?
Yes, it is possible.
You need to mention everything on your ServiceProvider for your package.
There are every informations about how to publish your views, assets in the docs and it fits your needs.
Have a look at the docs:
https://laravel.com/docs/5.3/packages#public-assets
I am copying some example for you over here:
If you want to publish your translations, you need to perform this task:
/**
* Perform post-registration booting of services.
*
* #return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
$this->publishes([
__DIR__.'/path/to/translations' => resource_path('lang/vendor/courier'),
]);
}
If you don't have translation in app's lang/vendor/courier then it falls back to your package translation.
You don't need to copy your class codes, which could remain in your package directory. The only things you copy will be your views, assets, translation files etc.
This should help you.
I have a Laravel site running locally on my machine, but I'd like to make it live. I already pay for shared hosting, and I have a number of sites running on the shared host in their own subdirectories. So for example, in the shared hosting, I have:
public_html/site1
public_html/site2
etc.
These are all personal sites. So I'd like to put my Laravel site on there too:
public_html/laravelsite
The issue is that I obviously don't want the majority of the files to actually be publicly accessible. If I split them up though and just put the public site files into public_html/laravelsite and put the rest of the files in a folder above public_html, nothing will be able to locate anything else and the site won't work.
Is there another work-around I can use to secure my files?
When users request your site, the starting point is always public/inde.php. So put the public folder where you want and the rest (Laravel) where you want. Then from public/index.php, try to link bootstrap/autoload.php.
For instance, in your case you would go to public/index.php and change lines 22 and 36 so they can still find the autload.php file like this:
22. require __DIR__.'/../bootstrap/autoload.php';
becomes
22. require __DIR__.'/../../laravel_folder/bootstrap/autoload.php';
And
36. $app = require_once __DIR__.'/../bootstrap/app.php';
becomes
35. $app = require_once __DIR__.'/../../laravel_folder/bootstrap/app.php';
There are other ways of doing the same. Just find the one that suits your needs.
For Elixir, "...you may begin any file path with ./. This instructs Elixir to begin at the project root, rather than using the default base directory". Source: https://laravel.com/docs/5.3/elixir. So you have do something like this to change the source
elixir(function(mix) {
mix.sass('./app/assets/sass/app.scss');
});
You can do the same to change the destination.
Now if you want to minimize the differences between your dev and prod, reorganize your folder in dev to have a similar structure.
Try opening AppServiceProvider.php and modify as following:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('path.public', function() {
return base_path().'/public_html/laravelsite';
});
}
}
And put the contents of public folder to laravelsite folder.
Most obvious solution - just tell your server to not serve files from /public_html/laravelsite?
For instance if your shared hosting is using apache, create an .htaccess file in /public_html/laravelsite with
Deny from all
Then go to your laravel's .htaccess file in the public directory and add
Allow from all
I moved all the public images of my website to a folder out of the web folder of symfony so it can be shared with other web applications.
I created a symbolic link to this folder so it can be accessed from the web folder of the symfony application.
ln -s /absolute/path/to/images /path/to/symfony/application_01/web/images
ln -s /absolute/path/to/images /path/to/symfony/application_02/web/images
Etc... for all applications.
I'm looking for a method that would allow me to retrieve the images URI in my development environment on localhost as well as in my production environment on the remote web server.
I would like to be able to retrieve this URI from the twig template AND from the controller.
Basically (for my application_01 for instance):
In the development environment it would return:
http://localhost/images/my_image.jpg
In the production environment, it would return:
http://www.application_01.com/images/my_image.jpg
My problem is that I found lots of different ways to get URIs but I'm not totally clear about how Symfony manages them and what functions to use to have a global solution working in all cases.
What is the best way to achieve my goal?
EDIT
Specifically I found some SO answers to quite similar questions proposing to use the following functions:
$request->getScheme();
$request->getHttpHost();
That seems to correspond to the values or superglobals $_SERVER['REQUEST_SCHEME'] and $_SERVER['HTTP_HOST']
And I don't know if this is the proper way to get this information since this is linked to the current request received by the server.
Isn't there another way to get this info independently from the request currently processed by the server?
Define the following url
image_url:
path: /images/{image}
Then use it like this
/** #var Router $router */
$router = $this->get('router');
$url = $router->generate('image_url', ['image' => 'my_image.jpg'], Router::ABSOLUTE_URL);
$url now contains the absolute url to your image. And of course it's the best practice you can think of :)
----- Answer to your comment about app_dev.php
We used this solution in our company months ago.
preg_replace('#/(.+?)\.php)', '', $router->generate('my_url');
http://techimho.com/index.php/2015/10/15/generate-production-url-in-dev-environment/
I have a problem when upload laravel project on my shared hosting. On that hosting I have two addon domains with separate folders in document root. But when I put laravel project in document root and move everything from public folder in root to remove that "/public" from url, I cant access to my addon domains. I'm getting 500 Internal service error. When I remove .htaccess file I can access to my other domains, but I can't access to my Laravel project. How can I change default laravel .htaccess file?
Well, you should not move everything from public folder, this is a very important part of your Laravel application, it was built this way to separate your application source code from the public files anyone can access, if you make your application root also your public folder, anyone will be able to access any php files from your application, and this is so unsafe...
What you need to do is to point your document root to /serverRoot/applicationRoot/public.
If you really cannot do that, I'm afraid you'll have to edit index.php and try to change thos two lines:
require __DIR__.'/../bootstrap/autoload.php';
$app = require_once __DIR__.'/../bootstrap/start.php';
to
require __DIR__.'/bootstrap/autoload.php';
$app = require_once __DIR__.'/bootstrap/start.php';
And see if it works for you.
EDIT
Laravel's default .htaccess file is there just for rewriting your URLs, so you dont see aindex.php` on them. Basically it does 2 things:
1) If you access your site using http://www.site.com/, internally it will point to http://www.site.com/index.php.
2) When you access your site using http://www.site.com/index.php it hides the index.php part.
This is kind of recursive, because the first step leads to the second one.
Now you have to think and see how this is conflicting with your other domains, because the files you are serving in those domains matters and since we are not aware of what they are, helping more is kind of difficult.
In a Zend Framework 1.10 application, I have a controller UsersController in a module api and in the index view of that controller I would like to reference a static asset (like a javascript file). How can I do that without putting the file in the main public?
so, we have a directory setup like this:
zfproj/
../application/modules/api/controllers/UserController.php
../application/modules/api/views/scripts/users/index.phtml
../application/modules/api/public/javascript/apimodule.js
../application/controllers/
../application/views/
../public/
I want to be able to include the apimodule.js in a view (in this case the users/index view). Ideally, this would able to be done without adding anything into zfproj/public
The intention behind this is to create a module that can be deployed into a ZF 1.10 application that is completely self-contained and does not require adding assets (like Javascript files) into the applications existing public/javascript files.
Typically all your publicly accessible assets go in public. It's meant to be the web root of your application and typically you set the DOCUMENT_ROOT of your apache virtual host to this folder. I'm not sure why you'd want to store client files (javascript, css, etc) outside the webroot. Can you elaborate more on your directory/application structure (maybe hinting at the location of the file you want to include)?
Edit
What you're asking should be possible. To make a standalone module, I think you'd just move "api" inside the primary public folder and the module would have its own bootstrap or you'd have to do something in your primary bootstrap based on the module name ("api" in this case). You'd have to modify your include paths accordingly. You'd need to add an .htaccess file to protect your code directories in this case.
../application/controllers
../public/api/controllers
../public/api/javascript/apimodule.js
../public/api/index.php
You might also create a symlink in your public folder that points to the public folder of api. So,
../public/api > ../application/modules/api/public
This would allow access to public but protect your code files. One thing I often do is check out subversion external into the public folder that just points to the public folder of the module. My CMS looks like this:
application/modules/cms
application/modules/cms/ui (public facing cms UI)
public/ui (svn:external pointing to application/modules/cms/ui)
HTH give you some ideas.