Zend_Mail: moveMessage() exception - email

According to the documentation, you should use the getNumberByUniqueId() method to retrieve the message ID when moving/deleting emails. However, I still seem to get an exception appearing part way through processing a folder: "the single id was not found in response".
The code that is used goes along the lines of:
try {
$emailAddresses = array ();
$invalidAddresses = array ();
$errors = array();
$emailValidator = new Zend_Validate_EmailAddress ();
$trimFilter = new Zend_Filter_StringTrim ();
$mail = new Zend_Mail_Storage_Imap (...);
$mail->selectFolder ( '/Unsubscribe' );
echo 'There are ' . $mail->countMessages () . " messages to process\n";
foreach ( $mail as $messageId => $message ) {
try {
$mail->noop ();
$recipientMatch = $trimFilter->filter ( str_ireplace ( 'REMOVE ', '', $message->subject ) );
if (! substr_count ( $recipientMatch, '#' )) {
// Try the sender if the subject line doesn't have an address in
$matches = array ();
$from = $message->getHeader ( 'from' );
preg_match ( '/<(.+#.+)>/', $from, $matches );
if (sizeof ( $matches ) == 2) {
$recipientMatch = $matches [1];
} else {
$recipientMatch = $from;
}
}
if (! $emailValidator->isValid ( $recipientMatch )) {
$invalidAddresses [] = $recipientMatch;
continue;
}
$emailAddresses [] = $recipientMatch;
$messageUniqueId = $mail->getUniqueId ( $messageId );
$mail->moveMessage ( $mail->getNumberByUniqueId ( $messageUniqueId ), '/Unsubscribe/done' );
} catch ( Exception $e ) {
$errors[] = array($recipientMatch , $e);
}
}
} catch ( Zend_Mail_Storage_Exception $e ) {
echo "There was a problem processing the mail account\n", $e->getMessage ();
} catch ( Exception $e ) {
echo "There was an unmatched exception\n", $e->getMessage ();
}
Any ideas why the exception is being thrown (Zend Framework v1.10.8)?
The stack trace for the exception is:
#0 /usr/share/php/libzend-framework-php/Zend/Mail/Storage/Imap.php(163): Zend_Mail_Protocol_Imap->fetch(Array, 4)
#1 /usr/share/php/libzend-framework-php/Zend/Mail/Storage/Abstract.php(307): Zend_Mail_Storage_Imap->getMessage(4)
#2 /tmp/unsubscribe.php(29): Zend_Mail_Storage_Abstract->current()
#3 /tmp/dummy.php(1): include('/tmp/unsubscribe.php')
#4 {main}
The content of the Array used in Zend_Mail_Protocol_Imap->fetch() is:
Array(
0 => 'FLAGS',
1 => 'RFC822.HEADER'
)

You sholud not use this kind of loop. With this loop $messageId is outdated as soon as you delete a single message. With the next cycle the $messageId would 'point' to the wrong message or even no message (like Index-Out-Of-Bounce). That's why you've got the error message.
Solution: collect all relevant unique ids first into an array, then loop through this array and call moveMessage - with the up-to-date id that you get from getNumberByUniqueId!
I hope I'm not wrong, but I think moveMessage($id, $folder) should be moveMessage($index, $folder). This is more accurate. But correct me if this is wrong.

as it mentioned before... in case if you've got an error: "the single id was not found in response" means that the message sequence changed in expunge process, so when you save all IDs of all messages and try to iterate you have this error, because some messages was deleted in previous, please check: http://framework.zend.com/issues/browse/ZF-5655
You can use "while" for get ACTUAL collection of ids on every iteration, like this:
while($next_id = $gmail->getUniqueId()) {
// move message to label folder "My_archive_folder"
$gmail->moveMessage($next_id, 'My_archive_folder');
}

Related

How do I attach a pdf file to a Gravity Forms Notification?

