How do i achieve a path alias in yii - php

As per this link i have almost managed to achieve the structure. But the path alias is confusing me. Could somebody explain me how can i achieve this.
http://www.yiiframework.com/wiki/155/the-directory-structure-of-the-yii-project-site/#hh5
I want my controller in frontend to access these models from common folder.
Thanks

Use setPathOfAlias() of YiiBase class, to set a path alias:
Yii::setPathOfAlias('site', $site);
You can do this in frontend's config main.php :
$site=dirname(dirname(dirname(__FILE__))); // this will give you the / directory
Yii::setPathOfAlias('site', $site);
return array(
// the config array
// incase you want to autoload the models from common
'import'=>array(
'site.common.models.*'
)
);
As asked without auto-loading, in this case you'll have to include the model first, and only then can you instantiate it. To include we can use Yii::import($alias) , which actually does almost the same thing(from guide):
The class definition being imported is actually not included until it is referenced for the first time (implemented via PHP autoloading mechanism).
So to use a DummyModel class which is defined in common/models/ :
Yii::import('site.common.models.DummyModel');
$model = new DummyModel;
I would suggest going with auto-loading in the main.php config itself, there is no performance drop in specifying that import array, since the model will be included only if, and when it is referenced.

The best way to define your own path alias is to add 'aliases' array in /config/main.php:
return array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'name'=>'Project name',
'aliases'=>array(
'myalias'=>'/path/to/some/folder',
),
'import'=>array(
'myalias.models.*'
)
...
And then anywhere in your code you can get the path to your alias:
echo Yii::getPathOfAlias('myalias');
More info on aliases here.

Related

Override JSON view in RequestHandler in CakePHP

I want to rewrite JSON View in the RequestHandler. So there's a file project_root/lib/JsonView.php. What I want to do is to
Import the JsonView.php file in another file in project_root/app/View/CustomJsonView.php. (I think I could use App:import, would it be right ?)
Choose this file as the custom in requestHandler like this:
public $components = array('RequestHandler' => array( 'viewClassMap' => array('json' => '/right/way/to/this/file/CustomJsonView', )));
But how do I write the right way for this file ?
I also saw this one https://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html#RequestHandlerComponent::viewClassMap
but there is no explanation about the right paths to the file. My CakePHP version is 2.4.4 .
You are not supposed to pass full paths, but "short classnames", just like shown in the linked example, where ApiKit.MyJson refers to the MyJsonView view class in the ApiKit plugin, which could be located in app/Plugin/ApiKit/View/MyJsonView.php.
If you follow the conventions and place your CustomJsonView class in app/View/CustomJsonView.php as shown in the docs, you then just pass CustomJson as the short classname in the request handlers viewClassMap option.
Whether you use App::import() or just require to include the /lib/JsonView.php file, is up to you, both works. In any way you must make sure that whatever you are importing there doesn't clash with existing class names (JsonView is a kinda reserved name as it already exists in the core), and that it is either following the CakePHP view class naming conventions, or you must extend it.
See also
Cookbook > Views > Creating your own view classes
Cookbook > Core Libraries > General Purpose > App Class> Loading Vendor Files

Extend blade engine in Laravel to use different views directory

I am working on a Laravel project and I am very new to it. For now, I want to use blade templates to render views but I want it to search for views in different directories like <custom_dir>\views instead of default resources/views.
The <custom_dir> will be dynamic (it can be a variable).
Any ideas? I was thinking of a custom service provider and then extend the default function which renders views in Laravel inside it. But not sure how to implement it.
Edit:
I have user this link to extend the default functionality of include function in blade template engine. But this overrides the include functionality. I want to change the path and then call the default blade functionality
You could probably append the path to the configuration:
1) Statically, by modifying file config/view.php
'paths' => [
realpath(base_path('resources/views')),
//more paths here
],
2) Dynamically at runtime:
$paths = config('view.paths');
$paths[] = $newPathToAdd;
config(["view.paths" => $paths ]);
I suggest you use this in moderation otherwise you will just end up with a mess of directories with no real specified purpose.
You can create custom directories in resources\views directory and use them with something like this:
return view($customDirectory.'.index');
Where index is a template inside custom directory.

Kohana 3.2 multisite configuration

