-1
'urlManagerBackend' => [
        'class' => 'yii\web\urlManager',
        'baseUrl' =>  'http://backend.test',
        'enablePrettyUrl' => true,
        'showScriptName' => true,
    ],

then I want to display the image saved under uploads directory

<img src="<?= Yii::$app->urlManagerBackend->baseUrl; ?>/uploads/logo.jpg>

the problem is this url must not be hardcode like this:

'baseUrl' =>  'http://backend.test',
SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
adnen manssouri
  • 51
  • 2
  • 11
  • How do you mean must not be hardcoded in configuration? You have different environments and based on env you can set different url. Maybe you have multiple urls? – borisaeric Nov 19 '19 at 10:04
  • the url 'http://backend.test' is static i can't use it after the deployment of the project – adnen manssouri Nov 19 '19 at 10:11
  • Do you have a way to determine backend domain in frontend? Since the domain pointed to the backend folder can be anything there is no universal way how to find it. But if you have some way to determine domain (for example you know that the backend domain will be `backend.frontend-domain.example`), you should be able to set the url manager's baseUrl in application's [EVENT_BEFORE_ACTION](https://www.yiiframework.com/doc/api/2.0/yii-base-module#EVENT_BEFORE_ACTION-detail). – Michal Hynčica Nov 19 '19 at 10:52

6 Answers6

1

The only way how to dynamically determine the domain of the other application (for example the backend from your frontend) would be by parsing the web server's configuration files.

The domain for current application (the one you can get with Url::base(true)) is determined from the request headers or variables set by web server. But those are available only for current application, not for any other application even if they are part of same project.

If you want to parse web server's configuration files than you will have to face three major challenges:

  1. Different web servers have different syntax for configuration files.
  2. Configuration files might be located anywhere.
  3. You might not have access rights to read the configuration files.

So it might be better to try to think about some workaround instead of insisting on determining the domain dynamically.

  1. Make a deploy script that would ask for the backend domain. The one who will be deploying your application on production servers will know the domain for the backend application and can enter it during deployment process. The deploy script will then set the entered backend domain in your configuration files.
  2. Make a page in backend that must be visited before accessing the frontend application. You can determine the domain for backend when the page in backend is visited then set that domain in frontend configuration files. If the frontend is accessed before the domain for backend is set you will only display the notice that the backend page must be accessed first.
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Michal Hynčica
  • 5,038
  • 1
  • 12
  • 24
0

In the config folder there should be a file called params.php. If you have something like this

<?php

return [
    'adminEmail' => 'admin@example.com',
    'baseUrl' =>  'http://backend.test',
];

You can use it in your code like this

<img src="<?= Yii::$app->params['baseUrl']; ?>/uploads/logo.jpg>

Then when you move to live, you just need to edit the params.php file.

Mike
  • 182
  • 1
  • 3
  • 15
  • this url 'http://backend.test' is hardcoded but I Must not use hardcoded URLs. – adnen manssouri Nov 19 '19 at 10:42
  • How will you then determine URLs? @adnenmanssouri @Mike why you use `$this->redirect`, it should work fine without that function as well? `````` – borisaeric Nov 19 '19 at 22:36
  • Oops!!! Thanks Borisa, it was cut and paste gone badly!! I've edited my answer. – Mike Nov 20 '19 at 08:27
  • yes it work without using the $this->redirect @BorisaEric i can't use 'http://backend.test' because this is a static adress ,i want it dynamic URL ,The problem still exists right Now. i need for help – adnen manssouri Nov 20 '19 at 08:28
  • Adnen - I'm confused as to your definition of dynamic. My usual thought would be that you have 2 (or more) URL's, say backend.test and backend.live and each has its own set of program files. In this scenario, the way I put would work. How do dynamic URL's work for you? – Mike Nov 20 '19 at 08:35
  • in the Backend if you want the URL you can use Url::base(true); this solution work in the same time in backend.test and backend.live URLs, If we could use a method similar to this to get the URL , I hope you understand what I want now – adnen manssouri Nov 20 '19 at 10:13
0

Too long comment so I need to put it here.

But I'm just wondering in which case that makes sense, except if you are creating web applications, sites, ..., through your application, which I doubt you do. You know your local domain (use local environment and put urls). You will know your dev domain (use dev environment and put urls). You will know your production domain (use prod environment and put urls).

You can also have multiple applications inside yii2 project, so for example, 10 applications across 3 envs, that is 30 urls which you will enter in you configs.

Can you please tell me, how you will access your app if url is dynamically determined -> without using anything else except Yii?

What is your step? You are typing in your browser what? Then we can proceed. Maybe we misunderstand each other.

urlManagerBackend' => [
    'class' => 'yii\web\urlManager',
    'baseUrl' =>  'http://backend.test',
    'enablePrettyUrl' => true,
    'showScriptName' => true,
]

