Skip to content

Instantly share code, notes, and snippets.

@vadviktor
Created August 30, 2012 14:31
Show Gist options
  • Save vadviktor/3529682 to your computer and use it in GitHub Desktop.
Save vadviktor/3529682 to your computer and use it in GitHub Desktop.
Gmail IMAP attacment downloader
<?php
final class Gmail{
//********************************************************
private $imap_username = '';
private $imap_password = '';
private $save_dir = '.';
//********************************************************
private $imap_base_address = '{imap.gmail.com:993/imap/ssl}';
public function go() {
return new Gmail ( );
}
public function __construct() {
$this->log ( '--- START ---' );
$this->doJob();
}
public function __destruct(){
$this->log ( '--- END ---' );
}
private function log($s) {
print $s . "\n";
}
private function decodeMimeStr($string, $charset = "UTF-8") {
$newString = '';
$elements = imap_mime_header_decode ( $string );
for($i = 0; $i < count ( $elements ); $i ++) {
if ($elements [$i]->charset == 'default')
$elements [$i]->charset = 'iso-8859-1';
$newString .= iconv ( $elements [$i]->charset, $charset, $elements [$i]->text );
}
return $newString;
}
private function _save_attachment($tmpname, $fname, $encoding) {
$_pre = date ( "YmdHis", time () ) . "_";
$name = $_pre . $fname;
$fullname = "{$this->save_dir}/{$name}";
$new_file = fopen ( $fullname, 'wb' );
switch ( $encoding )
{
case 1 :
fwrite( $new_file, quoted_printable_decode(imap_8bit(file_get_contents($tmpname, FILE_TEXT))));
break;
case 3 :
fwrite( $new_file, base64_decode( file_get_contents( $tmpname, FILE_TEXT ) ) );
break;
case 0 :
case 4 :
fwrite( $new_file, quoted_printable_decode( file_get_contents( $tmpname, FILE_TEXT ) ) );
break;
}
fclose ( $new_file );
unlink ( $tmpname );
$this->log ( "ATTACHMENT NAME: {$fname}" );
}
// Sub function for create_part_array(). Only called by create_part_array() and itself.
private function add_part_to_array($obj, $partno, & $part_array) {
$part_array [] = array (
'part_number' => $partno, 'part_object' => $obj );
if ($obj->type == 2) { // Check to see if the part is an attached email message, as in the RFC-822 type
//print_r($obj);
if (sizeof ( $obj->parts ) > 0) { // Check to see if the email has parts
foreach ( $obj->parts as $count => $part ) {
// Iterate here again to compensate for the broken way that imap_fetchbody() handles attachments
if (sizeof ( $part->parts ) > 0) {
foreach ( $part->parts as $count2 => $part2 ) {
$this->add_part_to_array ( $part2, $partno . "." . ($count2 + 1), $part_array );
}
} else { // Attached email does not have a seperate mime attachment for text
$part_array [] = array (
'part_number' => $partno . '.' . ($count + 1), 'part_object' => $obj );
}
}
} else { // Not sure if this is possible
$part_array [] = array ('part_number' => $prefix . '.1', 'part_object' => $obj );
}
} else { // If there are more sub-parts, expand them out.
if (sizeof ( $obj->parts ) > 0) {
foreach ( $obj->parts as $count => $p ) {
$this->add_part_to_array ( $p, $partno . "." . ($count + 1), $part_array );
}
}
}
}
private function create_part_array($structure, $prefix = "") {
//print_r($structure);
if (sizeof ( $structure->parts ) > 0) { // There some sub parts
foreach ( $structure->parts as $count => $part ) {
$this->add_part_to_array ( $part, $prefix . ($count + 1), $part_array );
}
} else { // Email does not have a seperate mime attachment for text
$part_array [] = array (
'part_number' => $prefix . '1', 'part_object' => $obj );
}
return $part_array;
}
private function doJob() {
if ($mbox = imap_open ( $this->imap_base_address . 'All Mail', $this->imap_username, $this->imap_password ))
{
$this->log ( 'MBOX SORTING' );
$sorted_mbox = imap_sort ( $mbox, "SORTARRIVAL", 1 );
foreach ( $sorted_mbox as $msgno ) {
$this->log ( 'READ NEW MAIL' );
//get info by searching the emails
$header = imap_headerinfo ( $mbox, $msgno );
$from = $header->from;
$email = $from [0]->mailbox . '@' . $from [0]->host;
$subject = htmlspecialchars ( $this->decodeMimeStr ( $header->Subject ), ENT_QUOTES );
$this->log ( "E-MAIL: {$email}; SUBJECT: {$subject}" );
//attach message parts
$struct = imap_fetchstructure ( $mbox, $msgno );
$parts = $this->create_part_array ( $struct );
if(count($parts) > 0)
{
$this->log ( "EXTRACTING ATTACHMENTS" );
foreach ( $parts as $part ) {
if($part['part_object']->subtype != 'ALTERNATIVE'
&& $part['part_object']->subtype != 'RELATED'
&& $part['part_object']->subtype != 'PLAIN'
&& $part['part_object']->subtype != 'HTML'
) {
if (gettype ( $part ['part_object']->parameters ) == 'array')
){
$fname = $this->decodeMimeStr ( $part ['part_object']->parameters [0]->value );
//save and attach file to iktatokönyv
$_pre = date ( "YmdHis", time () ) . "_";
$tmpname = "/tmp/{$_pre}{$fname}";
if (imap_savebody ( $mbox, $tmpname, $msgno, $part ['part_number'], FT_PEEK )) {
$this->_save_attachment ( $tmpname, $fname, $part['part_object']->encoding);
}
}
}
}
}
}
$this->log ( "CLOSE MBOX" );
imap_close ( $mbox );
}
}
}
Gmail::go ();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment