Zend Framework 2 Get controller name from layout - zend-framework2

I have the follow routes to different controllers and actions, that all shows the same layout and different views, example:
http://<my domain>/controllername1/action1
http://<my domain>/controllername1/
http://<my domain>/controllername2/action1
http://<my domain>/controllername3/action1
How can I get the controller name that loads the Layout in the Layout code?, something that returns: "controllername1", "controllername2" or "controllername3"
The goal is to identify in which section I'm of my site and make some customization in layout.
I checked similar replies but are for old versions of Zend Framework.
Clarification:
The idea is to get the controller name from the Layout code, not pass it from the controller code. Maybe isn't possible? Other answers are for older versions of ZendFramework (beta versions), and maybe is a more straightforward way now.
Edited: more information
I can set in my Module.php file the follow code on onBootstrap($e):
public function onBootstrap($e)
{
// (...) Other code
$application = $e->getParam('application');
$viewModel = $application->getMvcEvent()->getViewModel();
// Parsing URI to get controller name
$viewModel->controllerName = trim($_SERVER['REQUEST_URI'],'/');
if (substr_count($viewModel->controllerName, '/')) {
$viewModel->controllerName = substr($viewModel->controllerName, 0, strpos($viewModel->controllerName, '/'));
}
}
And then from the Layout code use it as follow:
echo $this->layout()->controllerName;
The first problem is that the follow piece of code should be replaced with something (more "beautiful") using ZF2 functions to get Controller name:
(...)
// Parsing URI to get controller name
$viewModel->controllerName = trim($_SERVER['REQUEST_URI'],'/');
if (substr_count($viewModel->controllerName, '/')) {
$viewModel->controllerName = substr($viewModel->controllerName, 0, strpos($viewModel->controllerName, '/'));
}
I want to avoid inject the Controller name from all controllers/actions: that is solved by using Module.php, but maybe is a more direct way.
Thanks!

You're looking for this link: How to get the controller name, action name in Zend Framework 2
$this->getEvent()->getRouteMatch()->getParam('action', 'index');
$this->getEvent()->getRouteMatch()->getParam('controller', 'index');
Otherwise you have the same question (and answer(s)) here : ZF2 - Get controller name into layout/views
MvcEvent – get NAMESPACE / Module Name from Layout
http://samsonasik.wordpress.com/2012/07/27/zend-framework-2-mvcevent-layout-view-get-namespace/
I didn't test but it seems correct : http://pastebin.com/HXbVRwTi

I know that this is an old question but there is a simple answer that should be noted here:
$this->getHelperPluginManager()->getServiceLocator()->get('Application')->getMvcEvent()->getRouteMatch()->getParam('action')
this will return any route param, 'action' in this case.
This code can be used in view or in layout.

Related

TYPO3 - Retrieved TypoScript in itemsProcFunc are incomplete

I have following problem:
We are overriding the tt_content TCA with a custom column which has an itemsProcFunc in it's config. In the function we try to retrieve the TypoScript-Settings, so we can display the items dynamically. The problem is: In the function we don't receive all the TypoScript-Settings, which are included but only some.
'itemsProcFunc' => 'Vendor\Ext\Backend\Hooks\TcaHook->addFields',
class TcaHook
{
public function addFields($config){
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');
$setup = $configurationManager->getConfiguration(
\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
);
}
$setup is now incomplete and doesn't contain the full TypoScript, for example some of the static-included TypoScript is missing.
Used TYPO3 7 LTS (7.6.18), PHP 7.0.* in composer-mode.
Does anybody know where the problem is? Is there some alternative?
You maybe misunderstood the purpose of TypoScipt. It is a way of configuration for the Frontend. The Hook you mentioned is used in the TCA, whích is a Backend part of TYPO3. TypoScript usually isn't used for backend related stuff at all, because it is bound to a specific page template record. Instead in the backend, there is the TSConfig, that can be bound to a page, but also can be added globally. Another thing you are doing wrong is the use of the ObjectManager and the ConfigurationManager, which are classes of extbase, which isn't initialized in the backend. I would recommend to not use extbase in TCA, because the TCA is cached and loaded for every page request. Instead use TSConfig or give your configuration settings directly to the TCA. Do not initialize extbase and do not use extbase classes in these hooks.
Depending on what you want to configure via TypoScript, you may want to do something like this:
'config' => [
'type' => 'select',
'renderType' => 'singleSelect',
'items' => [
['EXT:my_ext/Resources/Private/Language/locallang_db.xlf:myfield.I.0', '']
],
'itemsProcFunc' => \VENDOR\MyExt\UserFunctions\FormEngine\TypeSelectProcFunc::class . '->fillSelect',
'customSetting' => 'somesetting'
]
and then access it in your class:
class TypeSelectProcFunc{
public function fillSelect(&$params){
if( $params['customSetting'] === 'somesetting' ){
$params['items'][] = ['New item',1];
}
}
}
I had a similar problem (also with itemsProcFunc and retrieving TypoScript). In my case, the current page ID of the selected backend page was not known to the ConfigurationManager. Because of this it used the page id of the root page (e.g. 1) and some TypoScript templates were not loaded.
However, before we look at the solution, Euli made some good points in his answer:
Do not use extbase configuration manager in TCA functions
Use TSconfig instead of TypoScript for backend configuration
You may like to ask another question what you are trying to do specifically and why you need TypoScript in BE context.
For completeness sake, I tested this workaround, but I wouldn't recommend it because of the mentioned reasons and because I am not sure if this is best practice. (I only used it because I was patching an extension which was already using TypoScript in the TCA and I wanted to find out why it wasn't working. I will probably rework this part entirely.)
I am posting this in the hope that it may be helpful for similar problems.
public function populateItemsProcFunc(array &$config): array
{
// workaround to set current page id for BackendConfigurationManager
$_GET['id'] = $this->getPageId((int)($config['flexParentDatabaseRow']['pid'] ?? 0));
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$configurationManager = $objectManager->get(BackendConfigurationManager::class);
$setting = $configurationManager->getTypoScriptSetup();
$templates = $setting['plugin.']['tx_rssdisplay.']['settings.']['templates.'] ?? [];
// ... some code removed
}
protected function getPageId(int $pid): int
{
if ($pid > 0) {
return $pid;
}
$row = BackendUtility::getRecord('tt_content', abs($pid), 'uid,pid');
return $row['pid'];
}
The function getPageId() was derived from ext:news which also uses this in an itemsProcFunc but it then retrieves configuration from TSconfig. You may want to also look at that for an example: ext:news GeorgRinger\News\Hooks\ItemsProcFunc::user_templateLayout
If you look at the code in the TYPO3 core, it will try to get the current page id from
(int)GeneralUtility::_GP('id');
https://github.com/TYPO3/TYPO3.CMS/blob/90fa470e37d013769648a17a266eb3072dea4f56/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php#L132
This will usually be set, but in an itemsProcFunc it may not (which was the case for me in TYPO3 10.4.14).

