Zend: Which Class/Controller should i access from out of the module? - zend-framework

I have a running application and added my first module. Everthing works fine. Now i want want to use my module in the existing application.
I have the following folders:
application
- classes
- configs
- controllers
- ....
- modules
- discount
- configs
- controllers
- layouts
- models
- plugins
- views
- ....
- views
In an existing class under application/class i want to use some functions that belong to the module.
Now my questions:
1) Where should i store these functions i want to access from outside?
2) How can i access these from outside?

I assume your module is already registered with your application, for example in application/configs/application.ini, like so:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
After that, the files belonging to your module can be accessed anywhere you like, as they are now part of your application. So for example, in application/controllers/IndexController.php you could simply do:
$myModel = new Discount_Model_MyModel();

Related

Laravel 4 using vendor classes

I have installed Laravel 4 after using 3, love it.
I used to be able to use the Zend framework as such:
$yt = new Zend_Gdata_YouTube();
for instance
I have used composer to install Zend and everything is installed in the Vendor folder..
Problem:
How to address the individual classes i.e. Zend Gdata etc.
I can't find any documentation on calling classes from a vendor in L4.
Any help is appreciated.
Take a look at your vendor\composer\autoload_classmap.php file. In there you will find a list of all vendor classes that are being autoloaded. I think all classes will have to be called using their full namespaced name.
E.g.
I'm using Zizaco's Entrust package. This is what it looks like in the vendor\composer\autoload_classmap.php file.
'Zizaco\\Entrust\\Entrust' => $vendorDir . /zizaco/entrust/src/Zizaco/Entrust/Entrust.php',
If I wanted to access the Entrust.php class I have to call
$en = new Zizaco\Entrust\Entrust();
Alternatively you could alias certain classes in your app\config\app.php file.
E.g.
'Ent' => 'Zizaco\Entrust\Entrust'
In your case you'll need to do something like this:
$yt = new Zend\namespace\Zend_Gdata_YouTube();

Using Zend view helper from admin module with default module layout

I have a view helper being called in my layout that works fine in the default module, but I get an exception when I am in another module.
I have already changed my app.ini to use the default layout across all modules by setting:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
And searching here and google provided me with another app.ini setting to add the view helper path for all modules:
resources.view.helperPath.Zend_View_Helper = APPLICATION_PATH "/views/helpers"
However instead of fixing the problem, that additional setting causes the Zend Exception to become a WSOD.
Without that second app.ini setting, I see the layout and get this exception:
Plugin by name 'AutoScript' was not found in the registry; used paths: Admin_View_Helper_: /Applications/XAMPP/xamppfiles/htdocs/dad/application/modules/admin/views/helpers/ Zend_View_Helper_: Zend/View/Helper/:./views/helpers/
With the helperPath.Zend_View_Helper ini setting I get a WSOD with the following:
Fatal error: Uncaught exception 'Zend_Loader_PluginLoader_Exception' with message 'Plugin by name 'AutoScript' was not found in the registry; used paths: Zend_View_Helper_: Zend/View/Helper/:./views/helpers/'
It appears the plugin loader is looking in public/views/helpers/ for the AutoScript.php file even though it should be using the APPLICATION_PATH value as a prefix.
My layout invocation looks like this
<?php $this->AutoScript(); ?>
My AutoScript.php file's class is defined in application/views/helpers/
class Zend_View_Helper_AutoScript extends Zend_View_Helper_Abstract {
public function AutoScript() {...}
}
My current fix is to copy the AutoScript.php file from application/views/helpers into modules/admin/views/helpers which fixes the issue, but duplicates a file. What am I missing? Do I have to add this view helper path programmatically by creating an _initView function in my bootstrap?
Typically, you would name your custom view helper with your own prefix, not the Zend_ prefix. Beyond that, there are several choices for where to put and name your view helpers.
If this view-helper is really a single-application helper, then I find it natural for it to reside somewhere in the application folder. Within that possibility space, I would ask if the view-helper will be used in a single module or across multiple modules.
If the view-helper is intended for use in a single module, then I depend upon the build-in resource-autoloader mappings and place my view-helper class Mymodule_View_Helper_Myhelper in the file application/modules/mymodule/views/helpers/Myhelper.php.
If the view-helper is intended for use across multiple modules , I might pull it up a little higher than the modules folder, say Application_View_Helper_Myhelper (assuming an appnamespace of Application) stored in
application/views/helpers/Myhelper.php. In this case, we need to tell the view that there are helpers with prefix Application_View_Helper_ in that directory. This can be done at bootstrap:
protected function _initViewHelperPaths()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->addHelperPath(APPLICATION_PATH . '/views/helpers', 'Application_View_Helper_');
}
Sometimes, you need a view-helper in one module that exists in another module and you cannot - in practical terms - move the original one around. In that case, one workaround is to define an empty shell of a view-helper in your consuming module extending your unmovable view-helper. In file application/mymodule/views/helpers/MyHelper.php:
class Mymodule_View_Helper_Myhelper extends Othermodule_View_Helper_Myhelper
{
}
This way, the code for the helper implementation is not duplicated. The module-specific resource-autoloader mappings will allow all those classes to be found when they invoked as view-helpers from a view-script.
Finally, if this view helper is to be used in multiple projects, then there is an argument for placing it outside of application scope, out in in the library folder. So perhaps a class MyLibrary_View_Helper_Myhelper stored in the file library/MyLibrary/View/Helper/Myhelper.php. As before, you would need to inform the view - probably at bootstrap or in a front-controller plugin - of the prefix/path mapping:
$view->addHelperPath(APPLICATON_PATH . '/../library/MyLibrary/View/Helper', 'MyLibrary_View_Helper_');
Note that in all cases above, the invocation of the view-helper functionality itself - say, inside a view-script - is:
<?php echo $this->myhelper($params) ?>
Note, in particular, the casing difference between the classname and the invocation.