Gravity forms offers a way to attach files from the file uploader (See code below), but how would I change this code to simply attach my own PDF file from either a hidden field value or simply paste the pdf file within this code? I tried a few things but it didn't work. Any help would be appreciated!
add_filter( 'gform_notification', 'change_user_notification_attachments', 10, 3 );
function change_user_notification_attachments( $notification, $form, $entry ) {
//There is no concept of user notifications anymore, so we will need to target notifications based on other criteria, such as name
if ( $notification['name'] == 'User Notification' ) {
$fileupload_fields = GFCommon::get_fields_by_type( $form, array( 'fileupload' ) );
if(!is_array($fileupload_fields))
return $notification;
$attachments = array();
$upload_root = RGFormsModel::get_upload_root();
foreach( $fileupload_fields as $field ) {
$url = $entry[ $field['id'] ];
$attachment = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $url );
if ( $attachment ) {
$attachments[] = $attachment;
}
}
$notification['attachments'] = $attachments;
}
return $notification;
}
Based on that code, something like this should work. Replace the $url value with the URL to your PDF.
add_filter( 'gform_notification', 'change_user_notification_attachments', 10, 3 );
function change_user_notification_attachments( $notification, $form, $entry ) {
if ( $notification['name'] == 'User Notification' ) {
$url = 'http://yoursite.com/path/to/file.pdf';
$notification['attachments'][] = $url;
}
return $notification;
}

Why is the server returned the result for a different submit than selected by perl HTML::Form and LWP::UserAgent?

