How to get the current view being rendered inside ZF2 - zend-framework2

Is there a way to get the current view being rendered inside zend framework 2?
I believe this should be possible with the event system but I can't seem to make it work.
The reason I want to get this information is so I can automatically include a .js file with the same name, this would save me time having to specify this rule each time i'm inside a action.
Many thanks,
Tom

I'm not quite sure what you mean by rendering the current view inside ZF2, but here's how you can add a js file named after the action automatically. Just put this in your controller:
public function onDispatch(MvcEvent $mvcEvent)
{
$renderer = $this->serviceLocator->get('Zend\View\Renderer\PhpRenderer');
$actionName = $mvcEvent->getRouteMatch()->getParam('action');
$jsFile = $actionName . '.js';
$baseUrl = $mvcEvent->getRouter()->getBaseUrl();
$renderer->headScript()->appendFile($baseUrl . '/js/' . $jsFile);
return parent::onDispatch($mvcEvent);
}
You may need to adjust the code for your js file location and name of course. The onDispatch method is called automatically before the action.

Thank You Wunibald,
Your example worked perfectly, I have modified it below to be attached to an event so that it applies to every controller/module. To do this I have included it into the onBootstrap function in my Application module.
$events = StaticEventManager::getInstance();
$events->attach('Zend\\Mvc\\Application', 'dispatch', function(\Zend\EventManager\Event $event)
{
$baseUrl = $event->getRouter()->getBaseUrl();
$renderer = $event->getApplication()->getServiceManager()->get('Zend\View\Renderer\PhpRenderer');
$action = $event->getRouteMatch()->getParam('action');
$controller = $event->getRouteMatch()->getParam('controller');
if (strlen($controller) > 0)
{
list($module, $_null, $controller) = explode('\\', $controller);
$renderer->headScript()->appendFile($baseUrl . '/module/' . $module . '/view/' . strtolower($module) . '/' . strtolower($controller) . '/' . strtolower($action) . '.js');
$renderer->headScript()->appendFile($baseUrl . '/module/' . $module . '/view/' . strtolower($module) . '/' . strtolower($module) . '.js');
}
});
Once again thank you for pointing me in the right direction.

Related

Twitter Module - Drupal 7