Zend Framework Controller to Module routing

So i have been doing my best trying to absorb as much as i can about the Zend Framework which is pretty new to me, i'm about two weeks in since my first attempts and being doing well so far.
However i have run into a small issue i just can't figure out.
So here's the deal, i have a standard Zend Framework project with a number of modules in it. Like this :
- Project
- - Application
- - - configs
- - - controllers
- - - - IndexController
- - - - WMSController
- - - forms
- - - layouts
- - - models
- - - modules
- - - - content
- - - - - controllers
- - - - - - IndexController
- - - - - models
- - - - - views
- - - - - Bootstrap
- - - views
- - - bootstrap
- - public
etc..
Now i have a simple test link set in the view for the WMSController wich is supposed to direct someone klicking it to the IndexController of the content module.
test link to content module
Now as you can probably see this link is NOT going to work since it is pointing towards localhost/wms/content which would be the content action in the WMSController which doesn't exist at this moment.
Now what i want to do is to make the wms/content actually point towards the IndexController of the content module. Why? Well i simply do not want a user to type localhost/content to get to the content module which is part of the WMS. I want to force them to get trough the WMS controller first.
I have read numerous things about routing being the solution using the bootstrap or the autoloader but pretty much all of them simply help you with pointing a certain url to a specific action in a specific controller.
What i want is a url to point to a specific action in a specific controller in a specific module.
NOTE: All the other controllers and views are still the default generated versions with no changes made to them yet!
If anyone could show me a code example of how this is done it would be much appreciated!
If I understand correctly you simply want /wms/content to point to module content controller Index action index. This is a case where a simple router will work(at least until you want to get more complex)
In your application.ini add these lines:
resources.router.routes.content.route = "wms/content"
resources.router.routes.content.defaults.module = "content"
resources.router.routes.content.defaults.controller = "index"
resources.router.routes.content.defaults.action = "index"
this is the easiest way to build a custom route.
*Note:*The 4th parameter from the left is the name of the route, so if you use it with a method that allows using route names (the url() helper for example) you can just use the route name. $this->url(array(), 'content');
This is how you would use a named route, personally I would probably consider renaming my module wms (if possible and practical) and just redirecting there from the default Index controller. Because once you start with named and custom routes it's hard to quit...
From your question that you
want to force them to get trough the WMS controller first
You can do one thing. Whatever you want to do in WMSController whenever a user types localhost/content/** you can put it in the parent class for ALL THE CONTROLLERS IN MODULE: 'CONTENT'. This way you can check for something/ perform operations everytime a request comes to this controller (no matter if the user wanted to go to the other module.)
class Content_AnyController extends MyControllers_Controller_Action_Admin{
....
}
where
class Reviewmo_Controller_Action extends Zend_Controller_Action{
public function init(){
//Things you want to do each time
}
}
This is what I think you want to achieve because if you want to just simply redirect to WMSController's ContentAction you can simply redirect to that controller.

Fastest and easiest way to change controllers' module

I am developing my first Zend website, and I just finished the Back-office. The problem is that I did not create any module, but now that I have to develop the Front-office I would like to create a different module.
Knowing that I already have about 20 controllers for my back-office, how could I easily change their module to "Administration" ?
Then I would place the front office in a "Public" module and the main engines will be left in the "Default" module.
Thanks for your help !
I assume you use Zend_Application.
Enable modules in your application.ini:
resources.modules =
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.controllerDirectory.default = APPLICATION_PATH "/controllers"
Create a new file hierarchie for your new "Public" module:
library
public
application
- controllers // class UserController extends Zend_Controller_Action
- views
- modules
- frontend
- controllers // class Frontend_UserController extends Zend_Controller_Action
- views
Back-office:
http://server.tld/user/add
Frontend / Public:
http://server.tld/frontend/user/list

Zend Action helper

I am learning how to use Zend framework and realise that the action helper is something that would be useful.
I have set up a default installation of Zend on my machine, but I dont know where the helper file needs to go, what I need to put in the bootstrap file and how I use it. Can anyone point me in the right direction please - the ZF user guide is not to clear to me.
Thanks
John
Two thoughts for where to place your custom action-helpers:
In a separate, custom library
In the folder application/controllers/helpers
These ideas are not exclusive. Functionality that is general enough to work in multiple projects should probably be pulled into a separate library. But for functionality that is application-specific, there is an argument that it could be somewhere in the application folder.
#Jurian has already described the "separate-library" approach. For app-specific helpers, you can do as follows:
For a helper called myHelper, create a class Application_Controller_Helper_MyHelper in the file application/controllers/helpers/MyHelper.php. In Bootstrap, you have something like:
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Application',
'basePath' => APPLICATION_PATH,
));
Zend_Controller_Action_HelperBroker::addPath(
APPLICATION_PATH . '/controllers/helpers',
'Application_Controller_Helper_');
return $autoloader;
}
Then your helper can be invoked in a controller by using:
$this->_helper->myHelper;
As you can see, this presumes you are using appNamespace 'Application'. If not, you can (must!) modify your class names to accommodate your circumstance.
Cheers!
You can place action helpers in your own library. Besides library/Zend where all the Zend stuff is around, you can create a library/MyLibrary folder (MyLibrary is arbitrary chosen) and put the action helpers there.
A good place is the library/MyLibrary/Controller/Action/Helper folder you need to create and place your action helper there (i.e. Navigation.php). In this file, create the class MyLibrary_Controller_Action_Helper_Navigation.
The next step is to add the action helper to the HelperBroker of the Zend Framework during bootstrap. Therefore, create a new method in your Bootstrap.php file and add this function:
protected function _initActionHelpers ()
{
Zend_Controller_Action_HelperBroker::addHelper(
new MyLibrary_Controller_Action_Helper_Navigation()
);
}
One last remark is you need to configure the use of this library by adding this rule to your application.ini:
autoLoaderNameSpaces[] = "MyLibrary_"
You can do this through your application.ini file like so
resources.view[] =
resources.view.helperPath.Default_View_Helper_ = APPLICATION_PATH "/views/helpers/"
Then in your views/helpers path you can create a file like Time.php. This file would contain the following code:
<?php
class Default_View_Helper_Time extends Zend_View_Helper_Abstract
{
public function time()
{
$date = new Zend_Date();
return $date->get(Zend_Date::TIME_MEDIUM);
}
}
?>
To use this in your view scripts you would use
<?=$this->time()?>
Which would display the current time using your new View_Helper
You can avoid having to register your action helper namespace and path within the Bootstrap.php by declaring them in the application.ini instead like so:
resources.frontController.actionHelperPaths.My_Controller_Action_Helper = APPLICATION_PATH "/controllers/helpers"
Simply replace My_Controller_Action_Helper with your desired namespace, and modify the helpers directory path accordingly.
The helper can be initialized the same way:
$this->_helper->myHelper;
As mentioned by the docs, registering the prefix or path of the helpers is usually preferred because helpers would not be initialized until they are called like in the snippet above.
Of course, instantiating and passing helpers to the broker is a bit
time and resource intensive, so two methods exists to automate things
slightly: addPrefix() and addPath().
http://framework.zend.com/manual/1.12/en/zend.loader.pluginloader.html
Adding the config entry to the application.ini follows the same suggested pattern.