If you are wondering you can also have multiple urlManagerBackend components across Yii2 environments. Just like with params. Add it on multiple corresponding places at config. So in specific environment you place at same file only key => values which you need to override.

borisaeric
  • 573
  • 5
  • 12
0

You could simply use Assets and Aliases for this:

If you have a backup/web/uploads/ folder in which you save images uploaded via your backend and you'd like to display those images on your frontend.

Create a new asset file in your frontend/assets/, let's call it BackendAsset.php:

<?php

   namespace frontend\assets;
   use yii\web\AssetBundle;

   class BackendAsset extends AssetBundle {
      public $sourcePath = '@backend/web/uploads';
   }

where $sourcePath is the backend-folder (source) you'd like to access on the frontend. The @backend alias is predefined in the advanced template, so we'll use it.

Now in our view we can simply use the BackendAsset:

<?php

    use frontend\assets\BackendAsset;
    $backend = BackendAsset::register($this);

?>

and now we can easily display a file, let's say backend/web/uploads/somefile.jpg:

<img src="<?= $backend->baseUrl . '/somefile.jpg' ?>" >

NOTE: Using the asset in this way copies all the files from the backend/web/uploads to an asset folder in the frontend. To prevent that, you can tell your application not to copy the files, but to link to them (creating SymLinks) instead, unsing linkAssets (yii2 docu):

In your app configuration (in this case frontend/config/main.php), set the linkAssets parameter to TRUE:

'components' => [
    'assetManager' => [
        'linkAssets' => true,
        ]
    ]
David Lang
  • 93
  • 1
  • 9
  • This can solve the issue for assets. But assets are not all cases where you are using url manager. For example you might need to create a link or redirect user to the backend app. – Michal Hynčica Nov 22 '19 at 09:58
  • The OP specifically mentioned that he wants to "display the image saved under uploads directory" (from the backend, in the frontend) and "no hardcoded URL" - which my suggestions does. Redirecting a user to the backend app is something completely different (which I'd solve using a Symlink like example.com/backend) – David Lang Nov 22 '19 at 10:18
  • If you want to limit the question to displaying the image then creating symlink in `frontend/web` that would point to the `../../backend/web/uploads` might be better solution than using assets. Every time the new file is uploaded into `backend/web/uploads` the hash for assets will change. That means all images will be copied to new folder in `frontend/web/assets` or the new symlink will be created there while the old folder/link will stay there. That might lead to issues with disk space or the number of inodes. – Michal Hynčica Nov 22 '19 at 10:51
0

I solve this problem by saving the full url in the database.

adnen manssouri
  • 51
  • 2
  • 11
-1

What about putting a reverseproxy (e.g. nginx) in front of the frontend-server?
Could be configured like:

http://frontend/backend/* -> forwards everyhing to the backend service, the rest will still go to the frontend server.

The configuration (in this case the location of the backend server) of this reverseproxy can be changed any time (also after deployment).

Could that be a viable scenario?