eZ Community » Forums » Developer » Attach file with original filename in...
expandshrink

Attach file with original filename in email

Attach file with original filename in email

Wednesday 26 October 2011 12:59:51 pm - 6 replies

Hi,

I managed to send an email when a certain contentclass node is created, hacking the /content/edit.php with the ezc mail method (0)

I also managed to attach a file stored as en ezbinaryfile attribute (1) to the mail but I can't figure out how to attach the file with its original_filename (and not the internal filename which has no meaning for the receiver).

I looked at the download template (2) and it's doing what I want to achieve (downloaded file has the human name!) but indicating in the /content/download... url in the $mail->addFileAttachment(); instruction does not seem to work (I guess this instruction needs a direct path and not a template path ; and there does not seem to be a direct path with original filename...).

Unfortunately I'm not good enough at understanding the related PHP code (3) like the handleDownload function of the eZBinaryFileHandler class.

=> My question is : how and when shall I modify the name of the file so that the mail attachement has a human name ?

Below my current code in /content/edit.php folowd by related ressources links.

Thanks a lot for your help that would let me finish my project !!!

 // mike : "email with ezfile attachment" test begin
$mikeclassID = $object->attribute( 'contentclass_id' );
if ( $mikeclassID == 53 )
    {
    $map =( $object->attribute( 'data_map' ));      
    $AttMessage = $map[message];
    $TextMessage = $AttMessage->attribute( 'data_text' );
    $AttName = $map[name];
    $TextName= $AttName->attribute( 'data_text' );
       $receiver = 'xxx@gmail.com';
        $ccReceivers = '';
        $bccReceivers = '';
        $sender = 'xxx@gmail.com';
        $replyTo = 'xxx@gmail.com';
 
# / Create a new mail composer object
$mail = new ezcMailComposer();
#
# // Specify the "from" mail address
$mail->from = new ezcMailAddress( $sender, 'sendername' );
#
# // Add one "to" mail address (multiple can be added)
 $mail->addTo( new ezcMailAddress( $receiver, 'receivername' ) );
#
# // Specify the subject of the mail
 $mail->subject = $TextName;
#
# // Specify the body text of the mail
 $mail->plainText = $TextMessage;
 
$mail->addFileAttachment( '/home/xxx/www/var/ezwebin_site/storage/original/application/6e11d8a517f98f4cabfcdcc1b1b2bb3a.doc' );  
 
// the method below doesnot work :-(
//$mail->addFileAttachment( 'http://www.xxx.com/index.php/user_path/content/download/178/2525/file/CV_MICKAEL_xxx.doc' );  
  
 
# // Generate the mail
 $mail->build();
#
# // Create a new MTA transport object
$transport = new ezcMailMtaTransport();
#
# // Use the MTA transport to send the created mail object
$transport->send( $mail );         
    }
 
// mike : "email with ezfile attachment" test end              

RELATED RESSOURCES

Modified on Wednesday 26 October 2011 1:07:46 pm by Mickael Robin

Wednesday 26 October 2011 2:27:04 pm

You'll be able to get the original filename From the file object:

$originalFilename = $file->attribute( "original_filename" );

I see that's a hard-coded path but I assume at some point you'll want to get this from an object.  To get the file to download as the original filename, you'll have to pass a filename in the header - if you look at the kernel hack in http://projects.ez.no/enhancedezbinaryfile you'll see what I mean:

                         foreach ( $fileAttachments as $attacharray) {
                                $filedata = chunk_split(base64_encode(eZFile::getContents($attacharray[0])));
                                $message .= "\n\n\n--{$mime_boundary}\n" .
                                        "Content-Type: " . $attacharray[2] . ";\n" .
                                        " name=\"" . $attacharray[1] . "\"\n" .
                                        "Content-Transfer-Encoding: base64\n" .
                                        "Content-Disposition: inline;\n" .
                                        " filename=\"" . $attacharray[1] . "\"\n\n" .
                                        $filedata . "\n";
 
                        }