Twitter Module is working finde with my Drupal 7 site. I wanted to make a tweek so that nodes that are not hidden get tweeted, I was able to do this by altering twitter_post_node_insert in twitter/twitter_post . All I did was add a new condition of !$node->hidden . It works great.
function twitter_post_node_insert($node) {
if (!empty($node->status) && !empty($node->twitter) && !empty($node->twitter['post'])
&& !$node->hidden) { ......
My problem is that this code in the Twitter Module only gets called when I directly edit a node and save it. Now, I would like to have said code called also when I edit my node programmatically, where I save it with $node_wrapper->save(); . The twitter code won't get called. I've also tried with node_save($node); , instead of using my $node_wrapper. Nothing.
I also tried including the file twitter_post.module located in twitter/twitter_post, and then calling the function in charge of posting the tweet :
module_load_include('module', 'twitter', '../twitter/twitter_post/twitter_post');
twitter_post_node_update($node);
Nothing happens and no errors are shown. What I'd like is to know what Drupal 7 function gets called in its core when you edit a node through its interface and then save it. That way I can just put that function in the code where I edit my node programmatically so that the Twitter code will also get called. Or, does anyone have a better approach?
Thanks.
After looking into the Twitter module this is what I have done in order to have the nodes published programmatically.
I added the following function to twitter/twitter_post/twitter_post.module . It's a copy of the function function twitter_post_node_insert($node), found on the same file. I made a copy so that it would not print out the message of "tweet posted succesfully". That way I call the copied function from another place to post the tweet.
/**
* Function called from custom .module to insert tweets from "Editar Pesos" tab
*/
function twitter_post_node_custom_insert($node) {
if (!empty($node->status) && !empty($node->twitter) && !empty($node->twitter['post']) && !$node->hidden ) {
module_load_include('inc', 'twitter');
$twitter_account = twitter_account_load($node->twitter['account']);
$replacements = array(
'!title' => truncate_utf8($node->title, 90, false, true),
'!url' => url('node/' . $node->nid, array('absolute' => TRUE, 'alias' => TRUE)),
'!url-alias' => url('node/' . $node->nid, array('absolute' => TRUE))
);
// Only generate the shortened URL if it's going to be used. No sense
// burning through TinyURLs without a good reason.
if (strstr($node->twitter['status'], '!tinyurl') !== FALSE) {
$replacements['!tinyurl'] = twitter_shorten_url(url('node/' . $node->nid,
array('absolute'=> TRUE)));
}
$status = strtr($node->twitter['status'], $replacements);
return twitter_set_status($twitter_account, $status);
}
}
And following is the "magic", which gets called whenever I want the node posted as a tweet.
function post_to_twitter($node){
module_load_include('module', 'twitter', '../twitter/twitter_post/twitter_post');
$twitter = array(
'account' => getTwitterUid(),
'post' => 'POST',
'status' => "!title !tinyurl"
);
$node->twitter = $twitter;
return twitter_post_node_custom_insert($node);
}
function getTwitterUid(){
return db_query("select twitter_uid from {twitter_account} where screen_name = :screen_name
limit 1", array(":screen_name" => 'YOUR_TwitterScreenName'))->fetchField();
}
Hope this can help anyone who was looking for the same thing as I.

How to override processForm() in admin-generator

I'm trying to add some extra logic to update and delete actions in a module generated by task doctrine:generate-admin. I read here and see that I can create executeUpdate() and executeDelete() methods in /application/mymodule/actions/actions.class.php. Because executeUpdate() call proccessForm() method then I think the best is to override this instead of executeUpdate() but don't know how. The code I need to add is this:
$q = Doctrine_Core::getTable('SdrivingEmpresa')
->createQuery('a')
->where('idempresa = ?', $request->getParameter('idempresa'))
->execute();
$file = new sfFilesystem();
$file->remove(sfConfig::get('sf_upload_dir') . '/' . $q[0]->getLogotipo());
I do it for executeDelete() by copying the generated cache coded and writing my logic see below:
public function executeDelete(sfWebRequest $request) {
$request->checkCSRFProtection();
$this->dispatcher->notify(new sfEvent($this, 'admin.delete_object', array('object' => $this->getRoute()->getObject())));
$q = Doctrine_Core::getTable('SdrivingEmpresa')
->createQuery('a')
->where('idempresa = ?', $request->getParameter('idempresa'))
->execute();
$file = new sfFilesystem();
$file->remove(sfConfig::get('sf_upload_dir') . '/' . $q[0]->getLogotipo());
if ($this->getRoute()->getObject()->delete()) {
$this->getUser()->setFlash('notice', 'The item was deleted successfully.');
}
$this->redirect('#sdriving_empresa');
}
But I tough this is not right, so my question is, should I do the same with processForm() or exists a better way to do this? any advice or help?
You can copy the proccessForm() generated in the cache of the application in your admin module action to override it.

Simple HTML Dom Parser: How to insert to elements

I am trying to insert (append) into an element ... "body" specifically.
I am able to do this this way at the moment:
$var = "some JS stuff";
$e = $htmlDOM->find("body", 0);
$e->outertext = '<body>' . $e->innertext . $var . '</body>';
My issue is that this fixes <body> but the actual html might have js or id etc attached to <body> and I will like to maintain that if it is the case.
The docs don't seem to show a method for this.
Is it possible?
After looking at the source code, I found that the way to go about it is to use
$var = "some JS stuff";
$e = $htmlDOM->find("body", 0);
$e->outertext = $e->makeup() . $e->innertext . $var . '</body>';
That is, the undocumented makeup() function will build the tag and any associated text/code.

Using a command object boolean with a input:checkbox in grails

This is probably a ridiculously easy question, but I've been struggling with it nonetheless.
I have a form:
.
.
.
<g:form controller='somecontroller' action='someaction'>
<g:textField name='name'/>
<g:checkBox name='active'/>
<g:submitButton name='save'/>
</g:form>
.
.
.
And I have a command object:
class MyCommandObject{
String name
Boolean active
static constraints{
.
.
.
}
}
When I try to access the active property of the command object in my controller, it's always false. The name property, however, is being properly populated. I've tried changing the value to true, and also ${true} (as I saw in some example) and none seem to work. What am I doing wrong here?
Edit: How I'm binding to the command object in the controller:
class MyController{
.
.
.
def save(MyCommandObject cmd){
// Do validation/error checking
def myDomainObject = new DomainObject()
myDomainObject.name = cmd.name
myDomainObject.active = cmd.active
// Do something with myDomainObject
}
}
I've also tried the style:
def save = { MyCommandObject cmd ->
.
.
.
}
Everything you've done looks fine and I've verified as working in 1.3.7 and 2.0.4.
Please do a grails clean and try again.

Magento multilanguage - double change in language resuts in 404 (or how to change language within stores not views)

I have a problem with a magento installation. I used Magento ver. 1.5.0.1, community edition to develop this website http://cissmarket.com/.
The problem appears when I change the language from the EU version to French and after that to German. The change to french is ok, but when in the same page i change to German i receive a 404 error. Also this is generation 404 errors in the Google webmaster tools and when i try for example to take this link and paste it in the browser it gives me also a 404 error. I have there some 50 products and ~550 404 errors in Google Webmaster tools. I understand that the problem is from what I described.
Moreover I have a SEO problem since I have this page in french:
http://cissmarket.com/de/cartouches-refilables.html
And when I switch to the german version of the website it takes me to this link
http://cissmarket.com/de/cartouches-refilables.html?___from_store=fr (if i try now to switch to uk I will get the 404 mentioned above)
instead of going to this one:
http://cissmarket.com/de/nachfullpatronen.html
Already checked this 404 error when switching between stores when in a category on magento but it does not relate to my problem.
About settings:
I use the caching service and also I did index all the content.
The product or category I am trying to access is available and set active for all the languages.
System > General > Web > URL options > Add Store Code to Urls is set
to yes.
System > General > Web > Search Engines Optimization > Use Web Server
Rewrites is set to yes.
No other changes has been made to the .htaccess file except for the
ones that the system itself made.
So to conclude: the problem is the 404 given by 2 succesive changes of the language and the bad url address when I switch from one page to another.
Any suggestions would be appreciated.
UPDATE: tried this http://www.activo.com/how-to-avoid-the-___from_store-query-parameter-when-switching-store-views-in-magento but it results in a 404 at the first language change
Edit #1:
Found the problem: file languages.phtml contained this code <?php echo str_replace ("/fr/","/de/",$_lang->getCurrentUrl()); ?> and actually did replace only the language code and not the whole url according to the corresponding translation.
So applied to this
http://cissmarket.com/fr/cartouches-refilables.html
it will return
http://cissmarket.com/de/cartouches-refilables.html
So does anyone know how to get the corresponding URL of the current page for the other languages available in the store?
Edit #2 (using #Vinai solution):
It works on the product pages but not on the category yet.
There is no such thing in the native Magento as far as I know.
That said, you can use the following code to get the current page URL for each store.
$resource = Mage::getSingleton('core/resource');
$requestPath = Mage::getSingleton('core/url')->escape(
trim(Mage::app()->getRequest()->getRequestString(), '/')
);
$select = $resource->getConnection('default_read')->select()
->from(array('c' => $resource->getTableName('core/url_rewrite')), '')
->where('c.request_path=?', $requestPath)
->where('c.store_id=?', Mage::app()->getStore()->getId())
->joinInner(
array('t' => $resource->getTableName('core/url_rewrite')),
"t.category_id=c.category_id AND t.product_id=c.product_id AND t.id_path=c.id_path",
array('t.store_id', 't.request_path')
);
$storeUrls = (array) $resource->getConnection('default_read')
->fetchPairs($select);
This will give you an array with the array key being the store IDs and the array values being the request path after the Magento base URL, e.g. assuming your French store has the ID 1 and the German one has the ID 2, you would get:
Array
(
[1] => cartouches-refilables.html
[2] => nachfullpatronen.html
)
Then, in the foreach loop where the URL for each store is output, use
<?php $url = isset($storeUrls[$_lang->getId()]) ? $_lang->getUrl($storeUrls[$_lang->getId()]) : $_lang->getCurrentUrl() ?>
The call to $_lang->getUrl() will add the base URL, so you will get the full URL for each store (e.g. http://cissmarket.com/de/nachfullpatronen.html). If no store view value is found in the core_url_rewrite table it will revert to the default behaviour.
You still need the ___store=fr query parameter because otherwise Magento will think you are trying to access the new path in the context of the old store. Luckily, the getUrl() call an the store model adds that for you automatically.
The code querying the database can be anywhere of course (since its PHP), even in the template, but please don't put it there. The correct place to have code that access the database is a resource model. I suggest you create a resource model and put it in a method there.
I've found an ugly patch until a better approach comes up.
In the admin section, i've added the following javascript inside the wysiwyg in CMS > PAGES > (My 404 pages) (at the beginning of the wysiwyg) :
<script type="text/javascript" language="javascript">// <![CDATA[
var lang = "en";
var rooturl = "{{config path="web/unsecure/base_url"}}"
var url = document.location.href;
if(!(url.match("/"+lang+"/")))
{
var newUrl = url.replace(rooturl , rooturl+lang+"/" );
window.location.href = newUrl;
}
// ]]></script>
(Note: you need to do this for all of your translated 404 pages. In each 404 page you need to modify lang="en" for your storeview url value)
Because the wysiwyg (tiny_mce) does not allow javascript to be threated, you'll have to modify js/mage/adminhtml/wysiwyg/tinymce/setup.js. Add the following code under line 97 (under "var settings = "):
extended_valid_elements : 'script[language|type|src]',
For Magento 1.7.0.2 and 1.8.0.0 this is the bugfix:
Starting from line 251 of /app/code/core/Mage/Core/Model/Url/Rewrite.php
:
Mage::app()->getCookie()->set(Mage_Core_Model_Store::COOKIE_NAME, $currentStore->getCode(), true);
// endur 02-03-2013 fix for missed store code
// $targetUrl = $request->getBaseUrl(). '/' . $this->getRequestPath();
if (Mage::getStoreConfig('web/url/use_store') && $storeCode = Mage::app()->getStore()>getCode()) {
$targetUrl = $request->getBaseUrl(). '/' . $storeCode . '/' .$this->getRequestPath();
} else {
$targetUrl = $request->getBaseUrl(). '/' . $this->getRequestPath();
}
// endur 02-03-2013 end
Make sure to create a custom copy of the file in:
/app/code/local/Mage/Core/Model/Url/Rewrite.php or:
/app/code/local/YourTheme/Mage/Core/Model/Url/Rewrite.php
source:
It looks like a bug in Magento 1.7. Here is a hack that worked for me.
It should work for a two language store with store code in URL
in var/www/html/shop1/app/code/core/Mage/Core/Model/Url/Rewrite.php
remove this line
// $targetUrl = $request->getBaseUrl(). '/' . $this->getRequestPath();
and add these:
$storecode = Mage::app()->getStore()->getCode();
if ($storecode='en')
{
$targetUrl = $request->getBaseUrl(). '/'.$storecode.'/' . $this->getRequestPath();
}
else
{
$targetUrl = $request->getBaseUrl(). '/' . $this->getRequestPath();
}
Here a another solution for this problem. Just add this code after "$this->load($pathInfo, 'request_path');" in app/code/core/Mage/Core/Model/Url/Rewrite.php:
if (!$this->getId() && !isset($_GET['___from_store'])) {
$db = Mage::getSingleton('core/resource')->getConnection('default_read');
$result = $db->query('select store_id from core_url_rewrite WHERE request_path = "' . $pathInfo . '"');
if ($result) {
$storeIds = array();
if($row = $result->fetch(PDO::FETCH_ASSOC)) {
$storeId = $row['store_id'];
$storeCode = Mage::app()->getStore($storeId)->getCode();
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://" . $_SERVER['HTTP_HOST'] . "/" . $pathInfo . "?___store=" . $storeCode);
exit();
}
}
}
guys. For this error there is magento module. It have rewrite 2 models
http://www.magentocommerce.com/magento-connect/fix-404-error-in-language-switching.html

Resources