I have extension with some actions in my controller. How can I call one of these action in my scheduler task?
In file mwextension/Classes/Task/Task.php I want to call in "public function execute()" the "public function datenimportAction()" which is located "mwextension/Classes/Controller/MyController.php"
Thanks for help!
Martin
You are nearly there. Just instantiate all the extbasey stuff with ObjectManager->get.
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
\TYPO3\CMS\Extbase\Object\ObjectManager::class
);
$controller = $objectManager->get(
\xxx\ddd\Controller\xxxController::class
);
$controller->datenimportAction($settingsForAction);
Related
I need to add and operation to handle downloading of a file.
How can i create route, and add setupDownloadOperation in the right way?
Or must I simply do 'laravel-way' manually adding a route?
Actually we did this
First - Create a setupDownloadRoutes
Actually this is called automatically ad boot
protected function setupDownloadRoutes($segment, $routeName, $controller)
{
Route::get($segment. '/{id}/download', [
'as' => $routeName . '.download',
'uses' => $controller . '#download',
'operation' => 'download',
]);
}
Create the setupDownloadOperation function
It's automatically launched if found. If you have nothing to do here you can avoid to create it.
protected function setupDownloadOperation()
{
...do things here...
}
Create the download function.
This is the classic controller action of Laravel
protected function download()
{
... do thing as usually in a normal action ...
}
I do not find these procedure documented actually
The docs here cover exactly what you need. Just replace “moderate” with “download” in the naming - https://backpackforlaravel.com/docs/4.1/crud-operations
I have a controller called "SiteController". On it there is a normal indexAction which displays the frontpage. It's fairly easy to test this, but how would I test another function that is NOT an action with parameters. Let's say I have a function called "sendMail($to, $message)". How do I test that?
<?php
class ControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
public function testShowCallsServiceFind()
{
$this->dispatch('/index'); // dont care about this...
// what I need is a way to do this:
$res = $controller->sendMail("bla", "bla"); // so that I can test sendMail?
}
}
How can I test sendMail?
You dont actually need to call the dispatch method, you can new up a controller object and call methods directly:
$controller = new \My\Controller();
$actual_result = $controller->sendMail($params);
$this->assertEquals($expected_result, $actual_result);
Be careful though, you'll need to 'mock' your dependencies so you don't actually send a real email when you run your tests! http://phpunit.de/manual/3.0/en/mock-objects.html
I want to create different view scripts for each modules in my application. My structure look like that:
-- application
-- modules
-- default
-- views
-- default
-- scripts
-- fluid
--scripts
I set default script path in Zend Controller Plugin, which preDispatch() is executed with the request:
$view->setScriptPath(sprintf('%s/modules/%s/views/%s/scripts', APPLICATION_PATH, $module, $views));
Everything works great until i call action from view:
$this->action('activity-stream', 'index', 'observation');
Application throws an exception with message:
script 'index/activity-stream.phtml' not found in path (C:/wamp/www/erp/application/modules/observation/views\scripts/;C:\wamp\www\erp\application/modules/user/views/fluid/scripts/)
Looks like, when calling module with View Action Helper, script path is not set properly. Any idea how to achieve that?
Problem not solved, but i dit what i want in a different way. Each controller within any module of my application inherits my custom action controller that inherits Zend_Controller_Action. Inside that custom controller i have something like this:
public function init() {
parent::init();
$module = $this->_request->getModuleName();
$config = new Zend_Config_Ini(APPLICATION_PATH . "/configs/modules.ini", $module);
$layout = isset($config->layout) ? $config->layout : 'default';
$views = isset($config->views) ? $config->views : 'default';
$this->view->layout()->setLayout($layout);
$this->view->setScriptPath(sprintf('%s/modules/%s/views/%s/scripts', APPLICATION_PATH, $module, $views));
}
It's not exactly what i wanted, but solves my problem.
I need same 2 lines in all my controllers, each controller have its own init logic, but these two lines are common for all of them.
public function init()
{
$fm =$this->_helper->getHelper('FlashMessenger');
$this->view->messages = $fm->getMessages();
}
How can I avoid repeat code ?
Update:
Ok, the FlashMessenger was only an example, let's say I need write a log line in every action except for 'someAction' # 'someController'. So the new common lines should be.
$this->logger = new Zend_Log();
$writer = new Zend_Log_Writer_Stream(APPLICATION_PATH.'/../logs/log.txt');
$this->logger->addWriter($writer);
$this->logger->log('Some Message',Zend_Log::DEBUG);
The question is, where should I place these lines in order to avoid repeat them in all init() of each controller.
These lines should be placed at bootstrap?. If so: How can skip log lines for 'someAction'.
Or should I implement a 'BaseController' and make all my controller extend from it. If so: How can I Autoload it? (Fatal error: Class 'BaseController' not found) .
Just subclass the controller:
class Application_ControllerAction extends Zend_Controller_Action {
public function init()
{
$fm =$this->_helper->getHelper('FlashMessenger');
$this->view->messages = $fm->getMessages();
}
}
class IndexController extends Application_ControllerAction {
}
You may also achieve the same writing Controller Plugin.
Edit:
Front controller plugins are executed on each request, just like the Controllers and have the same hook methods:
routeStartup(): prior to routing the request
routeShutdown(): after routing the request
dispatchLoopStartup(): prior to entering the dispatch loop
preDispatch(): prior to dispatching an individual action
postDispatch(): after dispatching an individual action
dispatchLoopShutdown(): after completing the dispatch loop
I addition, you may check controller params to execute the code only on selected requests:
if ('admin' == $this->getRequest()->getModuleName()
&& 'update' == $this->getRequest()->getActionName() ) …
You can access your flash messages through (you dont need to send anything from your controller to your view, it's all automated)
$fm = new Zend_Controller_Action_Helper_FlashMessenger();
Zend_Debug::dump($fm->getMessages());
in you view, i would also recommand that you encapsulate this code in a view helper like it is shown on this site http://grummfy.be/blog/191
In your bootstrap:
protected function _initMyActionHelpers() {
$fm = new My_Controller_Action_Helper_FlashMessenger();
Zend_Controller_Action_HelperBroker::addHelper($fm);;
}
How can I avoid repeat code ?
Write your own custom controller, implement that in init method of that controller, and then extend all controllers in your app from your custom controller.
But approach with separate view helper as #Jeff mentioned (look at link) is often taken as a better solution.
In your controller do only:
$this->_helper->flashMessanger('My message');
and view helper will do the rest.
It's not the reason for creating new custom controller. Just add this line to all you init() methods.
$this->view->messages = $this->_helper->getHelper('FlashMessenger')->getMessages();
I have an action which is rendering some content via a layout.
I actually want to send this output in an email. What is the best way to achieve this in the Zend Framework?
I know I need to use the Zend_Mail component to send the email, but I'm unclear about how to attach the output of my action to Zend_Mail.
I've done some reading on the ContextSwitch action helper, and I think that might be appropriate, but I'm still not convinced.
I'm still new to Zend Framework. I'm used to using techniques like output buffering to capture output, which I don't think is the correct way to do this in Zend.
From your controller:
// do this if you're not using the default layout
$this->_helper->layout()->disableLayout();
$this->view->data = $items;
$htmlString = $this->view->render('foo/bar.phtml');
If you're doing this from a class that's not an instance of Zend_Controller_Action, you may have to create an instance of a Zend_view first, to do this:
$view = new Zend_view();
// you have to explicitly define the path to the template you're using
$view->setScriptPath(array($pathToTemplate));
$view->data = $data;
$htmlString = $view->render('foo/bar.phtml');
public static function sendMail($data = array(), $template = ''){
$html = new Zend_View();
$html->setScriptPath(APPLICATION_PATH . '/modules/default/views');
// assign valeues
if(count($data['Assigni'])){
foreach($data['Assigni'] as $assign){
$html->assign($assign['key'], $assign['value']);
}
}
// create mail object
$mail = new Zend_Mail('utf-8');
// render view //'scripts/newsletter/emailtemplate.phtml'
$bodyText = $html->render($template);
$mail->addTo($data['To']);
$mail->setSubject($data['Subject']);
$mail->setFrom($data['From'], $data['FromName']);
$mail->setBodyHtml($bodyText);
$mail->send();
}
when you dispatch the action, you can catch the event in postDispatch() method of plugin, that you can dynamically add to the stack from desired action. In that you recieve the contents of response by
//in action
//...some php code
Zend_Controller_Front::getInstance()->registerPlugin(new My_Plugin());
//in plugin
$htmlCode = $this->_response->getBody();
I can't give you a super-detailed answer, but if you want the full output (including the layout), I think you want to write your email function as an Action helper, and insert it at the PostDispatch hook of the Zend_Controller_Action->dispatch() loop.
See http://nethands.de/download/zenddispatch_en.pdf for the full Zend Framework Dispatch Process Overview.
If you don't need the layout included in your email content, then you could do this at many points, including by the use of a context switch, as you mentioned.