Loading a custom Yii Component - php

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.

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

Using Custom Zend Validator in INI file

I don't have a custom Zend_Form and I just declared all the elements in the ini file. There is no problem with creating the Zend_Form from the ini file, but I am having problem using my own custom validator in my ini file. It always return Not Found In Registry error.
Currently, my code is like this.
[Bootstrap]
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'namespace' => 'MY',
'basePath' => dirname(__FILE__)
));
$resourceLoader->addResourceType('validator', 'forms/validate/', 'Form_Validate');
[ini file]
form.elements.new_password.options.validators.password.validator = "Password"
[Custom Validator]
<?php
class MY_Form_Validate_Password extends Zend_Validate_Abstract
{
......
Please tell me what I'm missing here. Thanks!
This is a case of over thinking:
I'm going to assume you're using a version of ZF1.x that's fairly new (v1.10 and newer).
You have a file called project/application/configs/application.ini
in a standard application.ini is the line:
includePaths.library = APPLICATION_PATH "/../library"
this tells us that all of our library code (a custom validator qualifies) would belong to the directory at this path.
Also there is the line:
autoloaderNamespaces[] = "MY_"
This tells us the name of our library (defines the directory below /library).
so our custom validator MY_Form_Validate_Password would live at:
project
/library
/MY
/Form
/Validate
Password.php
nothing else is required, all that bootstrap code is only needed if you are going to do something not anticipated by Zend Framework, also validators are not typically registered as resources.
The class can be called as
$validator = new MY_Form_Validate_Password();
as usual and any other access method should work as well.

How do i achieve a path alias in yii

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.

Zend Framework - Form class not autoloading

I'm getting
Fatal error: Class 'Form_Login' not found in /route/to/project/application/controllers/AuthController.php on line XX
when instantiating the class From_Login inside the controller.
I suppose the form is not being autoloaded by the bootstrap class.
In my bootstrap file I have this method
protected function _initAutoload(){
$modelLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH));
return $modelLoader;
}
supposed to autoload my resources.
I'm using the default project structure.
-application
--controllers
---Authcontroller.php
--forms
---Login.php
when I created the form with zf tool it automatically set the name as Application_Form_Login then I erased the Application_ part since I'm using "" namespace. I doesn't work either way.
I've also tried setting appnamespace="" in the application.ini file but nothing happened
After trying over and over different options I got tired because it didn't work so I erased the project folder and started from the beginning whit zend tool and ... voilĂ , it works!
In my opinion it was a problem with zend tool and/or the .zfproject.xml file since I was adding some resources manually and some others with the zf tool.
use Zend modular structure and change your class name 'Form_Login' to 'Default_Form_Login' .

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