C# code in the View, Cloudinary API guide

I am trying to make an asp.net mvc 5 app by this ASP.NET image upload guide.
I am curious about this part of the guide (on the photo here):
as I understand at that part I am supposed to write the code in my View (cshtml) page. (Cause before there was attaching js's and running scripts in "<"script">" tag)
How can I write such C# code in the View? Where am I wrong?
string cors_location = (new UriBuilder(Request.Url.AbsoluteUri) { Path = Url.Content("~/Content/cloudinary_cors.html") }).ToString();
C# code in a view generally belongs in a server side block like this ...
#{
string cors_location = (new UriBuilder(Request.Url.AbsoluteUri)
{ Path = Url.Content("~/Content/cloudinary_cors.html") }).ToString();
}
How can I write such C# code in the View? Where am I wrong?
Hi.
like this by adding the '#'sign
#{string cors_location = (new UriBuilder(Request.Url.AbsoluteUri) { Path = Url.Content("~/Content/cloudinary_cors.html") }).ToString();}
also please check http://www.asp.net/web-pages/overview/getting-started/introducing-razor-syntax-c
my server should get a link of uploaded file
To manage this You should do something like this:
create property in Your model class for eg.
public string ImgUrl {get;set;}
In Your View controller you should pass url value from view
Img.Url = "My Image Url passed from View";
and then save Your model to Db.
For more please check http://www.mikesdotnetting.com/article/259/asp-net-mvc-5-with-ef-6-working-with-files

action helper and routing priority laravel 5

I have two rules
Route::get('this-is-an-awesome-route', 'Ads#getIndex');
Route::controller('ads', 'Ads');
action('Ads#getIndex') renders
http://my-awesome-domain/ads
I want
http://my-awesome-domain/this-is-an-awesome-route
What's the problem ?
For some reason from Laravel 4.2 to Laravel 5 the logic changed a little bit. The line you wrote was working before, you just have to reverse everything as the router isn't processing your code the same way.
Tested and working solution
Route::controller('ads', 'Ads');
Route::get('this-is-an-awesome-route', 'Ads#getIndex');
The first route will be overwritten by the second one.
The second route is rewriting the first route declaration. Let's see:
// Ads#getIndex will be called
Route::get('this-is-an-awesome-route', 'Ads#getIndex');
// Ads#getIndex will be called too by native definition
Route::controller('ads', 'Ads');
Because of Route::controller('ads', 'Ads') is called as latest declaration it will overwrite the previous one. So, you have at least two ways to achieve this task
You could create a new function into Ads controller just to response to the first route:
Route::get('this-is-an-awesome-route', 'Ads#awesome');
Then:
public function awesome(){
// do stuff here
}
Rename the route name for your controller
Route::controller('ads', 'Ads', [
'getIndex' => 'ads.getHome',
]);
Now your Route::controller('ads', 'Ads'); will respond to getHome() instead getIndex() as per renamed route:
public function getHome(){
// do stuff for getIndex() definitions here
}