But since your using the components, take a look at lib/ezc/Mail/src/composer.php at around line 83 you'll see how you'll have to do it.

Wednesday 26 October 2011 4:54:32 pm

Hello Mickael,

I took a few minutes this morning to re-write your script to use good source code formatting (ezpublish code standards) and correct api usage to reach the goals stated.

The following example should work for your needs. Let us know how it works for you.

// heath : "email with ezbinaryfile attachment" test begin
$matchClassID = 53;
$prospectiveClassID = $object->attribute( 'contentclass_id' );
 
if ( $prospectiveClassID == $matchClassID ){
    $dm = $object->dataMap();
 
    $fileAttribute = $dm['file'];
    $filePath = $fileAttribute->attribute( "filepath" );
    $originalFileName = $fileAttribute->attribute( "original_filename" );
 
    $AttMessage = $dm['message'];
    $TextMessage = $AttMessage->attribute( 'data_text' );
    $AttName = $dm['name'];    $TextName= $AttName->attribute( 'data_text' );
 
    $receiver = 'xxx@gmail.com';
    $ccReceivers = '';
    $bccReceivers = '';
    $sender = 'xxx@gmail.com';
    $replyTo = 'xxx@gmail.com';
 
    // Create a new mail composer object
    $mail = new ezcMailComposer();
 
    // Specify the "from" mail address
    $mail->from = new ezcMailAddress( $sender, 'sendername' );
 
    // Add one "to" mail address (multiple can be added)
    $mail->addTo( new ezcMailAddress( $receiver, 'receivername' ) );
 
    // Specify the subject of the mail
    $mail->subject = $TextName;
 
    // Specify the body text of the mail
    $mail->plainText = $TextMessage;
 
    if ( $fileAttribute->hasContent() == true )
    {
        $disposition = new ezcMailContentDispositionHeader();
        $disposition->fileName = $originalFileName;
        $disposition->fileNameCharSet = 'utf-8'; // if using non-ascii characters in the file name
        $disposition->disposition = 'attachment'; // default value is 'inline'
        $mail->addFileAttachment( $filePath, null, null, $disposition );
    }
 
    // Generate the mail
    $mail->build();
 
    // Create a new MTA transport object
    $transport = new ezcMailMtaTransport();
 
    // Use the MTA transport to send the created mail object
    $transport->send( $mail );
}
 
// heath : "email with ezbinaryfile attachment" test end

Special thanks to Steven E. Bailey for sharing the Zeta Components based disposition suggestion!

I hope this helps ...

Cheers,

Heath

Modified on Wednesday 26 October 2011 4:59:41 pm by // Heath

Thursday 27 October 2011 1:56:35 am

Thank a lot Steven and Heath for your 2 promising answers !

Despite many searches and trials, I could not figure out how to reach the ezbinaryfile attribute.

I seems that the filepath and original filename (attributes of the ezbinaryfile object) can not be reached from the contentobject's datamap.

I tried many things, and have the feeling that I need to fetch the ezbinaryfile object from the contentattribute but I can't find a correct syntax for this.

Below a few useful links :

  • to get the ezbinaryfile :

http://pubsvn.ez.no/doxygen/trunk/html/classeZBinaryFile.html#a5d1da5c25a924efe5c77ec5ee836c358

  • to get the contentobjectattribute (file datatype) that is related to the binaryfile : 

http://pubsvn.ez.no/doxygen/trunk...ml#a4c359c20bdb6c5b3a71276a82191d6c1

Thanks again for your precious help happy.gif Emoticon

Mickael

Thursday 27 October 2011 4:02:33 am

Hello Mickael,

Your very welcome. We are happy to help happy.gif Emoticon

 

"Despite many searches and trials, I could not figure out how to reach the ezbinaryfile attribute."

This is your error I assure you. I think you lack the specific examples and experience to know what the right lines of code.The ezbinaryfile attribute is absolutely reachable through a content object datamap.

 

"I seems that the filepath and original filename (attributes of the ezbinaryfile object) can not be reached from the contentobject's datamap."

