Zend Framework configuring decorator - zend-framework

if(count($this->form->email->getMessages()) > 0)
{
$e = '<ul>';
$m = $this->form->email->getMessages();
foreach($m as $me)
{
$e .= '<li>';
$e .= $me;
$e .= '</li>';
}
$e .= '</ul>';
echo $e;
unset($e);
unset($m);
}
I'm currenly passing form object to VIEW and echo every elemen manually.
But when comes to errors, it takes a lot of code to write.
Could someone tell, how to output errors for each element without such amount of code?
Thanks!
Here is the picture of all decorators before the output:

Found amazing method:
renderFormErrors();
Just what i was looking for. :)
But for individual outputing, can be used decorator. Found on this forum.

this is impossible since to havent provided your current decorator. However, you should add the helper
Errors
to the decorator.

Related

Sending a mail with a dynamic table from perl script

I have the following code in Perl:
foreach my $result ( #results ) {
if ( $result->{Error} ) {
print"No response received \n";}
else {
my $H = "$result->{H}";
my $I = "$result->{I}";
$mailbody.=qq(<h4 style="background: blue; color: white;">$H--->$I</h4>);
}
}
Here, I am using Mime::Lite to send mails:
$msg = MIME::Lite->new(
From => $from,
To => $to,
Cc => $cc,
Subject => $subject,
Data => $mailbody
);
$msg->attr("content-type" => "text/html/css");
$msg->send;
What I want is that the result data i.e $H and $I to be represented in the form of a table in the mail.
H | I
1 | 46
2 | 565756756767
3 | 232132
The number of rows of the table are dynamic and depend on the input given by the user. How can I do this?
If you want it to be a table in the email, you should create a table in the email body something like this:
$mailbody . = '<table>';
foreach my $result ( #results ) {
if ( $result->{Error} ) {
print"No response received \n";}
else {
my $H = "$result->{H}";
my $I = "$result->{I}";
$mailbody.=qq(<tr><td>$H</td><td>$I</td></tr>);
}
}
$mailbody . = '</table>';
If you want an HTML table in your email, then add HTML table elements to your output.
# Note: border=1 attribute to make the table borders visible.
$mailbody .= '<table border="1">';
foreach my $result ( #results ) {
if ( $result->{Error} ) {
print"No response received \n";}
else {
$mailbody .= qq(<tr><td>$result->{H}</td>)
. qq(<td>$result->{I}</td></tr>);
}
}
$mailbody .= </table>
In a comment to another answer that suggested something similar, you said that this doesn't work because you can't see the table borders. That was, of course, a simple case of adding border=1 so that the borders are displayed.
However.
It's always worth repeating that putting raw HTML strings into your program code is a terrible idea. It's a recipe for an unmaintainable mess. It's a bad idea when creating web applications and it's a bad idea when creating HTML to go into email bodies.
Far better to separate the code from creating the output and the best way to do that is to use a templating engine like the Template Toolkit. By creating a template file that contains all of the HTML output, you make it easier to change the way that the HTML looks without getting bogged down in the Perl code.
Also (and I've suggested this to you before) I would suggest that you avoid using MIME::Lite. But don't take my word for it. The current documentation for the module says this:
MIME::Lite is not recommended by its current maintainer. There are a number of alternatives, like Email::MIME or MIME::Entity and Email::Sender, which you should probably use instead. MIME::Lite continues to accrue weird bug reports, and it is not receiving a large amount of refactoring due to the availability of better alternatives. Please consider using something else.
I recommend switching to Email::Sender (together with Email::MIME) or Email::Stuffer.

HTML parsing with HTML::TokeParser::Simple

I am parsing an HTML file with HTML::TokeParser::Simple. The HTML file has the content shown far below. My problem is, I am trying to ignore the JavaScript from showing up as text content. Example:
use HTML::TokeParser::Simple;
my $p = HTML::TokeParser::Simple->new( 'test.html' );
while ( my $token = $p->get_token ) {
next unless $token->is_text;
print $token->as_is, "\n";
}
This prints the output as seen below:
Test HTML
<!--
var form_submitted = 0;
function submit_form() {
[..]
}
//-->
The actual HTML Document Content:
<html>
<span>Test HTML</span>
<script type="text/javascript">
<!--
var form_submitted = 0;
function submit_form() {
[..]
}
//-->
</script>
</html>
How do I ignore the JavaScript tag contents from showing.
I get the desired result. Comments are (correctly) not considered text by the version I have. Looks like you need to upgrade the modules you are using. (I used HTML::Parser 3.69 and HTML::TokeParser::Simple 3.15.)
>perl a.pl
Test HTML
>
You'll still have to process HTML entities and format the text usefully, the latter being quite difficult since you removed all formatting instruction. Your approach seems fatally flawed.
I believe you only need to use the as_text method.
my $tree = HTML::TreeBuilder->new();
$tree->parse( $html );
$tree->eof();
$tree->elementify(); # just for safety
my $text = $tree->as_text();
$tree->delete;
I adapted this from the WWW::Mechanize module (http://search.cpan.org/dist/WWW-Mechanize/) which has tons of convenience methods that can help you. It basically acts as a web browser in an object.
Scan through the token to ignore all open and close script tags. See below as used to resolved the issue.
my $ignore=0;
while ( my $token = $p->get_token ) {
if ( $token->is_start_tag('script') ) {
print $token->as_is, "\n";
$ignore = 1;
next;
}
if ( $token->is_end_tag('script') ) {
$ignore = 0;
print $token->as_is, "\n";
next;
}
if ($ignore) {
#Everything inside the script tag. Here you can ignore or print as is
print $token->as_is, "\n";
}
else
{
#Everything excluding scripts falls here handle as appropriate
next unless $token->is_text;
print $token->as_is, "\n";
}
}

Zend_Navigation rendering submenu with partial

I've posted an edit to my question. While working on it I noticed the problem is easy to simplify.
I need a custom format of my submenu so i have to use partial. But then the problem occurs.
The below code shows the INCORRECT level (0):
echo $this->navigation()->menu()
->setMinDepth(1)
->setMaxDepth(1)
->setRenderParents(false)
->setOnlyActiveBranch(true)
->renderPartial(null, array('partials/menu.phtml', 'default'));
The below code shows the CORRECT menu level (1)
echo $this->navigation()->menu()
->setMinDepth(1)
->setMaxDepth(1)
->setRenderParents(false)
->setOnlyActiveBranch(true)
->render();
Any ideas? Guys please. I would appreciate any help!
Edit
My partials/menu.phtml:
foreach ($this->container as $page)
{
$active = $page->isActive();
echo '<div class="item">';
echo '<a class="'. ($active ? 'active' : '') .'" href="' . $this->baseUrl($page->getHref()) . '">' . $page->getLabel() . '</a>';
echo '</div>';
}
EDIT 2
My understanding of Zend_Navigation was, first to prepare container and than put it through partial.
$nav = $this->navigation()->menu()->setOnlyActiveBranch(true)->getContainer();
echo $this->navigation()->menu()->renderPartial($nav, array('/partials/menu.phtml', 'default'));
What is the point of setting set{Min/Max}Depth, parentRendering at the container when passing it anywehere is useless?
I use this code:
<?=$this->navigation()->menu()->renderPartial(null, 'shared/menu.phtml')?>
you should pass true to the method $page->isActive(true) so that also functions in depth.
in your partial
foreach ($this->container as $page) {
$active = $page->isActive(true);
if (count($page->getPages())) {
foreach ($page->getPages() as $subPage) {
$active = $subPage->isActive(true);
echo '<div class="item">';
echo '<a class="'. ($active ? 'active' : '') .'" href="' . $this->baseUrl($subPage->getHref()) . '">' . $subPage->getLabel() . '</a>';
echo '</div>';
}
}
}
before the second foreach you could add a check if and when to show the submenu.
my 2 cent.
EDIT
try this:
$partial = array('partials/menu.phtml', 'default');
echo $this->navigation()->menu()
->setMinDepth(1)
->setMaxDepth(1)
->setRenderParents(false)
->setOnlyActiveBranch(true)
->setPartial($partial)
->render();
Came across this while searching for an answer to the same problem. Having looked through the code for Zend_View_Helper_Navigation_Menu, it doesn't look like any of the view helper options are passed through to the view partial, although I don't see why they couldn't be... (in ZF 1.12 take look a line 736 of Zend_View_Helper_Navigation_Menu, the only thing passed is the container itself, the options array could easily be passed along with it, or the container prefiltered, may be worth filing a feature request with ZF)
These options are purely a way of filtering the Zend_Navigation_Container for rendering with the default renderMenu method. As you say, it seems you can accomplish the same thing by first filtering the container and then passing it as the first argument of the renderPartial method
In your main view
Find the container of the submenu located in navigation config. Then echo this container using said partial.
$pages = $this->navigation()->findOneBy('label', 'Label of your submenu');
echo $this->navigation()->menu()->renderPartial($pages,module/partials/menu.phtml');
In the partial (module/partials/menu.phtml)
Customise. This example iterates over the top level pages of your chosen container.
foreach ($this->container as $page) {
echo $this->navigation()->menu()->htmlify($page) . PHP_EOL;
}

CodeIgniter: Cannot redirect after $this->email->send()

i have the following code which sends an email from a posted form:
$this->load->library('email');
$config['charset'] = 'iso-8859-1';
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from('info#mysite.com', 'Scarabee');
$this->email->to('info#mysite.com');
$this->email->subject('Message via website');
$data['msg'] = nl2br($this->input->post('msg'));
$data['msg'] .= '<br><br><b>Verstuurd door:</b><br>';
if($this->input->post('bedrijf')){
$data['msg'] .= $this->input->post('bedrijf').'<br>';
}
$data['msg'] .= $this->input->post('naam').'<br>';
$data['msg'] .= $this->input->post('adres').' - '.$this->input->post('postcode').', '.$this->input->post('gemeente').'<br>';
$data['msg'] .= $this->input->post('tel').'<br>';
$data['msg'] .= $this->input->post('email');
$message = $this->load->view('email', $data, TRUE);
$this->email->message($message);
if($this->email->send()){
$success = 'Message has been sent';
$this->session->set_flashdata('msg', $success);
redirect('contact/'.$this->input->post('lang'));
}
else{
show_error('Email could not be sent.');
}
Problem: the email gets sent with proper formatting (from the email view template), but the page then goes blank. For instance, if I try to echo out $message just below the $this->email->send() call, nothing shows up. Redirecting, as I’m attempting above, obviously doesn’t work either. Am I missing something? Thanks for any help…
Update
Traced the problem down to a function inside /system/libraries/Email.php (CI's default email library). Commenting out the code inside this function allows the mail to get sent, as well as a proper redirect:
protected function _set_error_message($msg, $val = '')
{
$CI =& get_instance();
$CI->lang->load('email');
if (substr($msg, 0, 5) != 'lang:' || FALSE === ($line = $CI->lang->line(substr($msg, 5))))
{
$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
}
else
{
$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
}
}
The line that caused the error is: $CI->lang->load('email');
Go figure...
UPDATE 2: SOLVED
I had this in my controller's construct:
function __construct() {
parent::__construct();
$this->lang = $this->uri->segment(2, 'nl');
}
I guess there was a conflict between $this->lang and the _set_error_message function which also returns a "lang" variable (see var_dump further down).
Solution: changed $this->lang to $this->language, and everything's hunky dory!
Thought I'd post the answer here in case anyone else is ever losing hair with a similar problem :-)
It's likely that an error is occurring when you attempt to send an e-mail which is then killing your script during execution. Check your apache and PHP error logs ( /var/log/apache/ ) and enable full error reporting.
You could, for debugging purposes, try doing this:
...
$this->email->message($message);
$this->email->send();
redirect('contact/'.$this->input->post('lang'));
This should redirect you, regardless of your mail being sent or not (if you still recieve it, you can assume that the redirect would be the next thing that happens).
My own solution looks like this:
...
if ( $this->email->send() )
{
log_message('debug', 'mail library sent mail');
redirect('contact/thankyou');
exit;
}
log_message('error', 'mail library failed to send');
show_error('E-mail could not be send');
$ref2 = $this->input->server('HTTP_REFERER', TRUE);
redirect($ref);
By using the above code you can redirect to the current page itself
and you can set your flash message above the redirect function.

Mojolicious wildcard placeholders and question mark

The wildcard placeholder (*) is said to match absolutely everything.
But I'm afraid that it doesn't...
I have a webservice with the following method:
get '/*param' => sub {
my $self = shift;
my $param = $self->stash('param');
$self->app->log->debug($param);
}
When i query my service with: http://localhost:3000/search
then the method logs "search" which is ok
but
when i query my service with: http://localhost:3000/search?page=1
then the method also logs "search" which is not ok IMO
I also tried replacing
get '/*param' => sub {
with
get '/:param' => [param => qr/.*/] => sub {
but the result is the same.
Does anybody know of a way around this?
Or should I file this as a bug?
Regards,
Lorenzo
UPDATE
for people with the same problem, I've worked around this issue like this:
get '/*path' => sub {
my $self = shift;
my $path = $self->stash('path');
my #params = $self->param;
if (scalar #params > 0) {
$path .= '?';
foreach my $param (#params) {
$path .= $param . '=' . $self->param($param) . '&';
}
$path = substr($path, 0, length($path) - 1);
}
$self->app->log->debug($path);
}
?page= its not url.
Its param.
So no any bugs here.
you have 'search' in $param.
And $page=1 in stash.
I think Korjavin is right, that's expected behavior. Looks like "page=1" as a parameter and should be in $stash->param('page'). See GET-POST-parameters in ::Lite
If it does not work, maybe renaming the "param" placeholder to something else helps? Maybe it's a name-clash.
The request parameters wouldn't be in the stash.
They're in
$self->req->params
So
my $params = $self->req->params->to_hash;
$self->app->log->debug(Dumper $params);
Should allow you to see the information you're after