ZF2: How to pass a variable from the method attached to MvcEvent::EVENT_FINISH to the layout attached in MvcEvent::EVENT_RENDER?

I am trying to understand Zend Framework 2 (ZF2). Few days ago I bought the book "Learn ZF2: Learning By Example" by Slavey Karadzhov. Now I am reading it and trying to get some examples working.
I am stuck in page 60. The example shown in the book works well, but the modification I just made does not work... Why? How to fix it?
To get into the same code/situation you would have to:
git clone https://github.com/slaff/learnzf2 .
composer.phar self-update
composer.phar install
git stash
git checkout 'ch-view'
After that You will have the same setup as I do.
Now I have changed the file /module/Debug/view/debug/layout/sidebar.phtml from this:
<h1>Top Line</h1>
<?= $this->content ?>
<h1>Bottom Line</h1>
to this (just added one line at the end):
<h1>Top Line</h1>
<?= $this->content ?>
<h1>Bottom Line</h1>
<p>MVC duration: <?= $this->mvcDuration ?></p>
I would like $this->mvcDuration to be the value of $duration from /module/Debug/Module.php file getMvcDuration method.
I changed the content of method getMvcDuration from this:
public function getMvcDuration(MvcEvent $event)
{
// Here we get the service manager
$serviceManager = $event->getApplication()->getServiceManager();
// Get the already created instance of our timer service
$timer = $serviceManager->get('timer');
$duration = $timer->stop('mvc-execution');
// and finally print the duration
error_log("MVC Duration:".$duration." seconds");
}
to this (added two lines at the end of the method):
public function getMvcDuration(MvcEvent $event)
{
// Here we get the service manager
$serviceManager = $event->getApplication()->getServiceManager();
// Get the already created instance of our timer service
$timer = $serviceManager->get('timer');
$duration = $timer->stop('mvc-execution');
// and finally print the duration
error_log("MVC Duration:".$duration." seconds");
$viewModel = $event->getViewModel();
$viewModel->setVariable('mvcDuration', $duration);
}
However, this kind of change does not work and the value of $duration is not passed to the layout. The question is WHY? How can I pass $duration to $this->mvcDuration of the layout?
p.s. The code downloaded from official github repo (https://github.com/slaff/learnzf2) is acting quite strange... Changing project files (e.g.: /module/Debug/view/debug/layout/sidebar.phtml) does not change the output. If You have the same situation while trying to help me with this case then I would suggest you to modify files in /vendor/learnzf2 directory instead of files in /module directory. I know that modifying code in vendor directory is not good thing to do, but let this post (my question) be about the one problem only.
Good book. Your basic problem is that you are Trying to update a variable into the view in a method that is triggered after the view has already been sent. You probably can't do this, unless you redefine which event triggers it, but that would defeat the intended purpose of timing the whole mvc duration.
All that said, you shouldn't be injecting variables into the view model from module.php. It's very hard to test that. This is what view helpers are good for.

Why data is not send by form submitting (zf2 forms + filters)?

I have problem:
When I fill in form and pressing add button page is reloaded, but no data is added to the database.
Code of NewsController, add action is below:
public function addAction() {
$form = new AddNewsForm();
$form->get('submit')->setValue('Add1');
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
var_dump($form->isValid());
if ($form->isValid()) {
echo "form is valid";
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
$blogpost = new NewsItem();
$blogpost->exchangeArray($form->getData());
$blogpost->setCreated(time());
$blogpost->setUserId(0);
$objectManager->persist($blogpost);
$objectManager->flush();
// Redirect to list of blogposts
return $this->redirect()->toRoute('news');
}
}
return array('form' => $form);
}
Class AddNewsForm is included as use \News\Form\AddNewsForm as AddNewsForm; above.
I tried to debug my code and realized, that $form->isValid() return false all time. I tried to fill in all fields of form — it says that form is not valid. If not all fields are filled in it false too.
The problem is with validation, I think, so I will add here how I assing filter to the form. This is how I assing filter to my form:
$this->setInputFilter(new AddNewsInputFilter());
Class AddNewsInputFilter is included by this:
use \News\Form\AddNewsInputFilter as AddNewsInputFilter;
I don't think it is good to paste there ~100 lines of code, so I will just give a link to files in my github repo (full code of controllers/files available here):
AddNewsForm.php — file, where I create the form
AddNewsInputFilter.php — file, where I set fil
NewsController.php — file, controller, where I call created form
Repository link — root dir of my module
So the problem is that $form->isValid(); doesn't show is form valid or not properly and I don't know why. Note, that request is getting properly and first condition is passed (but second is not passed). It is the problem, thats why I am writing here.
How I can solve it?
Thanks is advance!
try var_dump($form->getMessages()) and var_dump($form->getInputFilter()->getMessages()) in controller(after calling $form->isValid()) or in view . see what error you getting and on witch element ?
NOTICE : getMessages() will be empty if $form->isValid() has not been called yet,
UPDATE : do this in controller :
var_dump($form->isValid());
var_dump($form->getMessages())
var_dump($form->getInputFilter()->getMessages())

Resources