This question is about CodeIgniter 3.1.9
I override the CI_Controller with MY_Controller according to this page.
I wonder if I can create a variable in the constructor of MY_Controller that would be accessible everywhere else in the project (Controllers, Models, Views, Libraries ...)
Sessions will do the job but will not be the best options, since variables will be keep from one page to another.
the best way is make your library to deal with thing and it can be access by: $this->your_library
take look here
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.
Is it correct to require_once?
where and how would you put it include path?
Should it not be in a application.ini or bootstrap?
EXAMPLE:
require_once 'Zend/View/Helper/Abstract.php';
// #question - is this correct - where and
// how would you put it include path
class Zend_View_Helper_Translate extends Zend_View_Helper_Abstract
{
}
Generally speaking, you can avoid require_once calls almost entirely by appropriately using Zend_Loader_Autoloader. Of course, the key is "appropriate".
Typically, your public/index.php sets the include_path to be the library folder. Then, if you are using Zend_Application, the Zend_Loader_Autoloader is registered to find any PSR-0 compliant classes whose namespace prefixes have been registered using the autoloadernamespaces array in application/configs/application.ini.
The tricky part is for classes defined in files that don't "reside on the include_path", like models that appear in application/models, services that reside in application/services, etc. Even though the classes defined there tend to follow PSR-0 standards, the fact that the PSR-0 mapping occurs relative to a base off the include-path means that the system has to know the mapping between classname prefixes and base paths. This is where resource autoloaders come in. These resource autoloaders are typically set up automatically in the application Bootstrap extending Zend_Application_Bootstrap_Bootstrap and module bootstraps that extend Zend_Application_Module_Bootstrap.
View helpers are another example of classes that reside "off the include_path", perhaps in something like application/views/helpers. Since these are typically invoked in a view script using a short form $this->someHelper($someParam), the system must be told how to generate the fully qualified classname from this short name. This is accomplished using $view->addPrefixPath() which maps namespace prefixes to filesystem locations. Again, the app-level and module level bootstrapping mechanism sets most of these up for you.
For libraries/classes that do not follow PSR-0 standards, you can create custom autoloaders and attach them (typically at Bootstrap) to the Zend_Loader_Autoloader singleton. This is the only place where you would have an explicit include/require.
tl;dr: With proper use of the existing ZF autoloader mechanism, you almost never need to have include/require statements in your own application code.
It is not correct in this case.
First off, please use Zend Tool. It will create the files you don't know how to create yourself. It will create the correct class names, extend them appropriately and require_once anything that might be needed.
Do not place require_once in the bootstrap. You want it to execute only when needed, not with every request.
As for the example you've provided, the correct version would be:
require_once "Zend/View/Interface.php";
class Zend_View_Helper_Foo extends Zend_View_Helper_Abstract {
}
The class that is extended by the helper is autoloaded and putting it in require_once does nothing.
In Play! 2.0, one can use Global as documented here. Global needs to be in the default (empty) package.
I also need globals in my application, and some of them need to be available to the methods in Global. Thus, I put them in Global.scala like so:
package object globals {
lazy val foo = Play.maybeApplication.flatMap(_.configuration.getString("foo")).getOrElse("default_value_of_foo")
}
And then I use it in my controllers like this:
globals.foo
Is there a better way?
I think this question is more about general software design than it is about Play Framework. If you truly need a bunch of random properties why not create your own object?
object Configuration {
val timeout = Play.maybeApplication.flatMap(
_.configuration.getString("timeout")
).getOrElse(0))
}
But usually the values belong to some other logical entity that is being configured.
I had problems using Global as a singleton for my app. I think you will have some problems too to access the singleton from your controllers (see this post).
But you can create your own singleton in one of your packages and access it as you plan to do.
I'm looking for best way of using session within zf application.
At first I did something like this - in init method of controller superclass I initialized session:
class Vovkin_Controller_Action extends Zend_Controller_Action
{
protected $_session;
public function init()
{
// here I define namespace
// ...
$this->_session = new Zend_Session_Namespace($nameSpace);
parent::init();
}
...
}
after that session in controller was used in this way:
public function someAction()
{
$this->_session->user = $user;
}
but I found this approach not very handy for other parts of system, like plugins, services, etc, because there I had to init session in other way, but I want keep it in one place if it's possible. So I decided to change it to this approach https://stackoverflow.com/a/2506447.
Now I have a few action helpers to provide access for sessions with different namespaces, it works like this:
public function someAction()
{
$this->_helper->session()->user = $user;
}
and so far it looks useful, because I can get access to session namespaces in other parts of system, for example in services, in this way:
class Vovkin_Model_Service_UserLoginService
{
public function login()
{
$session = Zend_Controller_Action_HelperBroker::getStaticHelper('session')->direct();
...
}
....
}
but how much it's correct to use it in this way, from point of architecture and used resources?
Thanks.
The answer you have refereed to is from Rob Allen, one of the main contributors of Zend Framework, so it's right to some extent. You can go with the action helpers on controllers without any problems.
But outside it, it's completely wrong. Services doesn't has nothing with action helpers and the front controller. You can't put a dependency on it (services to action helpers).
So, as the application bootstrap works as a container for initializing the application, it's reasonable to get the necessary values from there. The first thing I would suggest you is to use Zend_Registry. But as far as I cal tell you, it would be the same initializing the session object again, since it will not be wiped, it's just an object referencing the native $_SESSION superglobals. So, simply call
new Zend_Session_Namespace($nameSpace).
But again, this is wrong. You should not let your services know how sessions are handled (thus creating the objects inside it):
$session = Zend_Controller_Action_HelperBroker::getStaticHelper('session')->direct()
or even
$session = Zend_Registry('userSession')
or
$session = new Zend_Session_Namespace('userSession')
With that you are also not using the bootstrap container at all. Instead you should provide a common interface to deal with sessions (it could be $_SESSION or even a database) and inject it into the service as a parameter (e.g. __construct($session)). But that's a whole new subject (Dependency Injection).
So, you have two options considering the current state of the ZendFramework 1.11 (that's already old and full of bad practices):
1) You'll use services through controllers:
So you will get the session through the action helper and then pass it as a parameter to your service.
new Vovkin_Model_Service_UserLoginService($session)
2) You will use services independently of controllers and will get the dependencies through the bootstrap container:
Well, the worst thing is that to get the bootstrap you need to have a frontController dependency.
$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
So, avoid it, and go with the first option, injecting the dependency instead. Although, if you really want it in that way, access it directly:
$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$bootstrap->get('userSession')
Sadly, in the end, it's everything wrong. But it's the best you can do with ZF 1. You should look forward to ZF 2 and Symfony 2 to better understand these concepts.
Here it's a good explanation: http://symfony.com/doc/current/book/service_container.html
(I know that you're using ZF, but it doesn't matter, the concept is the key)
I have 2 databases that my site uses including a central user database that relates to other site-specific databases.
Sometimes it is adequate to call new User(array('db'=>'adapter1')); (but never convenient); other times, though, such as when declaring relationships between tables on different databases, there is no way to do this.
Does anyone know a way to specify which database adapter to use from within the Zend_Db_Table_Abstract class?
Thanks!
Getting back to this pretty late, but none of the answers here quite did it for me. A select few of my database models needed to use 'tdb' and the following code was added to each of those classes to have that happen automatically:
protected function _setupDatabaseAdapter()
{
$this->_db = Zend_Registry::get('tdb');
parent::_setupDatabaseAdapter();
}
I thank you all for your suggestions along the way!
Zend_Db_Table_Abstract provides a static method to set the default database adapter. Do this as follows:
Zend_Db_Table_Abstract::setDefaultAdapter($adapter);
Now, all your Table objects will use your adapter by default.
Note: the online docs sometimes don't make this obvious, so your second best place to check is in the API here: http://framework.zend.com/apidoc/core/
You could set the class variable $_db to the correct adapter in the constructor.
global $adapter1; //There are better ways than using a global variable
$this->_db = $adapter1;
Assuming the adapter object can be referenced in the constructor. That doesn't seem to portable, but I believe it would work.
The init function can be used, it is not used in Zend_Db_Adapter_Abstract, can be used in your class to setup whatever needs to be done. _setAdapter accepts a string naming a Registry Key.
public function init()
{
$this->_setAdapter('tdb');
}