I'm trying to set an alias in Yii2 but I'm getting a Invalid Parameter / Invalid path alias for the below code that is placed in the app config file:
'aliases' => [
// Set the editor language dir
'#editor_lang_dir' => '#webroot/scripts/sceditor/languages/',
],
If I remove the # it works.
I noticed you can do this:
Yii::setAlias('#foobar', '#foo/bar');
...but I would prefer to set it within the app config file. Is this not possible? If so, how?
Yii2 basic application
To set inside config file, write this inside $config array
'aliases' => [
'#name1' => 'path/to/path1',
'#name2' => 'path/to/path2',
],
Ref: http://www.yiiframework.com/doc-2.0/guide-structure-applications.html
But as mentioned here,
The #yii alias is defined when you include the Yii.php file in your entry script. The rest of the aliases are defined in the application constructor when applying the application configuration.
If you need to use predefined alias, write one component and link it in config bootstrap array
namespace app\components;
use Yii;
use yii\base\Component;
class Aliases extends Component
{
public function init()
{
Yii::setAlias('#editor_lang_dir', Yii::getAlias('#webroot').'/scripts/sceditor/languages/');
}
}
and inside config file, add 'app\components\Aliases' to bootstrap array
'bootstrap' => [
'log',
'app\components\Aliases',
],
In config folder create file aliases.php. And put this:
Yii::setAlias('webroot', dirname(dirname(__DIR__)) . '/web');
Yii::setAlias('editor_lang_dir', '#webroot/scripts/sceditor/languages/');
In web folder in index.php file put:
require(__DIR__ . '/../config/aliases.php');
Before:
(new yii\web\Application($config))->run();
If run echo in view file:
echo Yii::getAlias('#editor_lang_dir');
Show like this:
C:\OpenServer\domains\yii2_basic/web/scripts/sceditor/languages/
#webroot alias is not available at this point, it is defined during application bootstrap :
https://github.com/yiisoft/yii2/blob/2.0.3/framework/web/Application.php#L60
No need to define this alias yourself, you should simply use another one :
'aliases' => [
// Set the editor language dir
'#editor_lang_dir' => '#app/web/scripts/sceditor/languages/',
],
To improve on #vitalik_74's answer
you can place it in config/web.php instead(if you are using the basic yii app, I'm not sure about the main config file in the advance version, but the same applies, just put the require on the main config file) so that it gets shorten to:
require(__DIR__ . '/aliases.php');
Related
how I can load an external-site module? I have a common module I need to load in distinct Yii2 sites, like advanced-template my idea is to have a common dir where store generic modules wich I can load to each site. A file system structure can be like this:
/
site-1/
(loads modules from common-modules dir for site-1)
site-2/
(loads modules from common-modules dir for site-2)
common_sites_modules/
module-1/
module-2/
carrello/
Carrello.php
Each site in his configuration have to load modules from common-modules/
Is possible to implement this structure?
Edit 1
The configuration:
'cart' => [
'class' => dirname(dirname(dirname(__DIR__))) . '/common_sites_modules/carrello/Carrello',
'params' =>[
...
],
'components' => [
...
],
],
and this is the first line of the class Carrello.php:
<?php
namespace common_sites_modules\carrello;
...
The top bar of editor with the path of the class and the error returned by Yii:
Edit 2:
Thanks to #Yupik for support and suggests, the new settings:
bootstrap.php:
Yii::setAlias('#common-modules', dirname(dirname(dirname(__DIR__))) . '/common_sites_modules');
main-local.php:
'class' => '#common-modules\carrello\Carrello',
The generated error:
Like suggested in the comments the solution is to declare an alias and then use the name of alias for call the module. Like suggested by #Yupik I've set in the common/config/bootstrap.php an alias as follow:
Yii::setAlias('#common_modules', dirname(dirname(dirname(__DIR__))) . '/common_modules');
In the main configuration:
'carrello' => [
'class' => ''common_modules\carrello\Carrello',
...
]
Obviously namespace have to be configured based on the position on filesystem.
Thanks for the suggestions
Yes, we can do this by making a symlink of common_sites_modules directory in both site folder (site1, site2).
I have a CakePHP 3.3.14 application where I've created 2 subdirectories, webroot/data/downloads/ and webroot/data/master
I want to put these paths in a custom configuration file and reference them in a Controller. But I can't see how to do this.
I've followed the documentation on Configuration but it's not very clear.
So what I've done:
Created config/my_config.php
The above file defines an array:
return [ 'downloadsPath' => 'webroot/data/downloads/', 'masterPath' => 'webroot/data/master/' ];
In config/bootstrap.php I've put: Configure::load('my_config', 'default');
How do I then use this in a Controller? If I put Configure::read('my_config.masterPath'); it gives an error saying: Class 'App\Controller\Configure' not found
If I add use Cake\Core\Configure; to the top of my Controller, that clears the error but the return value is null:
debug(Configure::read('my_config.masterPath')); // null
Loading another config file just extends the default App.config. So just use \Cake\Core\Configure::read('masterPath') and you are good.
EDIT
If it is your goal to have different config paths you could do it like this:
// my_config.php
return [
'MyConfig' => [
'masterPath' => '...',
...
]
];
Then use the config like this:
<?= \Cake\Core\Configure::read('MyConfig.masterPath') ?>
I have one file inside config folder lets say: file1
File Location:
config/
---file1.php
I have following code in my file: file1.php
return [
'MASTER_KEY' => ['SUB_KEY1' => 'SOME_VALUE', 'SUB_KEY2' => 'SOME_VALUE', 'SUB_KEY3' => 'SOME_VALUE'],
];
How to access the value from MASTER_KEY of particular SUB_KEY?
Assuming for SUB_KEY2, Try -
config('file1.MASTER_KEY.SUB_KEY2')
Guide
In order to access that value you have 2 choices which are the same at the end:
first one: which use Config refers to the config facade.
use Config;
$myValue = Config::get('file1.MASTER_KEY.SUB_KEY1');
enter code here
second one: using config() helper function which uses Config facade and its only an alternative and easy way to use Config facade.
$myValue = config('file1.MASTER_KEY.SUB_KEY1');
use
config('file1.keyname');
if you have made any changes in config file then it might not work . so after changes in config file you have to run the following two commands .
php artisan config:cache
php artisan config:clear
Make a use Config; in your controller.
In config/file1.php
<?php return [
'ADMIN_NAME' => 'administrator',
'EMP_IMG_PATH' => '../uploads/profile/original',
'EMP_DOC_PATH' => '../uploads/profile/documents', ];
In controller
use Config;
$variable= Config::get('file1.EMP_DOC_PATH');
By this way you can get the variables value from config.
I think this will make something good.
I can't put the library under vendor/ because that directory is ignored in .gitignore. I put it under bing-ads/ and I have
<?php
namespace app\models;
include 'bing-ads\v10\bingads\ClientProxy.php';
use \Yii;
use BingAds\Proxy\ClientProxy;
to access it. It works for console commands/actions, but I have a feeling it will not work during a web call because the root directory will be web/. Where should I put this library and how can I access it via both console actions and web actions?
The Microsoft PHP library is located here.
I found a way by adding the file paths to the autoload section of composer.json. I remembered that I had to do that for some of the other libraries as well, even the ones available via Composer.
"autoload": {
"classmap": [
"vendor/googleads/googleads-php-lib/src/Google/Api/Ads/Common/Util",
"vendor/googleads/googleads-php-lib/src/Google/Api/Ads/AdWords/Util/v201605",
"bing-ads/v9/bingads/CustomerManagementClasses.php",
"bing-ads/v10/bingads/v10/CampaignManagementClasses.php",
"bing-ads/v10/bingads/v10/BulkClasses.php",
"bing-ads/v10/bingads/ClientProxy.php"
]
}
Then I ran
$ composer install
...
Generating autoload files
I'm not sure this is the best way though.
You could store them wherever you want e.g. in a folder named "BingAds".
Just add the alias as example in a common base config file /common/config/base.php which is included in your console as well as in your web application e.g. for your /web/index.php
$config = \yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../common/config/base.php'),
require(__DIR__ . '/../common/config/web.php'),
require(__DIR__ . '/../config/base.php'),
require(__DIR__ . '/../config/web.php')
);
Inside this common/config/base.php you could add your settings, extensions etc. which are valid for both the console and your web application
<?php
$config = [
...
'aliases' => [
'#BingAds' => '#app/BingAds/v10',
'#BingAds/Proxy' => '#app/BingAds/v10/bingads',
],
];
Your Clientproxy.php is stored as example in the directory /BingAds/Proxy/.
Then you don't have to include your files every time you want to use them and just write.
use BingAds\Proxy\ClientProxy;
I have unpacked your linked zip file and stored the files of the directory Bing Ads API in PHP\PHP\Bing Ads API in PHP to my application root directory BingAds whith the aliases mentioned above.
I have tested it by creating a clientProxy object in both a console and web application.
$test = new ClientProxy('test');
var_dump($test);
Both Printed out
object(BingAds\Proxy\ClientProxy)[140]
private 'authenticationToken' => null
private 'username' => null
private 'password' => null
private 'developerToken' => null
private 'wsdlUrl' => string 'test' (length=4)
private 'accountId' => null
private 'customerId' => null
private 'service' => null
private 'namespace' => null
I haven`t tested out other classes but I guess you get how it works.
Add this to your composer.json:
{
"repositories": [
{
"type": "package",
"package": {
"name": "microsoft/bing-ads",
"version": "9.0.0",
"dist": {
"url": "https://code.msdn.microsoft.com/Bing-Ads-API-Version-9-in-fb27761f/file/159208/2/Bing%20Ads%20API%20in%20PHP.zip",
"type": "zip"
},
"autoload": {
"classmap": [
"PHP/Bing Ads API in PHP/v10/bingads/"
]
}
}
}
],
"require": {
"microsoft/bing-ads": "9.0.0"
}
}
Then add composer generated autload.php file if you haven't already.
Then you can call the BingAds\Proxy\ClientProxy() without includes.
There's no better way:)
It's best to place external library to extensions directory.
And in config do
return [
'import' => [
'application.extensions.bing-ads.v10.bingads.ClientProxy',
],
...
];
in main and in console configs.
I usually just put the code in a components folder. If you're using the basic template, this folder can be under your application root; if you're using the advanced template, this folder can be under the necessary app: frontend, backend, console, or common. I recommend putting it under common for reasons I shall explain later
Under every app config, Yii 2 uses the ::setAlias method to assign different aliases to the key folders. In the basic app template, #app refers to the application root. While in the advanced template #app may refer to any of backend, frontend, or console.
If your library code is under backend, you can access it like so
namespace backend\controllers;
use yii\web\Controller;
use backend\components\MyLibCode;
class SiteController extends Controller
{
public function actionIndex()
{
$mlb = new MyLibCode();
// ...
}
}
However, it is good Yii 2 practice to have common library code in the common folder. So if this library code is to be used across apps, I suggest you put it into the common\components folder and replace backend with common in the use statement in the code above.
p.s: Justinas method also works; it's borrowed from Yii 1. But this may become cumbersome because this asks Yii to load the class when the application starts. If there is some heavy-lifting in that file, it may be detrimental to the app's performance.
i'm using laravel 4.2
I have 2 application folders namely 'app' and 'backend':
I edited bootstrap/start.php so that when i access www.site1.com/backend it will go to 'backend' application. Hence, it will go to the 'app'.
// override app folder to backend
if (defined('ENVIRONMENT') && ENVIRONMENT == 'backend')
{
$path_settings['app'] = __DIR__.'/../backend';
$path_settings['storage'] = __DIR__.'/../backend/storage';
}
I want to add a specific classmaps when I access /backend. I don't want to edit composer.json and add classmap there. How can I programattically do that?
You can try to use Composer's ClassLoader directly. Something like this:
$loader = new \Composer\Autoload\ClassLoader();
// PSR-0
$loader->add('My\Backend', __DIR__.'/../backend');
// PSR-4
$loader->addPsr4(....);
// class map
$loader->addClassMap(...);
// activate the autoloader
$loader->register();
In your file config/view.php add :
'paths' => [
realpath(base_path('backend'))
],