I want to process a number of files with http://2struc.cryst.bbk.ac.uk/twostruc; to automate this I wrote a perl script using perl's HTML::Form.
This server has a two step submit process: first, upload a file or enter an id; second, select the methods to be used and the output (by chosing one of five submits).
The first step works, but for the second step I seem to be unable to chose any submit button other than the first, even though my script output confirms that I selected the one I want (different from the first).
The two core parts of the code are below, the request function:
sub create_submit_request
{
my $form_arrayref = shift;
my $form_action = shift;
my $value_hashref = shift;
my $submit_name = shift;
my $submit_index = shift;
my $found_form = 0;
my $form;
foreach my $this_form( #$form_arrayref)
{
printf( "# Found form with action=%s\n", $this_form->action);
if( $this_form->action eq $form_action)
{
$found_form = 1;
$form = $this_form;
}
}
die( "# Error: No form with action $form_action") if( $found_form == 0);
my #inputs = $form->inputs;
my $inputs_string;
foreach my $input( #inputs)
{
my $input_name = defined( $input->name) ? $input->name : "<unnamed_input>";
my $input_value = defined( $input->value) ? $input->value : "";
$inputs_string .= $input_name.( length( $input_value) > 0 ? "=".$input_value : "")." (".$input->type."); ";
}
printf( "# Available input names: %s\n", $inputs_string);
printf( "# Filling in form data\n");
while( my( $key, $value) = each( %$value_hashref))
{
$form->value( $key, $value);
}
my #submit_buttons = $form->find_input( $submit_name, "submit", $submit_index); # 1-based counting for the index
die( "# Error: Can only handle a single submit, but found ".scalar( #submit_buttons)) if( scalar( #submit_buttons) != 1);
my %submit_hash = %{ $submit_buttons[ 0]};
# DEBUG
printf( "# Use submit: %s\n", Data::Dumper->Dump( [ \%submit_hash ]));
return $form->click( %submit_hash);
}
and the code using it:
my $request = HTTP::Request->new( GET => $url_server);
my $response = $useragent->request( $request);
# the first page contains the pdb id input and file upload inputs
my #forms = HTML::Form->parse( $response);
my %value_hash = ( "file" => $pdb_file);
# the submit buttons have no name, use undef; chose the first one (w/o javascript)
$request = create_submit_request( \#forms, $form_action1, \%value_hash, undef, 1);
printf( "# Submitting to server\n");
$response = $useragent->request( $request);
# the first page contains the pdb id input and file upload inputs
#forms = HTML::Form->parse( $response);
%value_hash =( "dsspcont" => "on", "stride" => "on");
# this form has 5 submit buttons; select the 5th
$request = create_submit_request( \#forms, $form_action2, \%value_hash, undef, 5);
printf( "# Submitting to server\n");
$response = $useragent->request( $request);
my $response_content = $response->content;
printf( "# Response content: %s\n", $response_content);
Even though the script prints
# Use submit: $VAR1 = {
'name' => 'function_sequenceStructureAlignment',
'onclick' => 'this.form.target=\'_blank\';return true;',
'type' => 'submit',
'value' => 'Sequence Structure Alignments',
'value_name' => ''
};
which is the 5th submit button in the second step, the response is equivalent to pressing the first submit button.
To test the server itself, the file 1UBI.pdb can be downloaded from http://www.rcsb.org/pdb/files/1UBI.pdb and uploaded to the server. The full script is at http://pastebin.com/bSJLvNfc and can be run with
perl 2struc.pl --pdb 1UBI.pdb
Why is the server returning a different output/submit that I seem to select in the script?
(It seems it's not dependend on cookies, because I can clear them after the first step, and still get the correct result for the second step in a web browser.)
You gave a hash as selector for click, which is wrong (see documentation how to specify the selector). But because you have already found the correct submit element you could simply call click directly on it:
--- orig.pl
+++ fixed.pl
## -87,7 +87,7 ##
# DEBUG
printf( "# Use submit: %s\n", Data::Dumper->Dump( [ \%submit_hash ]));
- return $form->click( %submit_hash);
+ return $submit_buttons[0]->click($form);
}
sub predict_pdb

Perl Hypertable mutator exception

I am using Hypertable::ThriftClient, and using mutator for mass insertion. Here is the code sample: $master, $port and $namespace are all defined.
Table:
show create table users; # Table schema is below
CREATE TABLE GROUP_COMMIT_INTERVAL "100" users (
'column_name_fake' MAX_VERSIONS 1,
ACCESS GROUP audience ('column_name_fake'),
)
:hypertable$ SELECT * FROM users limit 1; # displays
2342345 sf_following:1000234
2342346 sf_following:1234234
Code:
my $ht = new Hypertable::ThriftClient($master, $port);
my $ns = $ht->namespace_open($namespace);
my $users_mutator = $ht->mutator_open($ns, 'table_name', 2);
Subroutine:
sub batch_insert {
my ($ht, $mutator, $column_family, $row, $val) = #_;
my $keys;
my $cell;
try {
$keys = new Hypertable::ThriftGen::Key({
row => $row,
column_family => $column_family });
$cell = new Hypertable::ThriftGen::Cell({key => $keys, value => $val});
}
catch {
warn Dumper({ 'Error' => $_ });
};
$ht->mutator_set_cell($mutator, $cell);
$ht->mutator_flush($mutator);
return 1;
}
Function called:
for(.....) { # Just for example
batch_insert($ht, $users_mutator, '', $fs, "node:$node_u");
}
Here I get an exception,
Hypertable::ThriftGen::ClientException=HASH(0x54d7380)
Can anyone clarify, why?
Edit: I added table structure for more clarity?
The ClientException class is defined as follows:
exception ClientException {
1: i32 code
2: string message
}
Try catching the exception and printing out the code (in hex) and message. That should help pinpoint what's going on.
FIX: So, this exception is raised is a required parameter 'column_qualifier' was not
passed as per the table design. See below:
sub batch_insert {
my ($ht, $mutator, $cf, $cq, $row, $val) = #_;
my $keys = new Hypertable::ThriftGen::Key({
row => $row,
column_family => $cf,
column_qualifier => $cq });
my $cell = new Hypertable::ThriftGen::Cell({key => $keys, value => $val});
$ht->mutator_set_cell($mutator, $cell);
#$ht->mutator_flush($mutator);
}
Calling the above function:
--------------------------
batch_insert($ht, $users_mutator, 'column_family' , 'column_qualifier, 'row_key', '');
and it worked like a charm. If you are in similar types of issues, Let me know, I can help out. I spent quite a bit of time, reading about the Thrift api.

How do I return a value if the prepare statement fails in the below code?

sub loadFileRecon {
my $self = shift;
my $days = shift;
if($days eq '') {
$days = 1;
}
my $insert = $self->{rba}->rbdb->prepare(q{
insert into rba.filerecon (
filename,
records,
start_dtm,
file_type,
managed_file_id,
mf_dtm,
processed_tidemark,
mm_records,
mm_dropped,
mm_erred,
mm_duplicate,
file_source
)
select
i.filename,
i.records,
i.file_dtm start_dtm,
i.file_type,
mf.managed_file_id,
mf.created_dtm mf_dtm,
NULL,
i.orig_records,
i.dropped,
i.erred,
i.duplicate,
i.file_source
from rba.mmfilestats i, managedfile mf, filelog fl
where
i.filename = fl.file_name and
trunc(i.file_dtm) = trunc(sysdate - ?) and
mf.managed_file_id = fl.managed_file_id
}) or die $DBI::errstr;
$insert->execute($days);
$insert->finish;
$self->{rba}->rbdb->commit;
my $update = $self->{rba}->rbdb->prepare(q{
update rba.filerecon fr
set processed_tidemark = (
select processed_tidemark
from jobhasfile j
where j.managed_file_id = fr.managed_file_id
)
where
trunc(start_dtm) = trunc(sysdate - ?) and
processed_tidemark is null
});
$update->execute($days);
$insert->finish;
$self->{rba}->rbdb->commit;
}
If the prepare statement above fails due to table or view not existing, then it should return a value to perl module
you are telling your program to die if the prepare returns false:
}) or die $DBI::errstr;
replace that with what you're looking for:
}) or return $somevalue;
or remove the or entirely and check the value of your statement handle;
my $insert = $self->{rba}->rbdb->prepare(q{
...
});
return $somevalue if ( !$insert );
What you need to do is return the DBI::errstr. Do not die on error.
So do something like this (starting at your prepare and ending with your where but getting rid of the "or die"):
...prepare( ......
where
i.filename = fl.file_name and
trunc(i.file_dtm) = trunc(sysdate - ?) and
mf.managed_file_id = fl.managed_file_id
});
if ($DBI::errstr) {
# oops something is wrong
print $DBI::errstr;
call_error($DBI::errstr);
}
Good luck
Your post of the errorlog shows that your error is raised at point of execute not at the point of prepare.
So this what you do AFTER the execute:
#your execute statement first
$insert->execute($days);
#Now the check on the execute
if ($DBI::errstr) {
# oops something is wrong
return -1;
}
Please let me know if this works

insert_id mysqli

I'm trying to return the inserted id from a mysql INSERT query. Each time I run the function I get 0 as the result. Can someone please explain at what point I can retrieve the value because although the script below executes I cannot retireve the inserted id. Probably done something stupid.
<?php
public function execSQL($sql, $params, $close){
$mysqli = new mysqli(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME);
$stmt = $mysqli->prepare($sql) or die ("Failed to prepared the statement!");
call_user_func_array(array($stmt, 'bind_param'), $this->refValues($params));
$this->insert_id($this->connection);
$stmt->execute();
if($close){
$result = $mysqli->affected_rows;
} else {
$meta = $stmt->result_metadata();
while ( $field = $meta->fetch_field() ) {
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $this->refValues($parameters));
while ( $stmt->fetch() ) {
$x = array();
foreach( $row as $key => $val ) {
$x[$key] = $val;
}
$results[] = $x;
}
$result = $results;
}
$stmt->close();
$mysqli->close();
return $result;
}
?>
Check $mysqli->insert_id after executing insert query.