Right now I am sharing Kohana::Core between many sites on the same server based on this tutorial. I would like to go one step further and share everything (Controllers, Views, Models) except configs and content. Is it possible? I am using 'table_prefix' field in database config to distinguish tables for each sites. I would like to load dynamically database config base on url parameters - I think it should work.
I was thinking about changing routes to:
Route::set('default', '(<site>(/<controller>(/<action>(/<parametr>)))))')
->defaults(array(
'controller' => 'mainpage',
'action' => 'index',
));
But currently I have no idea in which place and how I should check and load appropriate configs.
There are some ways you can do this,
one way:
build a Controller_Base class
put there method before()
in this method grab the <site> param by use $this->request->param('site').
now you can load the config file in switch case or by the <site> param
by set the config name for each site as the <site>
now in every controller you should extends the Controller_Base
put before() method
and in this method use parent::before()
Hope i helped you
I found the best and the most elegant solution. I moved my application to modules directory. It was rather easy. It was necessary to change bootstrap.php to init.php by removing everything except routing. Now I can use all controllers, models and views many times with standard multisite configuration.

Loading a custom Yii Component

I am trying to use a custom class I have created to send out mail so I can keep the controller files thin. I created my custom class and put it in the components folder. I then added:
'sendMail' => array(
'class'=>'application.components.SendMail.',
),
underneath main components in my main config file.
This should allow me to access the class directly correct? I try using:
Yii::app()->SendMail->MailerConfirmation();
and:
Yii:app()->MailerConfirmation();
and all I end up with is errors.
Can anyone tell me how I include a custom component? Maybe I am doing this all wrong?
First it should be:
'sendMail' => array(
'class'=>'application.components.SendMail',
),
Notice the absence of dot in the end "SendMail" instead of "SendMail.". Also, this configuration expects that you have php file SendMail.php, in protected/components directory that is a class with name "SendMail" and that this component extends CApplicationComponent. The component id will be with lower first letter, eg Yii::app()->sendMail and this will return instance of "SendMail" class. I do not know what MailerConfirmation is, but if this is a method of SendMail object, then you should access it like Yii::app()->sendMail->MailerConfirmation()
If this doesn't help, then please post some code and post the errors you are getting.
Note that if you are not going to set any component properties in the config file or use other CApplicationComponent features and your config file includes the default:
'import'=>array(
'application.models.*',
'application.components.*',
),
You can put your SendMail.php class in the components directory and it will autoload by calling it via:
$mailer = new SendMail();
then call your methods via:
$mailer->MailerConfirmation();
if you do want to use CApplicationComponent, you may want to look here or here for a couple examples, as well as the Yii tutorials.

Zend Framework Autoloader question

In zend framework I register my namespace like this (in application.php):
'autoloaderNamespaces' => array(
'Cms_'
)
And after this - I'd expect that Zend would always check that path in addition to Zend and ZendX paths if unknown class is called. But for some reason this doesn't work with for example view helpers.
I still have to register a separate path for my view helpers even though view helper scripts are named according to Zend coding standards and are located in:
Cms/View/Helper/
And this is how I register helper path in config file:
view' => array(
'charset' => 'UTF-8',
'doctype' => 'XHTML1_TRANSITIONAL',
'helperPath' => array(
'Cms_View_Helper_' => 'Cms/View/Helper'
)
),
So - I'm not sure why I have to register "Cms" namespace twice first through 'autoloaderNamespaces' and then through View "helperPath"? Shouldn't Cms namespace include Cms/View/Helper namespace?
can someone plz clarify this:)
View Helpers are considered application specific, so in the Recommended Project Directory Structure View Helpers are supposed to be placed in application/views/helpers. Which means, they usually wouldn't be found if ZF would just resolve the conventionalized class name.
When you call helpers with $this->helperName() or $this->getHelper('HelperName') from the View, the View will use the PluginLoader with the configured prefix and path to fetch that helper and inject the current View Instance. See sourcecode for all the details:
http://framework.zend.com/svn/framework/standard/trunk/library/Zend/View/Abstract.php
http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Loader/PluginLoader.php
So in other words, when loading a ViewHelper, you are not using the Autoloader. See:
Loading Plugins in the Zend Framework Reference Guide
This is taken directly from one of my application.ini files.
autoloaderNamespaces.Foo = "Foo"
includePaths.library = APPLICATION_PATH "/../library"
My "Foo" libraries are in the library directory - library/Foo. All I've done up until this point is make the "Foo" library available within the include paths.
I need to add a separate helper path to the default list for my view, otherwise the view won't look in that directory for matching view helpers. I think of loading view helpers as direct discovery. The view needs explicit instructions on where to look for helpers.
I believe it is exactly as you describe, the documentation on custom view helpers is pretty explicit about it:
You may, and should, give the class name a prefix, and it is recommended that you use 'View_Helper' as part of that prefix: "My_View_Helper_SpecialPurpose". (You will need to pass in the prefix, with or without the trailing underscore, to addHelperPath() or setHelperPath()).
This does make some sense to me though. In theory you could build a library of generic view helpers that could be re-used across multiple applications, so binding them to a specific application namespace would be inconvenient, i.e. if all my helpers were prefixed 'MyApp_' I would have to rename them to be able to use them in 'MyOtherApp'.

Categories