question related to app_controller - php

I am trying to include a small code in each page of my site.
Is there any way to do this without modifying each controller?
For example - I want to read/unread message from Message model.
Can i do this using the app_controller? I have add following function in app_controller.php.
I need suggestion. Please help me.
function messageStatus() {
App::import('Model','Message');
$new_message = $this->Message->find(
'first',
array (
'conditions' => array (
'Message.status' => '1'
)
)
);
$this->set("new_message",$new_message);
}

Depending on when you want to execute your actions, you will have to override in the app_controller.php file one of the following functions (according to the documentation), :
beforeFilter()
afterFilter()
beforeRender()
Since all your other controllers will be inheriting the methods of this class, your actions will be executed every time (as specified in the docs) one of your controllers are executed.
If you want to have a controller that does not run the code in the app_controller simply override the method again locally.

As user559744 mentioned you can use AppController within your application to create attributes and methods that can be accessed by your controllers. AppController is the parent class of your controllers.
You should copy app_controller.php from /cake/libs/controller/ to YOURAPP/app_controller.php to avoid making changes to the core files.
http://book.cakephp.org/view/957/The-App-Controller

Related

Run an init function in codeigniter

So I have my codeigniter setup in which I have a whole bunch of autoloaded helpers, libraries etc. I have a function written which I want to execute before the application bootstraps. Lets call the function init() and assume its defined in one of the helpers. Problem is that it uses functions from other autoloaded helpers and libraries etc so calling the init() in the autoloaded file itself does not help because it runs into 'call to undefined function X' etc..
So I want to make the init() call after everything has loaded..I cannot call it in the default controller, because users might have a different URL bookmarked.
What is the best way to call init() in this case?
Add a hook in application/config/hooks.php
$hook['pre_controller'] = function()
{
// ...
};
You may use a function declared in another file, for example:
$hook['pre_controller'] = array(
// ...
'function' => 'init'
);
There are many hooks available but in your case, the 'pre_controller' hook seems appropriate to me because pre_controller called immediately prior to any of your controllers being called. All base classes, routing, and security checks have been done.

OpenCart add products in custom php script

I want to add products via my script which is not connected with OpenCart.
For example: somedir/index.php. I try to do it in this way:
$productData = array(
'model' => 'ABC123',
'name'=>'aaa',
'description'=>'aaa',
'tag'=>'aaa',
...
);
require_once ('../../system/engine/model.php');
require_once ('../../admin/model/catalog/product.php');
$a= new ModelCatalogProduct();
$a->addProduct($productData);
But there are many functions that need to be triggered. How can this be achieved?
OpenCart uses a so called MVC-pattern. This patteren works within OpenCart in a very specialised and deeply coupled way, so you need the context of the routing system in case you would like to use controllers and models in your code.
Also, it really depends on which version you use, what semantics would be right, so that is hard to tell. Conceptually, you would do something like this:
- define a new contoller in the /admin/controller directory structure, i.e. /admin/controller/tool/product_import.php
Call that controller ControllerToolProductImport which extends Controller;
Create a public function index()
Have it load the model like $this->load->model("catalog/product");
Now the model function becomes available and you would use it like $this->model_catalog_product->addProduct($productData);
This public function index can be triggerd by https://hostname:port/admin/index.php?route=too/product_import&token=ABC (you'll see what the token should be, once logged in into the admin section). To trigger another function within that controller directly (it needs to be public), you could extend the route easily. So for public function doSomething() it would become https://hostname:port/admin/index.php?route=too/product_import/doSomething&token=ABC.
When triggering this function from within the admin section, you would use the OpenCart functions to do so. Depending on your version, this would go like this for 2.2.0.0:
$this->url->link('tool/product_import', 'token=' . $this->session->data['token'], true)

How to call a zend controller action from an independent php file?

