Related
I found this code under this question PHP - IMAP: Save Attachment to Specific Folder and it works really well. Thanks for that.
I need a little change regarding the filename. Currently the attachments will be saved with the original filename. But i need as filename the timestamp of the mail. How I need to change the code to do that?
<?php
function getFileExtension($fileName){
$parts=explode(".",$fileName);
return $parts[count($parts)-1];
}
$imap = imap_open($server, $username, $password) or die("imap connection error");
$message_count = imap_num_msg($imap);
for ($m = 1; $m <= $message_count; ++$m){
$header = imap_header($imap, $m);
//print_r($header);
$email[$m]['from'] = $header->from[0]->mailbox.'#'.$header->from[0]->host;
$email[$m]['fromaddress'] = $header->from[0]->personal;
$email[$m]['to'] = $header->to[0]->mailbox;
$email[$m]['subject'] = $header->subject;
$email[$m]['message_id'] = $header->message_id;
$email[$m]['date'] = $header->udate;
$from = $email[$m]['fromaddress'];
$from_email = $email[$m]['from'];
$to = $email[$m]['to'];
$subject = $email[$m]['subject'];
echo $from_email . '</br>';
echo $to . '</br>';
echo $subject . '</br>';
$structure = imap_fetchstructure($imap, $m);
$attachments = array();
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($imap, $m, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
foreach ($attachments as $key => $attachment) {
$name = $attachment['name'];
$contents = $attachment['attachment'];
file_put_contents($name, $contents);
}
//imap_setflag_full($imap, $i, "\\Seen");
//imap_mail_move($imap, $i, 'Trash');
}
imap_close($imap);
?>
I'm using the below function to get attachments from an email (index $m) on an existing imap connection ($imap)
function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
$lstk= array_keys($attachments); $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = imap_utf8($object->value);
}
}
}
if($attachments[$j]['is_attachment']) {
if($par==''){
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $i+1);
}else{
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $par . $i+1);
}
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
}else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
}
if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
$prnt = $i;
$prnt = $prnt . '.';
parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );
}
}
}
}
the later function which calls this looks like:
$structure = imap_fetchstructure($imap, $m);
$attachments = array();
parse_parts($structure, $attachments, $imap, $m, '');
the standard function works fine, but when it has to recurse (i.e. there are nested parts), the resulting file is not readable, though it does appear to be the correct size. Any idea what i'm doing wrong?
i've tried changing $prnt to
$prnt = $i+1 .'.';
but then, it just outputs an empty file.
i noticed that other people had similar issues here:
imap - get attached file
but their solutions don't appear to work for this email/code.
thank you to IVO GELOV for finding my mistake. final working function:
function parse_parts(&$structure, &$attachments, &$imap, $m, $par){
if(isset($structure->parts) && count($structure->parts) ) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
$lstk= array_keys($attachments); $j=end($lstk); // use this instead of $i to avoid overlapping indices when there's sub-parts and recursion
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$j]['is_attachment'] = true;
$attachments[$j]['filename'] = imap_utf8($object->value);
}
}
}
if($attachments[$j]['is_attachment']) {
if($par==''){
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, ($i+1));
}else{
$attachments[$j]['attachment'] = imap_fetchbody($imap, $m, $par . ($i+1));
}
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$j]['attachment'] = base64_decode($attachments[$j]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$j]['attachment'] = quoted_printable_decode($attachments[$j]['attachment']);
}else{echo "encod:". $structure->parts[$i]->encoding . PHP_EOL; }
}
if(isset($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)){ //if the part contains its own parts, recurse
$prnt = $i+1;
$prnt = $prnt . '.';
parse_parts($structure->parts[$i], $attachments, $imap, $m, $prnt );
}
}
}
}
attachment may be inline or external file too.
so we have to get both type of attachments.
$structure = imap_fetchstructure($this->imap, $id);
$fileName = $attachments = array();
/* if any attachments found... */
if (isset($structure->parts) && count($structure->parts)) {
$n = 0;
for($i = 0; $i < count($structure->parts); $i++){
if(isset($structure->parts[$i]->parts) && !empty($structure->parts[$i]->parts) && count($structure->parts[$i]->parts)>0){
for($y = 0; $y < count($structure->parts[$i]->parts); $y++)
{
$attachments[$n] = array('is_attachment' => false,'filename' => '','name' => '','attachment' => '','size' => '','cid' => 0);
if($structure->parts[$i]->parts[$y]->ifdparameters==1) {
foreach($structure->parts[$i]->parts[$y]->dparameters as $object){
if(strtolower($object->attribute) == 'filename'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['filename'] = $filename;
$attachments[$n]['name'] = $filename;
}
}
}
if($structure->parts[$i]->parts[$y]->ifparameters){
foreach($structure->parts[$i]->parts[$y]->parameters as $object){
if(strtolower($object->attribute) == 'name'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['name'] = $filename;
$attachments[$n]['filename'] = $filename;
}
}
}
if($attachments[$n]['is_attachment']){
$attachments[$n]['attachment'] = imap_fetchbody($this->imap, $id, ($i+1).'.'.($y+1));
if($structure->parts[$i]->parts[$y]->encoding == 3){ /* 4 = QUOTED-PRINTABLE encoding */
$attachments[$n]['attachment'] = base64_decode($attachments[$n]['attachment']);
}
elseif($structure->parts[$i]->parts[$y]->encoding == 4){ /* 3 = BASE64 encoding */
$attachments[$n]['attachment'] = quoted_printable_decode($attachments[$n]['attachment']);
}
$attachments[$n]['size'] = $structure->parts[$i]->parts[$y]->bytes;
$attachments[$n]['cid'] = ($structure->parts[$i]->parts[$y]->ifid) ? str_replace(array('<', '>'), '', $structure->parts[$i]->parts[$y]->id) : 0;
}
$email['attachments'][] = $attachments[$n];$n++;
}
}else{
$attachments[$n] = array('is_attachment' => false,'filename' => '','name' => '','attachment' => '','size' => '','cid' => 0);
if($structure->parts[$i]->ifdparameters==1){
foreach($structure->parts[$i]->dparameters as $object){
if(strtolower($object->attribute) == 'filename'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['filename'] = $filename;
$attachments[$n]['name'] = $filename;
}
}
}
if($structure->parts[$i]->ifparameters){
foreach($structure->parts[$i]->parameters as $object){
if(strtolower($object->attribute) == 'name'){
$attachments[$n]['is_attachment'] = true;
$fileName[0] = $object->value;
$filename = $this->filterFileName($fileName);
$attachments[$n]['name'] = $filename;
$attachments[$n]['filename'] = $filename;
}
}
}
if($attachments[$n]['is_attachment']){
$attachments[$n]['attachment'] = imap_fetchbody($this->imap, $id, $i+1);
if($structure->parts[$i]->encoding == 3){/* 4 = QUOTED-PRINTABLE encoding */
$attachments[$n]['attachment'] = base64_decode($attachments[$n]['attachment']);
}elseif($structure->parts[$i]->encoding == 4){ /* 3 = BASE64 encoding */
$attachments[$n]['attachment'] = quoted_printable_decode($attachments[$n]['attachment']);
}
$attachments[$n]['size'] = $structure->parts[$i]->bytes;
$attachments[$n]['cid'] = ($structure->parts[$i]->ifid) ? str_replace(array('<', '>'), '', $structure->parts[$i]->id) : 0;
}
$email['attachments'][] = $attachments[$n];$n++;
}
}
}
public function filterFileName($fileName) {
$newstr = preg_replace('/[^a-zA-Z0-9\-\.\']/', '_', $fileName[0]);
$fileName = str_replace("'", '', $newstr);
return $fileName;
}
after that you have to store this attachments
PLease Help me,
I have this errors
Warning: Illegal string offset 'formId' in
C:\xampp\htdocs\wp-content\plugins\repeater-add-on-for-gravity-forms\class-gf-field-repeater.php
on line 287
Warning: Illegal string offset 'children' in
C:\xampp\htdocs\wp-content\plugins\repeater-add-on-for-gravity-forms\class-gf-field-repeater.php
on line 291
...
if (empty($value)) {
$value['formId'] = $form_id;
if (!empty($repeater_start)) { $value['start'] = $repeater_start; }
if (!empty($repeater_min)) { $value['min'] = $repeater_min; }
if (!empty($repeater_max)) { $value['max'] = $repeater_max; }
if (!empty($repeater_children)) { $value['children'] = $repeater_children; }
$value = json_encode($value);
}
...
Hi I solved adding $value = array() in line 287.
if (empty($value)) {
$value = array();
$value['formId'] = $form_id;
if (!empty($repeater_start)) { $value['start'] = $repeater_start; }
if (!empty($repeater_min)) { $value['min'] = $repeater_min; }
if (!empty($repeater_max)) { $value['max'] = $repeater_max; }
if (!empty($repeater_children)) { $value['children'] = $repeater_children; }
$value = json_encode($value);
}
That's work for me, I hope it could help you.
<?php
class GF_Field_Repeater extends GF_Field {
public $type = 'repeater';
public static function init_admin() {
$admin_page = rgget('page');
if ($admin_page == 'gf_edit_forms' && !empty($_GET['id'])) {
add_action('gform_field_standard_settings' , array('GF_Field_Repeater', 'gform_standard_settings'), 10, 2);
add_action('gform_field_appearance_settings' , array('GF_Field_Repeater', 'gform_appearance_settings'), 10, 2);
add_action('gform_editor_js_set_default_values', array('GF_Field_Repeater', 'gform_set_defaults'));
add_action('gform_editor_js', array('GF_Field_Repeater', 'gform_editor'));
add_filter('gform_tooltips', array('GF_Field_Repeater', 'gform_tooltips'));
}
if ($admin_page == 'gf_entries') {
add_filter('gform_form_post_get_meta', array('GF_Field_Repeater', 'gform_hide_children'));
}
}
public static function init_frontend() {
add_action('gform_form_args', array('GF_Field_Repeater', 'gform_disable_ajax'));
add_action('gform_enqueue_scripts', array('GF_Field_Repeater', 'gform_enqueue_scripts'), 10, 2);
add_filter('gform_pre_render', array('GF_Field_Repeater', 'gform_unhide_children_validation'));
add_filter('gform_pre_validation', array('GF_Field_Repeater', 'gform_bypass_children_validation'));
}
public static function gform_enqueue_scripts($form, $is_ajax) {
if (!empty($form)) {
if (GF_Field_Repeater::get_field_index($form) !== false) {
wp_enqueue_script('gforms_repeater_postcapture_js', plugins_url('js/jquery.postcapture.min.js', __FILE__), array('jquery'), '0.0.1');
wp_enqueue_script('gforms_repeater_js', plugins_url('js/gf-repeater.min.js', __FILE__), array('jquery'), GF_REPEATER_VERSION);
wp_enqueue_style('gforms_repeater_css', plugins_url('css/gf-repeater.css', __FILE__), array(), GF_REPEATER_VERSION);
}
}
}
public function get_form_editor_field_title() {
return 'Repeater';
}
public function get_form_editor_field_settings() {
return array(
'admin_label_setting',
'css_class_setting',
'description_setting',
'error_message_setting',
'label_setting',
'prepopulate_field_setting'
);
}
public static function gform_set_defaults() {
echo "
case \"repeater\" :
field.label = \"Repeater\";
break;
";
}
public static function gform_standard_settings($position, $form_id) {
if ($position == 1600) {
echo "<li class=\"repeater_settings field_setting\">
<label for=\"field_repeater_start\">Start ";
gform_tooltip('form_field_repeater_start');
echo " </label>
<input type=\"number\" id=\"field_repeater_start\" min=\"1\" value=\"1\" onchange=\"SetFieldProperty('start', this.value);\">
</li>";
echo "<li class=\"repeater_settings field_setting\">
<label for=\"field_repeater_min\">Min ";
gform_tooltip('form_field_repeater_min');
echo " </label>
<input type=\"number\" id=\"field_repeater_min\" min=\"1\" value=\"1\" onchange=\"SetFieldProperty('min', this.value);\">
</li>";
echo "<li class=\"repeater_settings field_setting\">
<label for=\"field_repeater_max\">Max ";
gform_tooltip('form_field_repeater_max');
echo " </label>
<input type=\"number\" id=\"field_repeater_max\" min=\"1\" onchange=\"SetFieldProperty('max', this.value);\">
</li>";
}
}
public static function gform_appearance_settings($position, $form_id) {
if ($position == 400) {
echo "<li class=\"repeater_settings field_setting\">
<input type=\"checkbox\" id=\"field_repeater_hideLabel\" onchange=\"SetFieldProperty('hideLabel', this.checked);\">
<label for=\"field_repeater_hideLabel\" class=\"inline\">Hide Label & Description ";
gform_tooltip('form_field_repeater_hideLabel');
echo " </label>
</li>";
}
}
public static function gform_editor() {
echo "<script type=\"text/javascript\">
fieldSettings['repeater'] += ', .repeater_settings';
jQuery(document).bind('gform_load_field_settings', function(event, field, form){
jQuery('#field_repeater_start').val(field['start']);
jQuery('#field_repeater_min').val(field['min']);
jQuery('#field_repeater_max').val(field['max']);
jQuery('#field_repeater_hideLabel').prop('checked', field['hideLabel']);
});
</script>";
}
public static function gform_tooltips($tooltips) {
$tooltips['form_field_repeater_start'] = "The number of times the repeater will be repeated when the form is rendered. Leaving this field blank or setting it to a number higher than the maximum number is the same as setting it to 1.";
$tooltips['form_field_repeater_min'] = "The minimum number of times the repeater is allowed to be repeated. Leaving this field blank or setting it to a number higher than the maximum field is the same as setting it to 1.";
$tooltips['form_field_repeater_max'] = "The maximum number of times the repeater is allowed to be repeated. Leaving this field blank or setting it to a number lower than the minimum field is the same as setting it to unlimited.";
$tooltips['form_field_repeater_hideLabel'] = "If this is checked, the repeater label and description will not be shown to users on the form.";
return $tooltips;
}
function validate($value, $form) {
$repeater_required = $this->repeaterRequiredChildren;
if (!empty($repeater_required)) {
$dataArray = json_decode($value, true);
foreach ($form['fields'] as $key=>$value) {
$fieldKeys[$value['id']] = $key;
if (is_array($value['inputs'])) {
foreach ($value['inputs'] as $inputKey=>$inputValue) {
$inputKeys[$value['id']][$inputValue['id']] = $inputKey;
}
}
}
if ($dataArray['repeatCount'] < $this->min) {
$this->failed_validation = true;
$this->validation_message = "A minimum number of ".$this->min." is required.";
return;
}
if ($this->max && $dataArray['repeatCount'] > $this->max) {
$this->failed_validation = true;
$this->validation_message = "A maximum number of ".$this->max." is allowed.";
return;
}
for ($i = 1; $i < $dataArray['repeatCount'] + 1; $i++) {
foreach ($dataArray['children'] as $field_id=>$field) {
$inputNames = $field['inputs'];
$repeatSkips = $field['conditionalLogic']['skip'];
if (!is_array($inputNames)) { continue; }
if (is_array($repeatSkips)) {
if (in_array($i, $repeatSkips) || in_array('all', $repeatSkips)) { continue; }
}
foreach ($inputNames as $inputName) {
if (is_array($inputName)) { $inputName = reset($inputName); }
if (substr($inputName, -2) == '[]') {
$getInputName = substr($inputName, 0, strlen($inputName) - 2).'-'.$dataArray['repeaterId'].'-'.$i;
} else {
$getInputName = $inputName.'-'.$dataArray['repeaterId'].'-'.$i;
}
$getInputName = str_replace('.', '_', strval($getInputName));
$getInputData = rgpost($getInputName);
$getInputIdNum = preg_split("/(_|-)/", $getInputName);
if (in_array($getInputIdNum[1], $repeater_required)) {
$fieldKey = $fieldKeys[$getInputIdNum[1]];
$fieldType = $form['fields'][$fieldKey]['type'];
$failedValidation = false;
switch($fieldType) {
case 'name':
$requiredIDs = array(3, 6);
if (in_array($getInputIdNum[2], $requiredIDs) && empty($getInputData)) { $failedValidation = true; }
break;
case 'address':
$skipIDs = array(2);
if (!in_array($getInputIdNum[2], $skipIDs) && empty($getInputData)) { $failedValidation = true; }
break;
default:
if (empty($getInputData)) { $failedValidation = true; }
}
if ($failedValidation) {
$this->failed_validation = true;
if ($this->errorMessage) { $this->validation_message = $this->errorMessage; } else { $this->validation_message = "A required field was left blank."; }
return;
}
}
}
}
}
}
}
public function get_field_content($value, $force_frontend_label, $form) {
if (is_admin()) {
$admin_buttons = $this->get_admin_buttons();
$field_content = "{$admin_buttons}
<div class=\"gf-pagebreak-first gf-pagebreak-container gf-repeater gf-repeater-start\">
<div class=\"gf-pagebreak-text-before\">begin repeater</div>
<div class=\"gf-pagebreak-text-main\"><span>REPEATER</span></div>
<div class=\"gf-pagebreak-text-after\">top of repeater</div>
</div>";
} else {
$field_label = $this->get_field_label($force_frontend_label, $value);
$description = $this->get_description($this->description, 'gsection_description gf_repeater_description');
$hide_label = $this->hideLabel;
$validation_message = ( $this->failed_validation && ! empty( $this->validation_message ) ) ? sprintf( "<div class='gfield_description validation_message'>%s</div>", $this->validation_message ) : '';
if (!empty($field_label)) { $field_label = "<h2 class='gf_repeater_title'>{$field_label}</h2>"; } else { $field_label = ''; }
if ($hide_label) { $field_label = ''; $description = ''; }
$field_content = "<div class=\"ginput_container ginput_container_repeater\">{$field_label}{FIELD}</div>{$description}{$validation_message}";
}
return $field_content;
}
public function get_field_input($form, $value = '', $entry = null) {
if (is_admin()) {
return '';
} else {
$form_id = $form['id'];
$is_entry_detail = $this->is_entry_detail();
$is_form_editor = $this->is_form_editor();
$id = (int) $this->id;
$field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
$tabindex = $this->get_tabindex();
$repeater_parem = $this->inputName;
$repeater_start = $this->start;
$repeater_min = $this->min;
$repeater_max = $this->max;
$repeater_required = $this->repeaterRequiredChildren;
$repeater_children = $this->repeaterChildren;
if (!empty($repeater_parem)) {
$repeater_parem_value = GFFormsModel::get_parameter_value($repeater_parem, $value, $this);
if (!empty($repeater_parem_value)) { $repeater_start = $repeater_parem_value; }
}
if (!empty($repeater_children)) {
$repeater_children_info = array();
$repeater_parems = GF_Field_Repeater::get_children_parem_values($form, $repeater_children);
foreach($repeater_children as $repeater_child) {
$repeater_children_info[$repeater_child] = array();
$repeater_child_field_index = GF_Field_Repeater::get_field_index($form, 'id', $repeater_child);
if (!empty($repeater_required)) {
if (in_array($repeater_child, $repeater_required)) {
$repeater_children_info[$repeater_child]['required'] = true;
}
}
if (!empty($repeater_parems)) {
if (array_key_exists($repeater_child, $repeater_parems)) {
$repeater_children_info[$repeater_child]['prePopulate'] = $repeater_parems[$repeater_child];
}
}
if ($repeater_child_field_index !== false) {
if ($form['fields'][$repeater_child_field_index]['inputMask']) {
$repeater_children_info[$repeater_child]['inputMask'] = $form['fields'][$repeater_child_field_index]['inputMaskValue'];
} elseif ($form['fields'][$repeater_child_field_index]['type'] == 'phone' && $form['fields'][$repeater_child_field_index]['phoneFormat'] = 'standard') {
$repeater_children_info[$repeater_child]['inputMask'] = "(999) 999-9999";
}
if ($form['fields'][$repeater_child_field_index]['conditionalLogic']) {
$repeater_children_info[$repeater_child]['conditionalLogic'] = $form['fields'][$repeater_child_field_index]['conditionalLogic'];
}
}
}
$repeater_children = $repeater_children_info;
}
if (empty($value)) {
$value['formId'] = $form_id;
if (!empty($repeater_start)) { $value['start'] = $repeater_start; }
if (!empty($repeater_min)) { $value['min'] = $repeater_min; }
if (!empty($repeater_max)) { $value['max'] = $repeater_max; }
if (!empty($repeater_children)) { $value['children'] = $repeater_children; }
$value = json_encode($value);
}
return sprintf("<input name='input_%d' id='%s' type='hidden' class='gform_repeater' value='%s' %s />", $id, $field_id, $value, $tabindex);
}
}
public function get_value_save_entry($value, $form, $input_name, $lead_id, $lead) {
$dataArray = json_decode($value, true);
$value = Array();
for ($i = 1; $i < $dataArray['repeatCount'] + 1; $i++) {
foreach ($dataArray['children'] as $field_id=>$field) {
$inputData = Array();
if (array_key_exists('inputs', $field)) {
$inputNames = $field['inputs'];
$repeatSkips = $field['conditionalLogic']['skip'];
if (is_array($repeatSkips)) {
if (in_array($i, $repeatSkips) || in_array('all', $repeatSkips)) { continue; }
}
if (is_array($inputNames)) {
foreach ($inputNames as $inputName) {
if (substr($inputName, -2) == '[]') {
$getInputName = substr($inputName, 0, strlen($inputName) - 2).'-'.$dataArray['repeaterId'].'-'.$i;
} else {
$getInputName = $inputName.'-'.$dataArray['repeaterId'].'-'.$i;
}
$getInputData = rgpost(str_replace('.', '_', strval($getInputName)));
if (!empty($getInputData)) {
if (is_array($getInputData)) {
foreach ($getInputData as $theInputData) {
$inputData[] = $theInputData;
}
} else {
$inputData[] = $getInputData;
}
}
}
}
} else {
if (GF_Field_Repeater::get_field_type($form, $field_id) == 'section') { $inputData = '[gfRepeater-section]'; }
}
$childValue[$field_id] = $inputData;
}
$value[$i] = $childValue;
}
return maybe_serialize($value);
}
public function get_value_entry_list($value, $entry, $field_id, $columns, $form) {
if (empty($value)) {
return '';
} else {
$dataArray = GFFormsModel::unserialize($value);
$arrayCount = count($dataArray);
if ($arrayCount > 1) { $returnText = $arrayCount.' entries'; } else { $returnText = $arrayCount.' entry'; }
return $returnText;
}
}
public function get_value_entry_detail($value, $currency = '', $use_text = false, $format = 'html', $media = 'screen') {
if (empty($value)) {
return '';
} else {
$dataArray = GFFormsModel::unserialize($value);
$arrayCount = count($dataArray);
$output = "\n";
$count = 0;
$repeatCount = 0;
$display_empty_fields = rgget('gf_display_empty_fields', $_COOKIE);
$form_id = $this->formId;
$get_form = GFFormsModel::get_form_meta_by_id($form_id);
$form = $get_form[0];
foreach ($dataArray as $key=>$value) {
$repeatCount++;
$tableContents = '';
if (!empty($value) && !is_array($value)) {
$save_value = $value;
unset($value);
$value[0] = $save_value;
}
foreach ($value as $childKey=>$childValue) {
$count++;
$childValueOutput = '';
if (empty($display_empty_fields) && count($childValue) == 0) { continue; }
if (is_numeric($childKey)) {
$field_index = GF_Field_Repeater::get_field_index($form, 'id', $childKey);
if ($field_index === false) { continue; }
$entry_title = $form['fields'][$field_index]['label'];
} else {
$entry_title = $childKey;
}
$entry_title = str_replace('[gfRepeater-count]', $repeatCount, $entry_title);
if ($format == 'html') {
if ($childValue == '[gfRepeater-section]') {
if ($media == 'email') {
$tableStyling = ' style="font-size:14px;font-weight:bold;background-color:#eee;border-bottom:1px solid #dfdfdf;padding:7px 7px"';
} else {
$tableStyling = ' class="entry-view-section-break"';
}
} else {
if ($media == 'email') {
$tableStyling = ' style="background-color:#EAF2FA;font-family:sans-serif;font-size:12px;font-weight:bold"';
} else {
$tableStyling = ' class="entry-view-field-name"';
}
}
$tableContents .= "<tr>\n<td colspan=\"2\"".$tableStyling.">".$entry_title."</td>\n</tr>\n";
} else {
$tableContents .= $entry_title.": ";
}
if (is_array($childValue)) {
if (count($childValue) == 1) {
$childValueOutput = $childValue[0];
} elseif (count($childValue) > 1) {
if ($format == 'html') {
if ($media == 'email') {
$childValueOutput = "<ul style=\"list-style:none;margin:0;padding:0;\">\n";
} else {
$childValueOutput = "<ul>\n";
}
}
foreach ($childValue as $childValueData) {
if ($format == 'html') {
$childValueOutput .= "<li>".$childValueData."</li>";
} else {
$childValueOutput .= $childValueData."\n";
}
}
if ($format == 'html') { $childValueOutput .= "</ul>\n"; }
}
if ($media == 'email') { $tableStyling = ''; } else { $tableStyling = ' class=\"entry-view-field-value\"'; }
if ($format == 'html') {
$tableContents .= "<tr>\n<td colspan=\"2\"".$tableStyling.">".$childValueOutput."</td>\n</tr>\n";
} else {
$tableContents .= $childValueOutput."\n";
}
}
}
if (!empty($tableContents)) {
if ($format == 'html') {
if ($media == 'email') { $tableStyling = ' width="100%" border="0" cellpadding="5" bgcolor="#FFFFFF"'; } else { $tableStyling = ' class="widefat fixed entry-detail-view"'; }
$output .= "<table cellspacing=\"0\"".$tableStyling.">\n";
$output .= $tableContents;
$output .= "</table>\n";
} else {
$output .= $tableContents."\n";
}
}
}
}
if ($count !== 0) {
if ($format == 'text') { $output = rtrim($output); }
return $output;
} else { return ''; }
}
public function get_value_merge_tag($value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br) {
$output = GF_Field_Repeater::get_value_entry_detail($raw_value, '', false, $format, 'email');
$output = preg_replace("/[\r\n]+/", "\n", $output);
return trim($output);
}
public function get_value_export($entry, $input_id = '', $use_text = false, $is_csv = false) {
if (empty($input_id)) { $input_id = $this->id; }
$output = rgar($entry, $input_id);
$output = GF_Field_Repeater::get_value_entry_detail($output, '', false, 'text', 'email');
$output = preg_replace("/[\r\n]+/", ", ", trim($output));
return $output;
}
public static function gform_hide_children($form) {
$form_id = $form['id'];
$repeaterChildren = Array();
$grid_modified = false;
$grid_meta = GFFormsModel::get_grid_column_meta($form_id);
foreach($form['fields'] as $key=>$field) {
if ($field->type == 'repeater') {
if (is_array($field->repeaterChildren)) { $repeaterChildren = array_merge($repeaterChildren, $field->repeaterChildren); }
} elseif ($field->type == 'repeater-end') { array_push($repeaterChildren, $field->id); }
if (!empty($repeaterChildren)) {
if (in_array($field->id, $repeaterChildren)) {
unset($form['fields'][$key]);
if (is_array($grid_meta)) {
$grid_pos = array_search($field->id, $grid_meta);
if ($grid_pos) {
$grid_modified = true;
unset($grid_meta[$grid_pos]);
}
}
}
}
}
if ($grid_modified) { GFFormsModel::update_grid_column_meta($form_id, $grid_meta); }
$form['fields'] = array_values($form['fields']);
return $form;
}
public static function gform_disable_ajax($args) {
$get_form = GFFormsModel::get_form_meta_by_id($args['form_id']);
$form = reset($get_form);
if (GF_Field_Repeater::get_field_index($form) !== false) {
$args['ajax'] = false;
}
return $args;
}
public static function gform_bypass_children_validation($form) {
if (GF_Field_Repeater::get_field_index($form) === false) { return $form; }
$repeaterChildren = Array();
foreach($form['fields'] as $key=>$field) {
if ($field->type == 'repeater') {
if (is_array($field->repeaterChildren)) { $repeaterChildren = array_merge($repeaterChildren, $field->repeaterChildren); }
}
if (!empty($repeaterChildren)) {
if (in_array($field->id, $repeaterChildren) && !$field->adminOnly) {
$form['fields'][$key]['adminOnly'] = true;
$form['fields'][$key]['repeaterChildValidationHidden'] = true;
}
}
}
return $form;
}
public static function gform_unhide_children_validation($form) {
if (GF_Field_Repeater::get_field_index($form) === false) { return $form; }
foreach($form['fields'] as $key=>$field) {
if ($field->repeaterChildValidationHidden) {
$form['fields'][$key]['adminOnly'] = false;
$form['fields'][$key]['repeaterChildValidationHidden'] = false;
}
}
return $form;
}
public static function get_field_index($form, $key = 'type', $value = 'repeater') {
if (is_array($form)) {
if (!array_key_exists('fields', $form)) { return false; }
} else { return false; }
foreach ($form['fields'] as $field_key=>$field_value) {
if (is_object($field_value)) {
if (property_exists($field_value, $key)) {
if ($field_value[$key] == $value) { return $field_key; }
}
}
}
return false;
}
public static function get_field_type($form, $id) {
$field_index = GF_Field_Repeater::get_field_index($form, 'id', $id);
if ($field_index !== false) { return $form['fields'][$field_index]['type']; }
return false;
}
public static function get_children_parems($form, $children_ids) {
foreach($form['fields'] as $key=>$value) {
if (in_array($value['id'], $children_ids)) {
if ($value['inputName']) {
$parems[$value['id']] = $value['inputName'];
} elseif ($value['inputs']) {
foreach($value['inputs'] as $key=>$value) {
if ($value['name']) { $parems[$value['id']] = $value['name']; }
}
}
}
}
if (!empty($parems)) { return $parems; } else { return false; }
}
public static function get_children_parem_values($form, $children_ids) {
global $wp_filter;
$children_parems = GF_Field_Repeater::get_children_parems($form, $children_ids);
if (empty($children_parems)) { return false; }
// Check the URL first
foreach($_GET as $url_key=>$url_value) {
$key = array_search($url_key, $children_parems);
if ($key !== false) {
$parems[$key][0] = $url_value;
} else {
$split_key = preg_split('/\D+\K/', $url_key);
$key = array_search($split_key[0], $children_parems);
if ($key !== false) { $parems[$key][$split_key[1]] = $url_value; }
}
}
// Then check the filters
foreach($wp_filter as $key=>$value) {
$split_key = preg_split('/^gform_field_value_+\K/', $key);
if (!empty($split_key[1])) {
$key1 = array_search($split_key[1], $children_parems);
if ($key1 !== false) {
$parems[$key1][0] = apply_filters($key, '');
} else {
$split_key2 = preg_split('/\D+\K/', $split_key[1]);
$key2 = array_search($split_key2[0], $children_parems);
if ($key2 !== false) { $parems[$key2][$split_key2[1]] = apply_filters($key, ''); }
}
}
}
if (!empty($parems)) { return $parems; } else { return false; }
}
}
GF_Fields::register(new GF_Field_Repeater());
I made a webmail php class to fetch my domain's webmail.
Everything runs perfectly except that when the email has embedded images (like signatures), the images are fetched with CID in their src and also are treated as attachments.
<img src="cid:auto_cid_2093934881" />
So i end up with a broken source image (in its original place in the email body) and an attachment of the same image that actually works. But i don't need the image to be an attachment, i just want the images to be shown in their places.
Can anyone help me fix this class so it can fetch the images correctly?
Here's my code to get a single email:
<?php
$uid=mysql_real_escape_string($_GET['email_id']);
ini_set("max_execution_time",360);
/* connect to server */
$hostname = '{***.com:143/notls}INBOX';
$username = 'fadi#***.com';
$password = '*******';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to domain:' . imap_last_error());
$overview = imap_fetch_overview($inbox,$uid,0);
$header = imap_headerinfo($inbox, $uid);
$fromaddr = $header->from[0]->mailbox . "#" . $header->from[0]->host;
$webmail = new Webmail();
$message = $webmail->getEmailBody($uid,$inbox);
$attachments = $webmail->extract_attachments($inbox,$uid);
$attach_hrefs = '';
if(count($attachments)!=0){
$target_dir = "emails/".$uid;
if (!is_dir($target_dir)) {
// dir doesn't exist, make it
mkdir($target_dir);
}
foreach($attachments as $at){
if($at[is_attachment]==1){
file_put_contents($target_dir.'/'.$at[filename], $at[attachment]);
$attach_hrefs .='<a target="new" href="'.$target_dir.'/'.$at[filename].'">'.$at[filename].'</a> ';
}
}
}
?>
Here's the webmail class:
<?php
class Webmail{
function getEmailBody($uid, $imap)
{
$body = $this->get_part($imap, $uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($imap, $uid, "TEXT/PLAIN");
}
return $body;
}
function get_part($imap, $uid, $mimetype, $structure = false, $partNumber = false)
{
if (!$structure) {
$structure = imap_fetchstructure($imap, $uid, FT_UID);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
switch ($structure->encoding) {
case 3:
return imap_base64($text);
case 4:
return imap_qprint($text);
default:
return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($imap, $uid, $mimetype, $subStruct, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
function get_mime_type($structure)
{
$primaryMimetype = ["TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER"];
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
function extract_attachments($connection, $message_number) {
$attachments = array();
$structure = imap_fetchstructure($connection, $message_number);
if(isset($structure->parts) && count($structure->parts)) {
for($i = 0; $i < count($structure->parts); $i++) {
$attachments[$i] = array(
'is_attachment' => false,
'filename' => '',
'name' => '',
'attachment' => ''
);
if($structure->parts[$i]->ifdparameters) {
foreach($structure->parts[$i]->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['filename'] = $object->value;
}
}
}
if($structure->parts[$i]->ifparameters) {
foreach($structure->parts[$i]->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$attachments[$i]['is_attachment'] = true;
$attachments[$i]['name'] = $object->value;
}
}
}
if($attachments[$i]['is_attachment']) {
$attachments[$i]['attachment'] = imap_fetchbody($connection, $message_number, $i+1);
if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
$attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
}
elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
$attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
}
}
}
}
return $attachments;
}
}
?>
Thanks in advance.
Try bellow class for fetch mail body with inline image
Note See get_mail_body($body_type = 'html') method in class to that store mail body inline image to local server you need to change it as you directory layout.
I hope this help you.
$email_message = new Email_message();
$mailbody = $email_message->get_mail_body();
;
class Email_message {
public $connection;
public $messageNumber;
public $bodyHTML = '';
public $bodyPlain = '';
public $attachments;
public $getAttachments = true;
public function __construct($config_data = array()) {
$this->connection = $config_data['connection'];
$this->messageNumber = isset($config_data['message_no'])?$config_data['message_no']:1;
}
public function fetch() {
$structure = #imap_fetchstructure($this->connection, $this->messageNumber);
if(!$structure) {
return false;
}
else {
if(isset($structure->parts)){
$this->recurse($structure->parts);
}
return true;
}
}
public function recurse($messageParts, $prefix = '', $index = 1, $fullPrefix = true) {
foreach($messageParts as $part) {
$partNumber = $prefix . $index;
if($part->type == 0) {
if($part->subtype == 'PLAIN') {
$this->bodyPlain .= $this->getPart($partNumber, $part->encoding);
}
else {
$this->bodyHTML .= $this->getPart($partNumber, $part->encoding);
}
}
elseif($part->type == 2) {
$msg = new Email_message(array('connection' =>$this->connection,'message_no'=>$this->messageNumber));
$msg->getAttachments = $this->getAttachments;
if(isset($part->parts)){
$msg->recurse($part->parts, $partNumber.'.', 0, false);
}
$this->attachments[] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => '',
'data' => $msg,
'inline' => false,
);
}
elseif(isset($part->parts)) {
if($fullPrefix) {
$this->recurse($part->parts, $prefix.$index.'.');
} else {
$this->recurse($part->parts, $prefix);
}
}
elseif($part->type > 2) {
if(isset($part->id)) {
$id = str_replace(array('<', '>'), '', $part->id);
$this->attachments[$id] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => $this->getFilenameFromPart($part),
'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
'inline' => true,
);
} else {
$this->attachments[] = array(
'type' => $part->type,
'subtype' => $part->subtype,
'filename' => $this->getFilenameFromPart($part),
'data' => $this->getAttachments ? $this->getPart($partNumber, $part->encoding) : '',
'inline' => false,
);
}
}
$index++;
}
}
function getPart($partNumber, $encoding) {
$data = imap_fetchbody($this->connection, $this->messageNumber, $partNumber);
switch($encoding) {
case 0: return $data; // 7BIT
case 1: return $data; // 8BIT
case 2: return $data; // BINARY
case 3: return base64_decode($data); // BASE64
case 4: return quoted_printable_decode($data); // QUOTED_PRINTABLE
case 5: return $data; // OTHER
}
}
function getFilenameFromPart($part) {
$filename = '';
if($part->ifdparameters) {
foreach($part->dparameters as $object) {
if(strtolower($object->attribute) == 'filename') {
$filename = $object->value;
}
}
}
if(!$filename && $part->ifparameters) {
foreach($part->parameters as $object) {
if(strtolower($object->attribute) == 'name') {
$filename = $object->value;
}
}
}
return $filename;
}
function get_mail_body($body_type = 'html')
{
$mail_body = '';
if($body_type == 'html'){
$this->fetch();
preg_match_all('/src="cid:(.*)"/Uims', $this->bodyHTML, $matches);
if(count($matches)) {
$search = array();
$replace = array();
foreach($matches[1] as $match) {
$unique_filename = time().".".strtolower($this->attachments[$match]['subtype']);
file_put_contents("./uploads/$unique_filename", $this->attachments[$match]['data']);
$search[] = "src=\"cid:$match\"";
$replace[] = "src='".base_url()."/uploads/$unique_filename'";
}
$this->bodyHTML = str_replace($search, $replace, $this->bodyHTML);
$mail_body = $this->bodyHTML;
}
}else{
$mail_body = $this->bodyPlain;
}
return $mail_body;
}
}
I want to locate the html and/or the plain text using the imap_fetchstructure.
I tried several solutions but the emails don't have always the same structure.
I'm actually using:
$message=imap_fetchbody($inbox, $number, "1.2.1");
if ($message== "") {
$message =imap_fetchbody($inbox, $number, "1.1");
}
if ($message== "") {
$message = imap_fetchbody($inbox, $number, "1");
}
$message = imap_qprint($body);
When trying this; the result is sometimes correct and sometimes returning The content of the attachements depending on the mail server.
So I want a solution based on Imap_fetchstructure.
I found an answer for my question:
function getBody($uid, $imap) {
$body = $this->get_part($imap, $uid, "TEXT/HTML");
// if HTML body is empty, try getting text body
if ($body == "") {
$body = $this->get_part($imap, $uid, "TEXT/PLAIN");
}
return $body;
}
function get_part($imap, $uid, $mimetype, $structure = false, $partNumber = false) {
if (!$structure) {
$structure = imap_fetchstructure($imap, $uid, FT_UID);
}
if ($structure) {
if ($mimetype == $this->get_mime_type($structure)) {
if (!$partNumber) {
$partNumber = 1;
}
$text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
switch ($structure->encoding) {
case 3: return imap_base64($text);
case 4: return imap_qprint($text);
default: return $text;
}
}
// multipart
if ($structure->type == 1) {
foreach ($structure->parts as $index => $subStruct) {
$prefix = "";
if ($partNumber) {
$prefix = $partNumber . ".";
}
$data = $this->get_part($imap, $uid, $mimetype, $subStruct,
$prefix. ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
function get_mime_type($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION",
"AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
You can use like this to separate from html and plaintext:
$inbox = imap_open($hostName,$userName,$pwd) or die('Cannot connect (Allow gmail IMAP): ' . imap_last_error());
$emails = imap_search($inbox,'UNSEEN');
if($emails){
rsort($emails);
foreach($emails as $email_number){
$structure = imap_fetchstructure($inbox, $email_number);
if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {// IF HTML
$part = $structure->parts[1];
$receivedEmailContent = imap_fetchbody($inbox,$email_number,2);
if($part->encoding == 3) {
$receivedEmailContent = imap_base64($receivedEmailContent);
} else if($part->encoding == 1) {
$receivedEmailContent = imap_8bit($receivedEmailContent);
} else {
$receivedEmailContent = imap_qprint($receivedEmailContent);
}
}else{//IF NOT HTML
$receivedEmailContent = imap_fetchbody($inbox,$email_number,1);
if($structure->type == 0){
$receivedEmailContent = imap_base64($receivedEmailContent);
}else{
$receivedEmailContent = imap_qprint($receivedEmailContent);
}
}
$receivedEmailContent = strip_tags($receivedEmailContent);
$header = imap_headerinfo ( $inbox, $email_number);
$receivedEmailTitle = $header->subject;
$receivedEmailSenderName = $header->from[0]->personal;
$receivedEmailSenderEmail = $header->from[0]->mailbox . "#" . $header->from[0]->host;
}
}
imap_close($inbox);