I have a module that I'm trying to use with an email template I created. I created the .phtml template directly (not through the new template form on the backend) into the locale > en_US > template > email folder. The template seems to work as the variables passed to it work and the email gets sent fine. My only problem is that now when I go into the management > Transactional Emails > New Template, the page crashes. The dropdown is empty and everything after it does't get rendered.
I think it might have something to do with the way I'm loading the template in the modules config.xml. When I remove the reference to the template the problem goes away. Put the reference back in and the form crashes..
Config.xml
<?xml version="1.0"?>
<config>
<modules>
<Optimise_Requestcallback>
<version>0.1.9</version>
</Optimise_Requestcallback>
</modules>
<frontend>
<routers>
<requestcallback>
<use>standard</use>
<args>
<module>Optimise_Requestcallback</module>
<frontName>request-callback</frontName>
</args>
</requestcallback>
</routers>
<layout>
<updates>
<requestcallback>
<file>optimise.xml</file>
</requestcallback>
</updates>
</layout>
</frontend>
<global>
<template>
<email>
<requestcallback_template translate="label" module="requestcallback">
<label>Optimise RequestCallback</label>
<file>requestcallback_template.html</file>
<type>html</type>
</requestcallback_template>
</email>
</template>
</global>
</config>
Here is how I send the email:
public function sendemailAction() {
$emailTemplate = Mage::getModel('core/email_template')
->loadDefault('requestcallback_template');
$emailTemplateVariables = array();
//Fetch submited params
$params = $this->getRequest()->getParams();
$subjectOfMail = "Request a Callback from the Puji Website<br /><br />Product = " . $params['product'] . "<br />Name = " . $params['name'] . "<br />Email = " . $params['email'] . "<br />Telephone = " . $params['telephone'] . "<br />Message = " . $params['comment'];
$emailTemplateVariables['body'] = $subjectOfMail;
$emailTemplate->setSenderName($params['name']);
$emailTemplate->setSenderEmail($params['email']);
try {
$emailTemplate->send('billy#optimiseweb.co.uk', 'Sales', $emailTemplateVariables);
Mage::getSingleton('core/session')->addSuccess('Thank you! We will contact you very soon.');
} catch (Exception $ex) {
$translate->setTranslateInline(true);
Mage::getSingleton('customer/session')->addError(Mage::helper('contacts')->__('Unable to submit your request. Please, try again later'));
$this->_redirect('*/*/');
return;
}
//Redirect back to index action of (this) activecodeline-simplecontact controller
$this->_redirect('request-callback/');
}
And the template itself probably couldn't be any simpler!
<!--#subject Request a Callback from the Puji Website #-->
{{var body}}
Can anyone see an issue here that would cause the New template form to crash?
There can be various reasons, but first check config.xml file for each custom module, one-by-one.
There must be one module, where you will find code like:
module="[some-module-name-here]"
Try removing this code one-by-one and reload the transactional e-mail template form again.
I am sure, it will solve the problem.
Related
I have a Symfony2 -project and it writes the logs into different files beautifully, but I would like it to write the logs into a remote database(mongodb) as well. I would like to keep the actual log files in the servers as a backup in case something goes wrong with the database connection.
Question 1:
Is it even possible to save the same logs into two different places at the same time?
Question 2:
How do I save the logs into the mongodb? I don't necessarily need specific mongodb-instructions, but some guidelines on how to write into a remote db with monologger. The mongodb-specific instructions are also welcome if available. ;)
Question 3(OPTIONAL):
Can I get a full error stack into the logs somehow? Where could one find a full list of what data the Monolog can actually write and how to write?
There was a very good Blogpost sometime back for logging to a mysql database with monolog and doctrine. I can't find it anymore so i will just add the neccessary Files here and you can adjust it.
The whole logic is done in the DatabaseHandler so you can just change from
mysql inserts to a handling for your mongodb.
This code is not mine if anyone knows the original post please comment.
BacktraceLoggerListener.php
namespace UtilsBundle\EventListener;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
class BacktraceLoggerListener{
private $_logger;
public function __construct(LoggerInterface $logger = null)
{
$this->_logger = $logger;
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$this->_logger->addError($event->getException());
}
}
DatabaseHandler.php
namespace UtilsBundle\Logger;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
/**
* Stores to database
*
*/
class DatabaseHandler extends AbstractProcessingHandler{
protected $_container;
/**
* #param string $stream
* #param integer $level The minimum logging level at which this handler will be triggered
* #param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
*/
public function __construct($level = Logger::DEBUG, $bubble = true)
{
parent::__construct($level, $bubble);
}
/**
*
* #param type $container
*/
public function setContainer($container)
{
$this->_container = $container;
}
/**
* {#inheritdoc}
*/
protected function write(array $record)
{
// Ensure the doctrine channel is ignored (unless its greater than a warning error), otherwise you will create an infinite loop, as doctrine like to log.. a lot..
if( 'doctrine' == $record['channel'] ) {
if( (int)$record['level'] >= Logger::WARNING ) {
error_log($record['message']);
}
return;
}
// Only log errors greater than a warning
// TODO - you could ideally add this into configuration variable
if( (int)$record['level'] >= Logger::NOTICE ) {
try
{
// Logs are inserted as separate SQL statements, separate to the current transactions that may exist within the entity manager.
$em = $this->_container->get('doctrine')->getManager();
$conn = $em->getConnection();
$created = date('Y-m-d H:i:s');
$serverData = ""; //$record['extra']['server_data'];
$referer = "";
if (isset($_SERVER['HTTP_REFERER'])){
$referer= $_SERVER['HTTP_REFERER'];
}
$stmt = $em->getConnection()->prepare('INSERT INTO system_log(log, level, server_data, modified, created)
VALUES(' . $conn->quote($record['message']) . ', \'' . $record['level'] . '\', ' . $conn->quote($referer) . ', \'' . $created . '\', \'' . $created . '\');');
$stmt->execute();
} catch( \Exception $e ) {
// Fallback to just writing to php error logs if something really bad happens
error_log($record['message']);
error_log($e->getMessage());
}
}
}
}
We used xml here but this can be done in
services.yml too
services.xml
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="utils.database.logger" class="UtilsBundle\Logger\DatabaseHandler">
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
<service id="utils.backtrace.logger.listener" class="UtilsBundle\EventListener\BacktraceLoggerListener">
<argument type="service" id="logger" />
<tag name="monolog.logger" channel="backtrace" />
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" />
</service>
</services>
And lastly add the handler to your monolog config in
config_**.yml so here for production for example
config_prod.yml
monolog:
handlers:
main:
type: rotating_file
action_level: error
max_files: 10
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
database:
type: service
level: notice
id: utils.database.logger
channels: ["!translation"]
Hope that helps
Hope I can some things up for you:
Question 1: Yes its possible. E.G. you can do smt. like:
$this->logger->pushHandler(new StreamHandler('/path/to/logs/123_info.log', Logger::INFO));
$this->logger->pushHandler(new StreamHandler('/path/to/logs/456_warning.log', Logger::INFO));
So if $this->logger->addInfo("testinfo"); this is getting logged in both streams.
Question 2: There is a MongoDBHandler as according to the StreamHandler. You should be able do configure it and pass it along to the pushHandler method or if you want to have it in your services look at MongoDBConfiguration.
Question 3:
This should help: Configure Monolog
Hope that helps.
I am following a tutorial about joomla 3 extension development. I am using Joomla 3.2.4
I have a plugin name clicktocall, which to make all phone number text displayed as a link.
Phone number format is XXXX-XXXX or XXXX XXXX, X is digit. and I want display any phone number as ">
The method is using pattern as replace any text match the pattern by link tag
I installed, enabled the plugin
I do it after a tutorial in an ebook, in the book everything are so smoothly, but in my site, after I view an article which have phone number text, there are nothing happen. The plugin not working.
My code:
clicktocall.php
defined('_JEXEC') or die;
jimport('joomla.plugin.plugin');
class plgContentClicktocall extends JPlugin {
function plgContentClicktocall(&$subject, $params) {
parent::__construct($subject, $params);
}
public function onContentPrepare($context, &$row, &$params, $page = 0) {
//don't run this when the content is indexing
if ($context == 'com_finder.indexer') {
return true;
}
if (is_object($row)) {
echo $row->text;
return $this->clickToCall($row->text, $params);
}
return $this->clickToCall($row, $params);
}
protected function clickToCall(&$text, &$params) {
// matches 4 numbers followed by an optional hyphen or space,
// then followed by 4 numbers.
// phone number is in the form XXXX-XXXX or XXXX XXXX
$pattern = '/(\W[0-9]{4})-? ?(\W[0-9]{4})/';
$replacement = '$1$2';
$text = preg_replace($pattern, $replacement, $text);
return true;
}
}
clicktocall.xml
<?xml version="1.0" encoding="UTF-8"?>
<extension
version="3.0"
type="plugin"
group="content"
method="upgrade">
<name>Content - Click To Call</name>
<author>Tim Plummer</author>
<creationDate>April 2013</creationDate>
<copyright>Copyright (C) 2013 Packt Publishing. All rights
reserved.</copyright>
<license> http://www.gnu.org/licenses/gpl-3.0.html</license>
<authorEmail>example#packtpub.com</authorEmail>
<authorUrl>http://packtpub.com</authorUrl>
<version>1.0.0</version>
<description>This plugin will replace phone numbers with click
to call links. Requires Joomla! 3.0 or greater.
Don't forget to publish this plugin!
</description>
<files>
<filename plugin="clicktocall">clicktocall.php</filename>
<filename>index.html</filename>
</files>
</extension>
index.html : blank tags only
Sorry for the XML, I try for 10 minutes to make it pre-formatted but seem to be useless, but I confirm it's OK, included all files in my plugin
I believe the issue is you are returning the value from your click2Call() method inside your onContentPrepare() method. Try reformatting like so:
public function onContentPrepare($context, &$row, &$params, $page = 0) {
//don't run this when the content is indexing
if ($context == 'com_finder.indexer') {
return true;
}
if (is_object($row)) {
echo $row->text;
$this->clickToCall($row->text, $params);
} else {
$this->clickToCall($row, $params);
}
return true;
}
Since the row variable is referenced, any changes you make to the row data you're making to the actual data. Therefor, no need to return any data outside of the the return true at the end of the method.
I am using Mantis Bug Tracker SOAP API, but unfortunately every time it returns to me message like
"looks like we got no XML document",
after tracing the last response I got following message
"<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body><SOAP-ENV:Fault><faultcode xsi:type="xsd:string">Client</faultcode><faultactor xsi:type="xsd:string"></faultactor><faultstring xsi:type="xsd:string">Issue does not exist.</faultstring><detail xsi:type="xsd:string"></detail></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>"
I hope that, I am getting xml respose back, it appears that there is a addition of "" characters in the beginning.
Any clue or help would be great, in removing those characters.
The code for connecting to MANTIS SOAP API SERVER
<?php
$c = new \SoapClient("http://dev06/api/soap/mantisconnect.php?wsdl", array('trace'=> true, 'encoding'=>' UTF-8', 'soap_version'=>1.2));
$username = "xxxxx";
$password = "xxxxx";
try {
$c->mc_issue_get(trim($username), trim($password), 2331);
} catch (SoapFault $exception) {
var_dump($c->__getLastResponse());
}
?>
I don't see any issue with your code and it works perfectly in my environment with slight modifications:
$c = new \SoapClient("http://localhost/demo/mantisbt-1.2.15/api/soap/mantisconnect.php?wsdl", array('trace'=> true, 'encoding'=>' UTF-8', 'soap_version'=>SOAP_1_2));
$username = "XXXXXXXX";
$password = "XXXX";
try {
$issue = $c->mc_issue_get(trim($username), trim($password), 31);
var_dump($issue);
} catch (SoapFault $exception) {
var_dump($c->__getLastResponse());
}
It could be the soap_version, so may be you could try with soap_version=SOAP_1_1
Oh...!
Finally got the solution for it. Its very simple.
Firstly mantis SOAP API code base contains may be more than 20,000 lines of code. I think there is some where some one is printing some BOM characters.
So best solution would be, just use following function,
ob_clean();
This function must be used in
/library/nusoap/nusoap.php
Because this file has
send_response()
That printouts payload, So just use ob_clean() at the beginning of the send_response() function.
Thanks and hope it will help others.
i have navigation menu which is displayed to users based on certain action of the controller. here is what i am doing.
//in each controller-action where i want "action navigation menu"
public function indexAction()
{
$this->_helper->navigation()->renderActionNavigation();
}
public function newAction()
{
$this->_helper->navigation()->renderActionNavigation();
}
the navigation menu is displayed accordingly. here is my navigation.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<configdata>
<item-index>
<new-item>
<label>New Item</label>
<route>admin-item-new</route>
</new-item>
<delete-item>
<label>Delete Item</label>
<uri>#</uri>
</delete-item>
</item-index>
<item-new>
<publish-unpublish-item>
<label>Save & Close</label>
<uri>#</uri>
</publish-unpublish-item>
<delete-item>
<label>Save & New</label>
<uri>#</uri>
</delete-item>
</item-new>
</configdata>
the parent element of each navigation menu represents a naming convention in the above navigation.xml file for example
`<item-index>` represents item{controller}index{action}
`<item-new>` represents item{controller}new{action}
//and so on
here is the action helper. Navigation.php i am using
class Zend_Controller_Action_Helper_Navigation extends Zend_Controller_Action_Helper_Abstract
{
private $_view = null;
public function direct()
{
$this->_view = Zend_Layout::getMvcInstance()->getView();
$this->_view->placeholder('action-navigation');
return $this;
}
public function renderActionNavigation()
{
$config = new Zend_Config_Xml(
APPLICATION_PATH.'/configs/navigation.xml', strtolower(
$this->getRequest()->getControllerName().'-'.
$this->getRequest()->getActionName()
)
);
$container = new Zend_Navigation($config);
$this->_view->partial('partials/_action-navigation.phtml', array('container' => $container));
}
}
and finally _action-navigation.phtml
<?php $this->placeholder('action-navigation')->captureStart(); ?>
<div class="statsRow">
<div class="wrapper" >
<?php foreach($this->container as $page): ?>
<?php endforeach; ?>
</div>
</div>
<?php $this->placeholder('action-navigation')->captureEnd(); ?>
My directory structure is as follows
/application
/layouts
admin.phtml
default.phtml
/modules
/admin
/controllers
/helpers
/Navigation.php
IndexController.php
/views
/helpers
/scripts
/partials
_action-navigation.pthml
sidebar.phtml
/index
/item
the weird behavior i am experiencing is. in my Bootstrap.php file there is an empty _initView() method. my application works properly if this method exist. note that this method is empty. but when i remove it it gives me following error.
Application error
Exception information:
Message: script 'partials/_action-navigation.phtml' not found in path (./views/scripts/)
i am not able to understand this behavior by Zend Framework. how is action-navigation code related to _initView method in Bootstrap? what is happening and any fix for this or any suggestion for improvement of my code?
Update:
The problem lies with this line of code
$this->_view->partial('partials/_action-navigation.phtml', array('container' => $container));
You forgot to add the name of the admin module as second argument:
$this->_view->partial('partials/_action-navigation.phtml', 'admin', array('container' => $container));
I Suggest you use this clean and lightweight way, removing your dependence to inform actual module and mantaining your view script clean without captureStart and End (it's used ob_start... when u do captureStart-end)
$navigation = $this->view->navigation()->menu()->renderPartial($container, 'partials/_action-navigation.phtml');
// U can use placeholders `append` and `prepend` methods too, if u need more control in your placeholder content
$this->view->placeholder('action-navigation')->set($navigation);
I have a legacy application where an email.cfm file is used with a cfmail tag to send e-mail:
<cfmail from="abc#123.com" to="def#456.com" subject="New e-mail!">
// lots of HTML
</cfmail>
Now I'd like to update it for ColdFusion Model Glue 3. I want to send it using a mail object in the controller, and include in the body a CFM page:
var mail = new mail();
mail.setFrom("abc#123.com");
mail.setTo("def#456.com");
mail.setSubject("New e-mail!");
mail.setBody( ** SOME CFM FILE ** );
mail.send();
Does anybody have any idea how I can do this?
You can render the content you want to email in a cfsavecontent block and then use that in the email, like:
<cfsavecontent variable="myemail">
...add some HTML, include another file, whatever...
</cfsavecontent>
<cfscript>
mail.setBody( myemail );
</cfscript>
See http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d57.html
Call the CFC assigning it to a variable, like cfset request.emaiBody = cfc.function(). Then just put it in your setBody tag.
OP was convinced to use CFML, but to answer the question as it was initially asked:
var mail = new Mail();
mail.setFrom("abc#123.com");
mail.setTo("def#456.com");
mail.setSubject("New e-mail!");
mail.setType("html");
savecontent variable="mailBody" {
include "email.cfm";
}
mail.setBody(mailBody);
mail.send();
I ended up following Henry's advice in the comments and created a CFML-based CFC:
<cfcomponent>
<cffunction name="SendMail">
<cfargument name="from"/>
<cfargument name="to"/>
<cfargument name="subject"/>
<cfmail from="#from#" to="#to#" subject="#subject#">
<!--- HTML for e-mail body here --->
</cfmail>
</cffunction>
</cfcomponent>
Dave Long's suggestion is also good, which is to create components using <cfcomponent>, then wrapping the code in <cfscript> tags. This gives you the ability to fall back to CFML in case the there is no cfscript equivalent or it's easier to do with CFML:
<cfcomponent>
<cfscript>
void function GetData()
{
RunDbQuery();
}
</cfscript>
<cffunction name="RunDbQuery">
<cfquery name="data">
SELECT * FROM ABC;
</cfquery>
<cfreturn data>
</cffunction>
</cfcomponent>