I am having a controller IndexController.php in which action is something like this
class IndexController extends CustomControllerAction {
public function preDispatch() {
if (!$this->view->authenticated) {
$this->_redirect('/users/login');
}
}
public function indexemailAction() {
//somecode which calculates certain things
}
}
NOw,I need to call the action "indexmailAction" inside the IndexController.php with an independent php file
The php file is indextest.php
<?php
//Need to write some code to call indexmailAction in IndexController.php
?>
What should I write in this file ......
Thanks in advance
I know this is a few years old, and this may not be the intended use of the classes/functions, but I've found the following quite useful in isolated files that are called from the command line.
The problem this solves for me is that it eliminates spawning of Apache processes. The solution is great because I can access the some Controller/Action needed that I would from the URL.
In almost any ZF1 based app, you can copy your index file and keep everything the same and just comment out the following line.
$application->run();
Anything below this line you can access with your autoloaders etc. It's crude, but it works. Unfortunately, you'll soon find yourself with limited access to a lot of the files your application has, and the feeling the only way you can access the files needed is through a Controller/Action.
Instead, I use the following in a new file below $application->bootstrap() ( still removing the $application->run() ):
$front = Zend_Controller_Front::getInstance();
// You can put more here if you use non-default modules
$front->setControllerDirectory(array(
'default' => APPLICATION_PATH.'/controllers'
));
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setNeverRender(true);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
$req = new Zend_Controller_Request_Http("http://anydomain.tld/controller/action");
// Example just to see how this can be extended
$req->setParam("someVar", "someValue");
$front->setRequest($req);
$front->dispatch();
In the end you have a isolated PHP file that bootstraps everything the same as your main index.php for the web, but you can manually trigger a controller/action as needed, giving you easier access to the rest of the files with how ZF1 intended you to access them.
Controllers are designed to be used in an MVC, not by scripts. Your controller should assemble request variables, direct them to models and return an HTTP response of some sort. Your scripts should act directly on the models instead.
Anyhow, if you insist, you can instantiate a controller class and call methods just like any other class as long as you inject any dependencies that the MVC would have.
If you want logic used in multiple places in your actions, then it should go in an action helper or if very generic code, then in a custom library (/library/custom/)
NB: The authentication would be better suited in a plugin rather than the pre-dispatch method in every controller.
You should not have to call a controller action for this, your logic should reside in your models. Then you can create a new instance of your model and invoke the appropriate methods. example :
require_once '/path/to/mymodel.php';
$mymodel = new Mymodel();
$data = $mymodele->fetchAll();
PS: Maybe you should think of creating a restful api to handle calls from outside your application
UPDATE:
ok, I see now what you need, The best way to achieve it is to call a url instead of a file (e.g. website.com/emails/send), if you are worried about security you can use some preshared key to make sure the request comes from you, send it with the request and check if it's correct in your action.

Simple way to pass object properties to next

This might be a bit hard to comprehend so I apologize in advance if this is not clear enough.
I'm writing my own MVC framework and am once again stuck.
I am in the process of writing the controller classes for the framework. Basically this is how it works:
Instantiate class coreController which extends abstract class
coreController sets controller to be loaded by interpreting query string
query string values stored in variables
other variables assigned values
new controller is loaded
new controller checks if an action object needs to be instantiated.
new actioncontroller is loaded
action controller checks if it is the final object required.
action controller is returned as an object to be referenced during the rest of the script.
generic $controller->method() can be called and references final controller loaded.
Another overview:
coreController
pageController
pageControllerActionAdd
return as object to start
$controller->something(); //References pageControllerActionAdd
Esentially what I want to be able to do is be able enter a url like:
http://www.mywebsite.com/page/modify/
and have the script pull up the PageModifyController as a variable so I can execute it's methods.
If you can tell me a better method for what I am doing please go ahead. You don't have to write any code, just the idea would be great. It is just that the way I am currently doing is very confusing and hard to debug. I will end up with multiple nested objects and I don't like the concept of that.
I've been reading a lot of other source code and found that it too can be quite sophisticated.
I actually created a framework that works along the lines you are trying to implement. I think what you are missing is a RoutingHandler class. Routing is the physical manipulation of the URL, which tells your application which Controller to load, and which Action to run.
In my world I also have Modules, so the basic routing scheme is
Module -> Controller -> Action
These three items map to my URI scheme in that fashion. Variables can be appended also like so...
http://www.domain.com/module/controller/action/var1/val1/var2/val2
So, what happens after the URI is parsed, and control is passed over to the appropriate controller and action? Let's make some code up to demonstrate a simple example...
<?php
class indexController extends Controller {
protected function Initialize() {
$this->objHomeModel = new HomeModel;
$this->objHeader = new Header();
$this->objFooter = new Footer();
$this->objHeader
->SetPageId('home');
}
public function indexAction() {
$this->objHeader->SetPageTitle('This is my page title.');
}
// other actions and/or helper methods...
}
?>
In the Initialize method, I'm setting some controller-wide stuff, and grabbing an instance of my Model to use later. The real meat is in the indexAction method. This is where you would set up stuff to use in your View. For example...
public function randomAction() {
$this->_CONTROL->Append($intSomeVar, 42);
}
_CONTROL is an array of values that I manipulate and pass onto the View. The Controller class knows how to find the right template for the View because it is named after the Action (and in a sibling directory).
The Controller parent class takes the name of the action method and parses it like so...
indexAction -> index.tpl.php
You can also do some other fun stuff here, for example...
Application::SetNoRender();
...would tell the Controller not to render inside a template, but just complete the method. This is useful for those situations where you don't actually want to output anything.
Lastly, all of the controllers, models, and views live inside their own Module directory like so...
my_module
controllers
indexController.class.php
someotherController.class.php
:
:
models
HomeModel.class.php
:
:
templates
index.tpl.php
someother.tpl.php
:
:
I can have as many Modules as I need, which means I can separate functionality out by Module and/or Controller.
I could go on, but I'm writing this from memory, and there are some wrinkles here and there, but hopefully this gives you food for thought.

