from what i know there is only action helper & view helper available at zend framework.
is there any model helper?
or how we can implement the model helper?
There's nothing in ZF actually called a Model helper - but if your model is accessing a database table you might want to create it as a class which extends Zend_Db_Table_Abstract. See examples in the ZF manual: http://framework.zend.com/manual/en/zend.db.table.html
In Zend Framework there is nothing defined for the models helpers like there is for the views helpers, however you can work around it and still preserve the application design (avoid using the library folder).
The way I do it is by adding a Helper folder inside the models one. Then you have to name your class like this:
class Application_Model_Helper_DateHelper
{
...
}
Then the autoloader will take care of finding it and loading it.
Unfortunately this naming is a little different from how you do it in the views folder. In the views folder you can create a folder named helpers and use a naming convention like:
class Zend_View_Helper_DarkBlueMenu extends Zend_View_Helper_Abstract
{
...
}
However, if you name the folder inside models as helpers then the classes inside it have to be named like this:
class Application_Model_helpers_DateHelper
{
...
}
First I add this line in my configuration file ie. application.ini:
includePaths.library = APPLICATION_PATH "/../library"
Then I add a class
class App_Model_Helper {
public static function resultAggregation($results) {}
//.... all the helper you need
}
in a file placed in ..library\App\Model\Helper.php
This is the only way I found to factor the code I use in the model.
The helper method can then be called from the model:
App_Model_Helper::resultAggregation($results);
I am aware this breaks the OOD, so if any one has a better and cleaner solution I would greatly appreciate.
Related
I know there are view controllers and action controllers. I think that view helpers can be used from views and action helpers used from actions in controllers.
I need a class that at bootstrap or wherever, it initializes a number of configuration options, arrays for things like convert month numbers to their names and role numbers to their names.
How can this be achieved?
Put them in a model and use it anywhere you like by instantiating it and calling its helper methods. All model files are auto loaded whenever you call them.
Have a model Constants.php:
<?php
class Constants {
public static function convertMonth($month) {
doLogic();
return $something;
}
}
?>
In your controller or view:
Constants::convertMonth(12);
You could build a Resource Plugin and then add it to yout bootstrap class.
The Constants class or Resource approaches both work nicely. However, I recently had to undo/upgrade a Constants class based solution to meet new requirements, so you might want to consider your future plans before going down those paths.
Specifically, if you ever intend to support multiple languages, or even different words for the constants in different contexts, check out Zend_Translate API docs, Zend_Translate example, or this blog post.
I'm using native session library to replace the built in session library in CI. I need to extend the class but when I drop in MY_Session.php, CI reverts back to the old /system/libraries/Session.php.
How to I extend a class that's replaced a core CI class like Session.php?
Simply by naming your class files identically to a native library will
cause CodeIgniter to use it instead of the native one. To use this
feature you must name the file and the class declaration exactly the
same as the native library. For example, to replace the native Email
library you'll create a file named application/libraries/Email.php
-user guide
then call it
class MY_Email extends CI_Email {
public function __construct()
{
parent::__construct();
}
}
Loading Your Sub-class:
$this->load->library('email');
EDIT
Try this:
Just load your new library (the one doing the extending):
Then, let's say we have Session.php and Mysession.php
<?php
load_class('session', false);
class Mysession extends Session {
//your code
}
You don't need the MY_ name tag still, I think you want to reserve that for it's original intended purpose to avoid confusion.
.. else just use an include() or require() :P
How can I eliminate to write $object = new Application_Model_Database() in every controller?
For example for an article controller, I have to type $articles = new Application_Model_Articles() for every controller. Should I put it under viewer controller, action helpers, or any other way?
Your question almost sounds like an OOP best practices question as opposed to a Zend Framework specific question. Regardless of whether or not I'm using a framework, and regardless of what framework I choose, I base when and where I create new objects on testability how many times I have to write $object = new My_Random_Object();.
Speaking specifically to the Zend Framework: Objects I'm going to use everywhere, or almost everywhere, get created in Bootstrap.php. These objects generally include a database adapter, logger, view object, and any plugins I might use. To access these across the application, I'll create private properties in the appropriate controllers and assign the objects to those properties in the controller's init() method.
class ExampleController extends Zend_Controller_Action
{
public function init()
{
$bootstrap = $this->getInvokeArg('bootstrap');
$this->_db = $bootstrap->getResource('db');
$this->_log = $bootstrap->getResource('log');
// and so on, and so forth
}
}
Ideally, models, services, daos, etc, will all be relatively tightly grouped by controller and by action. In my experience, and this is speaking generally, if I have the same model or service class showing up across all of the controllers in my application, I have an organization problem. That being said, any model that shows up in only one action gets created in that action. If it's across actions in a controller, it gets created in the init() method and assigned to a property. If it shows up across multiple controllers, it gets created in my Bootstrap.php.
(Ideally, everything gets created in the Bootstrap.php, so you can swap out that bootstrap for testing purposes. Sadly, I don't always do that, and I most often use the principles I outlined above.)
Well do you really need it in every controllers? Because that's pretty much by design. You implement models when you need them. Its not that much code really.
Now if its to be used across actions from a controller you could always:
class MyController extends Zend_Controllers{
$protected $_articleModel;
...
and in your constructor or __init() function initialize it so you can use it in every action thru $this->_articleModel
If you REALLY want it everywhere in your application just initialize it in your bootstrap and store it in the registry.
public function __initModels(){
$articles = new Application_Model_Articles()
Zend_Registry::set('articles', $articles );
}
And access it in your controllers like so:
Zend_Registry::get('articles')->fetchAll();
But then your still writing a couple of characters.
Hope this help!
IF you want to use models in the controllers you must call it..anyway some shortcuts are here
1.You can initialize it in the init section of your controller like
public function init(){
$this->object = new Application_Model_Database();
}
So that the this->object is available in all the actions of that particular controller
2.Use Zend_registry as suggested in the above answer
Another possibility is to use a Dependency Injection container, such as the Symfony DI component. It takes care of instantiating your objects, and you get some additional benefits:
Separation of concerns. You have a component devoted to create your object tree.
Easier testability of the objects.
Last, but not least, the performance benefits given by lazy instantiation (objects are created only when you ask for them). Thus, if some object is not used by the particular controller serving your request, it's not instantiated).
It's a bit more laborious than the above solutions, but much more flexible if you need to maintain and extend your application in the future.
Hope that helps,
If you are using this object to just display data in your view and are using your controller to grab the data and assign it to your view, like so:
//someControllerAction
$object = new Application_Model_Articles();
$object->fetchAll();
//assign to view
$this->view->articles = $object;
You might be better off making a view helper similar to:
//Articles.php put in /application/views/helpers
class Zend_View_Helper_Articles extends Zend_View_Helper_Abstract {
public function Articles() {
$articles = new Application_Model_Articles();
$articles->fetchAll();
//return rowset object
return $articles;
Then in your view (phtml) you could do something like:
//someView.phmtl
<?php $articles = $this->Articles(); ?>
<h1><?php echo $this->escape($articles->title); ?></h1>
<p><?php echo $this->escape($articles->body); ?></p>
building a view helper allows you to bypass the controller completely if you just need to display data from the model. This is a very simple example and can be used with partials and partialLoops.
REF:ZF reference Custom View Helper
ZF partial view helper reference
I am new on Zend framework and using first time it. I am looking for simple basic tutorials which I can read in very short time. I also stuck on if I want to add new class in Zend library. And it should also auto load when I make any new controller.
Please give your opinions if you have.
Regards,
This helped me At the beginning:
http://www.zendcasts.com/
http://devzone.zend.com/search/results?q=autoload (just search)
As autoload your class, This is the my way:
Create folder 'My' into library/
in it create folder 'Utils' and in Utils file 'Utils.php' so the path is library/My/Utils/Utils.php
For this path You must call class: class My_Utils_Utils{ ... }
and in configs/application.ini Put
appnamespace = "Application"
autoloaderNamespaces.my = "My_"
Then you can use namespace My_ and class My_Utils_Utils
In controller: $test = new My_Utils_Utils();
I am looking for simple basic tutorials
Here are a few tutorials I found while googling:
Official quickstart tutorial
A great book by frequent ZF-contributer PadrĂ¡ic Brady: Survive the deep end!
http://akrabat.com/zend-framework-tutorial/
Page with different tutorials: ZFTutorials.com
I also stuck on if I want to add new class in Zend library
You should not add new classes to the library per se, but instead create your own library or add classes in the "models"-folder/folders (if you use the modular project layout). Autoloading is achieved by utilizing Zend_Loader_Autoloader and its subclasses. As long as you follow the PEAR convention, i.e. if you have a class MyLib_Database_Table, then it should be inside the folder MyLib/Database, and the filename should be Table.php. (also make sure that the parent folder of MyLib is on the project include path.
To autoload simply use new MyLib_Database_Table, and the autoloader will load the class behind the scenes if necessary. Since 1.10 (I think), the autoloader also fully support PHP 5.3 namespaces. I.e:
// Filepath: lib\MyLib\Database\Table.php
namespace MyLib\Database;
class Table {
}
will work with the same folder structure. Code example:
use MyLib\Database\Table;
class IndexController extends Zend_Controller_Action
{
public function indexAction ()
{
$myTable = new Table();
}
}
auto load when I make any new controller
I'm not quite sure what you mean here. ZF does not have any dependency injection setup per default. But you can instantiate your classes without requiring them first if that's what you mean.
I'm creating a plugin for my symfony project, which includes a base action class, i.e.:
<?php
// myActions.class.php
class myActions extends sfActions {
/* ... */
}
Where in my plugin folder (e.g.: plugins/sfMyPlugin/???) should I place this file?
The goal is to have actions that are NOT a part of this plugin extend this class, hopefully having the class be autoloaded (similar to if it were placed under apps/my_app/lib). If it can't be autoloaded, how do I get symfony to include my php file?
You typically put it in your plugin's lib directory. The general conventions is also to to name with Base in the name so given your example that would be BasemyActions. Then you would also make an empty concrete class called myActions and you would extend that within your plugin thus allowing other user to complety replace myActions with their own implementation (so long as it extends the base class) or to simply extend myActions.
you can place it in the lib directory of your plugin. This is what the generate:plugin-module task of the sfTaskExtraPlugin does.