Wildcard parameter value and zend navigation - php

Is it posible to map a page to a specific action + param combination, like this:
<myprofile>
<label>My Profile</label>
<controller>user</controller>
<action>profile</action>
<visible>1</visible>
</myprofile>
<othersprofile>
<label>User Profile</label>
<controller>usuario</controller>
<action>perfil</action>
<visible>0</visible>
<reset_params>0</reset_params>
<params>
<id>*</id>
</params>
</othersprofile>
I'd like that if the uri includes any id param , then the should be active. (I put a * as wildcard but I dont know a correct way to do it)
/user/profile = should set myprofile to active
/user/profile/id/5 = should set othersprofile to active
Any help appreciated.
Thanks

There is a workaround by setting explicitly the page as active in your action.
You could do it like this :
public function perfilAction(){
$this->view->navigation()->findOneBy('controller','usario')->setActive();
// rest of your action code...
Starting from ZF 1.11.8, you should be able to just add the route name in your page params, and it will be active for anything matching this route. (the "route" feature has been added before, but there were some issues with isActive detection, see http://framework.zend.com/issues/browse/ZF-11359)

Related

Magento issues when saving Categories

I have some issues saving categories in Magento 2.3.5, when I click save after changing the SEO information (Meta Title, Meta description and Meta Keywords) gives me this error.
Argument 1 passed to Magento\Catalog\Model\Category\FileInfo::removeStorePath() must be of the type string, array given, called in /home/adminpsol2016/public_html/vendor/magento/module-catalog/Model/Category/FileInfo.php on line 167
here you can see a screenshot of the problem.
This gave me quite a headache but finally managed to get to the bottom of it; my case is as follow:
Repro:
add a custom category attribute with backend_model := Magento\Catalog\Model\Category\Attribute\Backend\Image
Have the category form save operation fail for whatever reason (e.g. have a plugin on the category model save function which throws an Exception)
Reason:
If you look at https://github.com/magento/magento2/blob/2.4-develop/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php#L240 you'll see that this has the effect of storing the entire POST data of the current form request to session (also the LocalizedException block does the same).
Later on, this data is restored in https://github.com/magento/magento2/blob/2.4-develop/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php#L95 and immediately after the form information for the image attribute is stripped/cleared.
This of course does not handle any custom attribute of Image type we might have defined for our category entity.
Solution:
I added an after* plugin (in adminhtml area only) on \Magento\Framework\Session\SessionManager::__call, where I explicitly check that the invoked method is getCategoryData: if this is the case, I fetch all the custom category image attributes, and strip them from the returned array like Category/Edit does.
This way any further exception message is correctly displayed in the backoffice (granted it extends LocalizedException)
Just to expand on the answer from Francesco Salvi which really helped me with the same problem, this is how we implemented that solution:
etc/adminhtml/di.xml
<?xml version="1.0" ?>
<config>
<type name="Magento\Framework\Session\SessionManager">
<plugin name="pluginNameGoesHere" type="Vendor\Namespace\Plugin\StripCustomImage" />
</type>
</config>
plugin/StripCustomImage.php
<?php
namespace Vendor\Namespace\Plugin;
class StripCustomImage
{
public function after__call($method, $response, ...$args)
{
if ($args[0] === 'getCategoryData') {
if (isset($response['widget_image']['delete'])) {
$response['widget_image'] = null;
} else {
unset($response['widget_image']);
}
}
return $response;
}
}
Where 'widget_image' is the attribute name for the custom category image we created in another module that was causing us the pain.

How concatenate variable in url in magento

I'm trying to add Variable in URL in magento. Here is my link:
<?php echo Mage::helper("html")->getUrl("admin/index/test/".$testId); ?>
If i add / at the end of profile then url not concatenate with testId. But if concatenate testId without adding / at the end of profile then it's not concatenate variable id. here is link
<?php echo Mage::helper("html")->getUrl("admin/index/test".$testId); ?>
Can anyone describe me, what i'm missing?
There are a few mistakes:
the first parameter to getUrl must be a route in the form router/controller/action. Additional parameters can be added with the second parameter
the router for the admin URL is called adminhtml. Magento distinguishs between front name (the first part of the URL) and router (the internal value), which makes it possible to have a custom admin URL. This is configured in app/code/core/Mage/Adminhtml/etc/config.xml:
<routers>
<adminhtml>
<use>admin</use>
<args>
<module>Mage_Adminhtml</module>
<frontName>admin</frontName>
</args>
</adminhtml>
</routers>
The last part(s) of a route can be ommitted in the URL if they are "index", so for the URL /admin, the route is adminhtml/index/index. But as soon as you want to add parameters, all parts are required, to distinguish the parameters from controller and action. It looks like you want to add the parameter test=$testId to the existing route adminhtml/index/index, which redirects to the configured start page, by default adminhtml/dashboard/index, or to the login page if you are not logged in.
For admin URLs, you need to use the adminhtml helper (or the adminhtml/url model)
Conclusion
To get the URL admin/index/index/test/$testId, the first parameter must be adminhtml/index/index and the second parameter ['test' => $testId]
echo Mage::helper("adminhtml")->getUrl("adminhtml/index/index", ['test' => $testId]);
Alternative
If you want to build the URL with GET parameters in the form admin?test=$testId, you can use the _query parameter:
echo Mage::helper("adminhtml")->getUrl("adminhtml/index/index",
['_query' => ['test' => $testId]]);
Try this
echo Mage::helper("adminhtml")->getUrl("adminhtml/index/index",array('test'=>$testId));

making Url user friendly in magento

This is my custom module url http://192.168.1.18/upload/index.php/capsync/
I want to call the next action from the controller apiaction with this:
http://192.168.1.18/upload/index.php/capsync/index/api
but remove index in the url:
http://192.168.1.18/upload/index.php/capsync/api
My config.xml page
<rewrite>
<Livelids_Capsync>
<from><![CDATA[#^capsync/index/api/#]]></from>
<to><![CDATA[api]]></to>
<complete>1</complete>
</Livelids_Capsync>
</rewrite>
In Magento, router will parse your URL as follows:
http://yoursite.com/[frontName]/[actionControllerName]/[actionMethod]/
In your case, For URL : http://192.168.1.18/upload/index.php/capsync/index/api
frontName :: capsync
actionControllerName :: indexController
actionMethod :: apiAction
Above is exactly what you want that is next action in the controller which would be 'apiAction'
Similarly, if you want URL : http://192.168.1.18/upload/index.php/capsync/api
Then your actionControllerName will turn to another controller(apiController) & action(indexAction by default) altogether which is what I don't think you want.
Let me know if you don't get this. Thanks! :)

How can I display/hide menu items with Zend Framework

[See update at the end]
I'm working with Zend framework, in PHP and I have some difficulties with Zend Navigation. It's my first question here, so if something's wrong with it, just tell me and I'll correct it.
I have a menu looking like this in my application
Home
Login
Logout
Member's Page
I have a navigation xml file containing my menu.
<nav>
<home>
<label>Home</label>
<uri>/</uri>
</home>
<login>
<label>Login</label>
<uri>/index/login</uri>
</login>
<logout>
<label>Logout</label>
<uri>/index/logout</uri>
</logout>
<member>
<label>Member's Page</label>
<uri>/index/member</uri>
</member>
</nav>
Also a menu.phtml containing this
<div class="top-level">
<?php
foreach ($this->container as $page) {
if ($page->isVisible()) {
if ($page->isActive(true)) {
if ($page->isActive(false)
)$page->setClass("active");
else
$page->setClass("open");
echo $this->navigation()->menu()->htmlify($page);
//... the same continue for the 3 menu level
Finally, in my layout.phtml, I have this to render the menu
<?php
$partial = array('menu.phtml', 'default');
$this->navigation()->menu()->setPartial($partial);
echo $this->navigation()->menu()->render();
?>
For now, my menu works good, but I can't have Login and Logout always displayed in my menu. So, what I need to do, is to hide Login when I'm logged in, and to hide Logout when I'm logged out. It looked pretty simple when I started, and it still does, but I can't make it work. I don't know how and if I can hide and show item depending on logged users. I really need to make it work, because I will need to hide/display other items in the future.
So is there a way of doing that ?
Thanks !
EDIT :
I'm currently not using Zend::Auth or Zend_ACL for roles and authorization. If I want to know if the user is logged in or not, I have a token in the session that is valid only when the user is logged in. I'd like my menu to work without changing that if it's possible.
UPDATE :
I had it working in another way than those suggested. I'm really not sure it's a clean way, but it's doing the job for now. So now, my xml navigation file look like
<menuAnonymous>
<home>
<label>Login</label>
<uri>/login</uri>
</home>
</menuAnonymous>
<menuLogged>
<home>
<label>Logout</label>
<uri>/Logout</uri>
</home>
</menuLogged>
I initialize both in my bootstrap like this.
$config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'menuNotLogged');
$container = new Zend_Navigation($config);
Zend_Registry::set('main',$container);
And then, in my layout, I look at my token and display the menu depending on that.
if ($tokenValid) {
echo $this->navigation()->menu()->render(Zend_Registry::get('main'));
} else {
echo $this->navigation()->menu()->render(Zend_Registry::get('logged'));
}
So it's working like I want now, but I still want to do it cleaner, so if you have any suggestions to help me ... thank you !
You should have a look at the "Leveraging Zend_Navigator" webinar on http://www.zend.com/en/resources/webinars/framework. It explains how you can tie your navigation to specifiec roles/ACL.
I updated my question with the solution I used, maybe I'll find a better way to do it later but for now this is it. I didn't find the solution here, that's why I'm answering my own question. Thanks for your help !

Drupal View (Page) vs Taxonomy

I have the following problem:
I use taxonomys (tx) as tags. They can be added when the node is created. So I don't know how many tx I have or what ID they have.
The path of the tx is like the following:
/foo/element1
/foo/element2
/foo/element3
...
The secound element is the tx.
Now I want to use a view (page) to handle the tx-path:
/foo/%
The problem is, when I open a path like the one on top I see the theme of the node-taxonomy.tpl.php but not the style I set in the view.
Whenever I open a path in the form (/foo/not-a-tx) I can see the output of the view.
Could someone give me a hint how to get out the view output but not the tx-output?
Thanks
Sebastian
I solved the problem with this way:
I use a view block (not a page)
I added a new output area in my ,info file
I use this way to show only the vocab
I show the block in the new area online bei foo/*
It works Okay for me.
Thx to every one.
Do you want to get rid of the taxonomy pages completely?
If so, you can use a hook_menu_alter() and unset the taxonomy page.
EX.
hook_menu_alter(&$items) {
unset($items['taxonomy/term/%taxonomy_term']);
}
You'd have to look at the $items array to pinpoint the name of the registered menu path, but I think this is it.
This will remove the taxonomy page for all vocabularies however.
Actually you need to make a view to override the internal drupal path of the taxonomy term page: taxonomy/term/% (where % is the taxonomy id) and not the aliased path, which in your case is foo/%
[Optional but saves work: There is already an example view that is bundled with Drupal that implements the taxonomy view. Go to Views > List and you will see the the view is greyed out and it is called
Default Node view: taxonomy_term (default)
All you need to do is enable it and modify it to your needs]
Don't worry about the aliases. You can define your URL pattern at /admin/build/path/pathauto (make sure pathauto module is enabled. You can download it at http://drupal.org/project/pathauto ). In your case the pattern would be foo/[cat] where [cat] is a token for category. Make sure you enter this pattern under Taxonomy Term paths in the pathauto automated alias settings.

Categories