adding new library in CodeIgniter

I've just started learning CodeIgniter, and I'm following this authentication tutorial by nettuts+. I did not understand one thing in it:
He added the following constructor code in the Welcome controller, which basically can be accessed only if the Session has variable username, otherwise it will redirect to admin controller.
function __construct()
{
session_start();
parent::__construct();
if ( !isset($_SESSION['username'])){
redirect('admin');
}
}
He said:
If you have multiple controllers, then
instead of adding the above code in
every controller, you should Create a
new library, which extends the
controller you will paste the code in,
and autoload the library into
project. That way this code runs
always when a controller is loaded.
Does it mean, I should
Create a file in application/libraries (eg. auth.php)
Paste this code in the auth.php
.
if ( !isset($_SESSION['username'])){
redirect('admin');
}
Now how to autoload this library and make it run every time a controller is loaded as he said?
Thanks
1) to autoload a library, just add it to the array in the file application/config/autoload.php, look for the 'library' section and paste the name of the library(without extension) there, as an element of the array.
$autoload['libraries'] = array ('auth');
2) I suggest you use the native session handler (session library), which works pretty well and avoids you to use php $_SESSION. You set a width $this->session->set_userdata(array('username' => 'User1', 'logged' => 'true'), and then you retrieve the values with $this->session->userdata['logged'], for ex.
Works like a charm and don't have to call session_start() and so on. Go check the help because it's really really clear on that.
3) As for your problem, I'll go, instead, for 'hooks'. There are different hooks, depending on their 'position', i.e. the moment in which you're calling them.
You can use, for ex.. the 'post_controller_constructor', which is called after controller initialization but BEFORE the methods, so it's in a midway between the constructor and the actual method. I usually insert this controls here.
You define hooks in application/config/hooks.php, and give them an array:
$hook['post_controller_constructor'] = array(
'class' => 'Auth',
'function' => 'check',
'filename' => 'auth.php',
filepath' => 'hooks',
'params' => array()
);
Anyway, for all these needs, the docs are pretty clear and straightforward, I suggest you read about hooks and session and you'll see everything gets much clearer!
The other way to do this. This is what he means in tutorial.
Create a library called MY_Controller in your application/libraries folder and extend it from CI_Controller:
Class MY_Controller extends CI_Controller {
public function __construct()
{
parent::__construct();
// do the stuff you want to execute on every page.
// like auth.
}
}
Autoload the auth class in autoload.php config file. There is no need to autoload MY_Controller CodeIgniter will automaticly recognise it and run it. You can also load the Auth library within MY_Controller
Extend your controllers with MY_Controller class. (Not CI_Controller)
Extending your controller will give to more control of your project. You can add extra methods to use everywhere on your project.
For more information about extending native libraries of CodeIgniter check Creating Libraries: CodeIgniter.
Add the new library to the autoload library array in config/autoload.php.
$autoload['libraries'] = array ('database', 'session', 'auth');
Then when you want to call the function in controller constructors use $this->auth->function_name();.
You may want to make it a hook if there's a lot of repeat functionality that you don't want to call in every single constructor.

Categories