Again, what you say above is simply not true. Anyone can access the content object datamap attribute containing an ezbinaryfile (object class).

Here is an example of how to do this in PHP

<?php
 
    // Please change the value assigned for $id to match a content object id
    // which contains a 'file' attribute of datatype ezbinaryfiletype.
    $id = 42;
    $attributeIdentifier = 'file';
 
    // Fetch content object (with data)
    $object = eZContentObject::fetch( $id );
 
    // Load dataMap (content object attribute data)
    $dm = $object->dataMap();
 
    // Access the expected 'file' content object attribute (of class eZContentObjectAttribute)
    $fileAttribute = $dm[ $attributeIdentifier ];
 
    print_r( $fileAttribute ); echo "\n\n<hr />";
 
    // Access the ezbinaryfile class (with attribute data)
    $ezbinaryfileObject = $fileAttribute->content();
 
    print_r( $ezbinaryfileObject ); echo "\n\n<hr />";
 
    // Access the ezbinaryfile class attribute 'filepath' (path to file + stored filename)
    $filePath = $fileAttribute->attribute( "filepath" );
 
    print_r( $filePath ); echo "\n\n<hr />";
 
    // Exit current execution normally
    eZExecution::cleanExit();
?>

Here is an example of how to do the exact same thing in eZ Publish Templates

{def $object=fetch( 'content', 'object', hash( 'object_id', 42) )}
 
{$object.name|wash}<hr />
 
{$object.data_map.file|attribute(show,1)}<hr />
 
{$object.data_map.file.content|attribute(show,1)}<hr />
 
{$object.data_map.file.content.filepath}<br /><br /> 

Also you might want to study the eZContentObjectAttribute Class in greater detail as understanding it is the key to reach the attribute data you need.

http://doc.ez.no/eZ-Publish/Technical-manual/4.x/Reference/Objects/ezcontentobjectattribute
http://pubsvn.ez.no/doxygen/trunk/html/classeZContentObjectAttribute.html

 

 

Note: The method you linked to in the above PHP class documentation on pubsvn.ez.no, 'eZContentObjectAttribute::fetchByClassAttributeID' or 'eZContentObjectAttribute::fetchByIdentifier'
these methods are not the preferred or normal way to fetch your attribute. While they are useful in certain situations, in most situations your better using the examples I provided above as the default way to access your attribute content.

 

 

I hope this helps ...

 

 

Cheers,

Heath

Modified on Thursday 27 October 2011 4:05:41 am by // Heath

Thursday 27 October 2011 11:56:00 am

I'm done ! Thanks a lot happy.gif Emoticon

I was missing the $fileAttribute->content(); step between the datamap and the final attribute.

=> in the future, I'll make sure I get the right template way before going on the php side...

As a side note, I managed to get the grand-grand-father's file of the edited contentobject with this code.

$FatherNodeID = $object->attribute( 'main_parent_node_id' );
$FatherNode= eZContentObjectTreeNode::fetch($FatherNodeID);
$GrandFatherNodeID = $FatherNode->attribute( 'parent_node_id' );
$GrandFatherNode= eZContentObjectTreeNode::fetch($GrandFatherNodeID);
$GrandGrandFatherNodeID = $GrandFatherNode->attribute( 'parent_node_id' );
$GrandGrandFatherObject = eZContentObject::fetchByNodeID(GrandGrandFatherNodeID, true );
 

There might be a simpler way, but it works and could help those who are worst coders than me happy.gif Emoticon

Thanks again guys for your precious help .

Mickael

Modified on Thursday 27 October 2011 11:58:13 am by Mickael Robin

Thursday 27 October 2011 4:40:13 pm

Hello Mickael,

 

Congratulations! I'm very pleased you were able to reach your goal successfully with our help happy.gif Emoticon

Feel free to ask more questions here in the forums. Take care ...

 

Best wishes

 

Cheers,

Heath

expandshrink

You must be logged in to post messages in this topic!

36 542 Users on board!

Forums menu

Proudly Developed with from