Im at a bit of a loss, i have 2 scripts 1 which pulls email attachments from a mailbox and a second one which then parses the attachments and adds them to the DB.
This works ok most of the time, but is throwing up a few issues every now an again. Sometimes the email attachment is created, but not populated (blank file except for the name) and sometimes its just not created (downloaded) at all.
The first script opens a new file and writes to it, the second script then accesses the content of that file. Could these issues be because the file is still open when the second script is attempting to access it?
They run alternatively every 15 seconds.
1st script (its pretty big so i have attempted to just show the parts in question)
for ($jk = 1; $jk <= imap_num_msg($mbox); $jk++) {
echo "~~~~~~~~~~~~~~BEGIN!~~~~~~~~~~~~~~~~~~\n";
echo imap_num_msg($mbox);
$structure = imap_fetchstructure($mbox,$jk); echo "imap_fetchstructure()\n";
$parts = $structure->parts; echo "structure->parts\n";
$fpos=2;
for($i = 1; $i < count($parts); $i++) { echo "loop through parts of email\n";
$message["pid"][$i] = ($i);
$part = $parts[$i];
if($part->disposition == "ATTACHMENT") { echo "if ATTACHMENT exists then grab data from it\n";
$message["type"][$i] = $message["attachment"]["type"][$part->type] . "/" . strtolower($part->subtype);
$message["subtype"][$i] = strtolower($part->subtype);
$ext=$part->subtype;
$params = $part->dparameters;
$filename=$part->dparameters[0]->value;
$num = $this->append();
$newFilename = $this->addToDB($filename,$num);
echo $newFilename."- Added tp DB\n";
$mege="";
$data="";
$mege = imap_fetchbody($mbox,$jk,$fpos);
$filename="$newFilename";
$fp=fopen($savedirpath.$filename,w); echo "Create file at specified location\n";
$data=$this->getdecodevalue($mege,$part->type);
fputs($fp,$data); echo "Write data to the file\n";
echo ">>>>>>>>>>>>> File ".$savedirpath.$newFilename." ~ now exists!\n";
fclose($fp);
$fpos+=1;
imap_mail_move($mbox,'1:1','Processed');
echo "****************************************************\n";
echo "* Matched - Download and move to Processed folder. *\n";
echo "****************************************************\n";
echo "\n\n\n";
}
}
}
}else{
imap_mail_move($mbox,'1:1','Other');
echo "***************************************************\n";
echo "******** No Match - Move to Other folder **********\n";
echo "***************************************************\n";
}
imap_close($mbox);
}
The 2nd script does a bunch of parsing by taking file names added to the db in the 1st script, then sticking them into the following.
$addXML = "<xml>".file_get_contents($filename)."</xml>";
$tickets = simplexml_load_string($addXML);
For anyone who might encounter something similar, i figured out why certain files where appearing blank.
The blank files that where being created where coming from emails that had multiple email attachments. It worked fine with single attachments and the first attachment in multiple attachment emails.
for($i = 1; $i < count($parts); $i++) { echo "loop through parts of email\n";
//some code
if($part->disposition == "ATTACHMENT") { echo "if ATTACHMENT exists then grab data from it\n";
//bunch of code that gets the attachment using the section number
imap_mail_move($mbox,'1:1','Processed');
echo "****************************************************\n";
echo "* Matched - Download and move to Processed folder. *\n";
echo "****************************************************\n";
echo "\n\n\n";
}
}
Basically to get multiple attachments this part loops, but i had the imap_mail_move() function in the loop so the email was moved to a different folder before any other iteration could do its stuff for the other email attachments, hence the blank files
D'oh!
As for it skipping certain emails, i was having a play about with
for ($jk = 1; $jk <= imap_num_msg($mbox); $jk++) { }
It turned out that this was crapping out after about 4 iterations, causing some of the emails to be skipped. At this point im not sure why, however for my purposes i don't actually need this for loop so i have removed it.
I know this was a daft mistake on my part regarding the imap_mail_move(), but i decided to post this in case it might help anyone else in future.
Related
I need to download all photos about estates from an XML to save on the server. Every estate child in the XMl has a general section with all information and then a node called Foto (estate's photos) and another one for plans (Planimetria). The link of every image is structured as is:
<Link>http://www.site.it/ImageView.ashx?id=[photoID]&reduce=1438[can be set as I want es: 1000, 960, 1080]</Link>
I need to call it inside the $url_photo and $url_plan so I can read the photoID from XML and set resolution (1438,1000,960) with a global variable.
This is my code:
<?php
$xml = simplexml_load_file("Schede.xml"); // your xml
$path = '/mnt/c/Users/Giuseppe/Desktop/FotoTest/';
$i = 1;
$resolution = '1000';
// Estate Image
foreach($xml->CR03_SCHEDE as $estate){
//if((string) $estate['ELIMINATO'] = "NO"){
echo "\nEstate n $i Images\n";
foreach($estate->Foto->CR04_SCHEDE_FOTO as $photo){
$url_photo = (string) $photo->Link;
$filename_photo = basename($photo->CR04_FILENAME); // get the filename
if(file_exists($path . $filename_photo)) {
echo "file $filename_photo already exists \n";
}
else {
$img_photo = file_get_contents($url_photo); // get the image from the url
file_put_contents($path . $filename_photo, $img_photo); // create a file and feed the image
echo "file $filename_photo created \n";
}
}
// Plans
echo "\nEstate n $i plans\n";
foreach($estate->Planimetria->CR04_SCHEDE_FOTO as $plan) {
$url_plan = (string) $plan->'http: // www.site.it/ImageView.ashx?id=' . $plan->ID . '&reduce=' . $resolution; //$plan->Link;
$filename_plan = basename($plan->CR04_FILENAME);
if(file_exists($path . $filename_plan)) {
echo "file planimetry $filename_plan already exists \n";
}
else {
$img_plan = file_get_contents($url_plan); // get the image from the url
file_put_contents($path . $filename_plan, $img_plan); // create a file and feed the image
echo "file planimetry $filename_plan created \n";
}
}
$i++;
/*}
else{
echo "$estate->attributes(Riferimento)"."Deleted\n";
}*/
}
?>
I also have a problem with the first if commented:
if((string) $estate['ELIMINATO'] = "NO")...
Eliminato is an attribute of CR03_SCHEDE but the script won't read it and in any case go inside the if.
The complete XML has about 70/80 properties and the foreach works well to download all images, but I need that it should download the only one that has that attribute equals to NO
This is the example of XML (only one estate): link
Thanks to all
This is a classic mistake:
if((string) $estate['ELIMINATO'] = "NO")
You used the assignment operator instead of the comparison operator. Please use this exact form:
if ('NO' == (string)$estate['ELIMINATO'])
I'm facing strange problem right now - "filesize(): stat failed for C:\xampp\tmp\php7A38.tmp" exception. The problem occurs when I'm uploading files in my application built with PHP (Laravel).
Before I'm uploading the files onto the server I'm checking size of files like this (this works very well):
for ($i = 0; $i < $filesLength; $i++) {
if(filesize($request['files'][$i]) < 1572865) {
$file = $request['files'][$i];
$filename = $imageNumber.'.'.$request['files'][$i]->extension();
$file = $file->move(public_path().'/app/newsimages/'.$element->id.'/', $filename);
}
}
If I do it like that everything works very well. But the problem is that I have to put this loop in another loop, like this:
foreach($somelement as $element) {
for ($i = 0; $i < $filesLength; $i++) {
if(filesize($request['files'][$i]) < 1572865) {
$file = $request['files'][$i];
$filename = $imageNumber.'.'.$request['files'][$i]->extension();
$file = $file->move(public_path().'/app/newsimages/'.$element->id.'/', $filename);
}
}
}
In addition to that it crashes at the second loop of the foreach loop.
Maybe you have some idea what's wrong in here?
I think this is obvious, in inner loop you move the file, so when you go to next iteration of outer loop file is not there, so for example if you once move the file:
$request['files'][0]
it's not possible to execute:
filesize($request['files'][0])
because this file was moved - it doesn't exist any more.
I am trying to write a function that counts the image while looping through the files for one case (out of many cases), I declared the variable $imageCount global within the function copyInsertImage so that after the image is successfully inserted into the database, I do an $imageCount++.
After processing all the images for the case, the code exits the loop, the function processImages will be recalled again. However, I did a var_dump($imageCount) to print out the image count each time it gets increased by one, and found out that it was never reset back to 0 by the $imageCount = 0 when running the loop for a new case.
I am wondering if declaring global $imageCount has anything to do with it, because the code worked fine previously before grouping the same script into a function. If so, what is the solution?
Thanks!
function processImages($path,$patientID,$caseID)
{
// $path = rootDirectory/patientID
global $targetDirectory;
$targetPath = $targetDirectory.$patientID;
$caseSummaryFolder = $path."/".$caseID."/Summary";
$srcDirPath=$path."/".$caseID."/Summary/slicesdir"; //AKA src
$dstDirPath = $targetPath."/".$caseID;
//copyCaseImages($caseSummaryFolder,$targetCasePath,$patientID,$caseID);
global $status;
// print("processImages case path:".$casePath."</br>");
$files = glob($srcDirPath."/*.png");
echo "\n------------NEW CASE------------\n"
echo "PATIENT: $patientID \n";
echo "CASE: $caseID \n";
echo "--------------------------------\n"
$imageCount = 0;
for($i = 0; $i < count($files); $i++) {
$file = $files[$i];
$fileName = str_ireplace($srcDirPath."/", "", $file);
// if image name doesn't not contain string 'GROT'
if(strripos($fileName, "grot") === false)
{
if(doesImgExist($fileName)!==NULL) {
if (compareFileMTime($srcDirPath,$fileName,doesImgExist($fileName))) {
echo "There's a newer version of $fileName \n";
copyInsertImage($srcDirPath,$dstDirPath,$fileName,$patientID,$caseID);
}
else {
$imageCount++;
}
}
// copy image to analyzedCp and insert new image into DB
else {
copyInsertImage($srcDirPath,$dstDirPath,$fileName,$patientID,$caseID);
}
}
else {
echo "grot*.png files are not included \n";
}
}
If I understood your question correctly, it seems like you are redeclaring "global $imageCount" inside of your "copyInsertImage" function and this function is part of the for-loop. If this is indeed what you have then a problem is that everything time your for-loop hits the "copyInsertImage" function it will take re-declare $imageCount, this re-declaration will make imageCount a new variable and clear whatever you have stored in it. This could be the reason why you are seeing $imageCount = 0.
#andrewsi Answered my question.
My question was solved by declaring the initial $imageCount as global too.
"if you're using globals, you need to declare them as global in every function that uses them. Otherwise, you end up using a local variable with the same name. This is one of the reasons to try to avoid them if possible - it's easier to pass variables into functions when you need them."
Thanks!
I have this page where you can send message to multiple people and attach files into it...
Here is my code
<?php
session_start();
$inboxfrom = $_SESSION['loginusername'];
$inboxto = $_POST['inboxto'];
$inboxsubject = $_POST['inboxsubject'];
$inboxcontent = $_POST['inboxcontent'];
$inboxtime = date('g:i A', time()+(6*60*60));
$inboxdate = date('Y-m-d', time()+(6*60*60));
mysql_connect("127.0.0.1", "root", "")or die("Cannot Connect toDb");
mysql_select_db("Abbot_db");
$count = 0;
function generateRandomString($length = 8){
$string = "";
$possible = "0123456789bcdfghjkmnpqrstvwxyz"; //character that can be used
for($i=0;$i < $length;$i++){
$char = substr($possible, rand(0, strlen($possible)-1), 1);
if (!strstr($string, $char)){
$string .= $char;
}
}
return $string;
}
if (count($inboxto) != 0){
$count = 0;
while ($count < count($inboxto)){
$recepient = $_POST['inboxto'][$count];
mysql_query("INSERT INTO Inbox_tbl(InboxTo, InboxFrom, InboxSubject, InboxContent, InboxTime, InboxDate,InboxStatus,ToDelete,FromDelete)VALUES ('$recepient','$inboxfrom','$inboxsubject','$inboxcontent','$inboxtime','$inboxdate','Unread','No','No')");
$recepient_result = mysql_query("SELECT * FROM Accounts_tbl WHERE UserID='$recepient'");
if (mysql_result($recepient_result, 0, "UserTypeID") == 1){
$notiurl = "LMSadmin_inbox.php";
} else if (mysql_result($recepient_result, 0, "UserTypeID") == 2) {
$notiurl = "LMSteacher_inbox.php";
} else {
$notiurl = "LMSstud_inbox.php";
}
mysql_query("INSERT INTO Noti_tbl(NotiTo,NotiFrom,NotiContent,NotiDate,NotiTime,NotiType,NotiUrl)
VALUES('$recepient','$inboxfrom','has sent you a message','$inboxdate','$inboxtime','Message','$notiurl')");
//---------------------------------------------------------
$countto = 0;
$cont = generateRandomString(128);
$folder = "./Attachments/".$cont;
$name = $_FILES['file']['name'];
if (!empty($name)){
while (is_dir($folder)){
$cont = generateRandomString(128);
$folder = "./Attachments/".$cont;
}
mkdir($folder, 0700, true);
}
while ($countto < count($_FILES['file']['name'])){
$name = $_FILES['file']['name'][$countto];
$type = $_FILES['file']['type'][$countto];
$tmp_name = $_FILES['file']['tmp_name'][$countto];
$folder = "Attachments/".$cont."/";
move_uploaded_file($tmp_name, $folder.$name);
$fileurl = $cont."/".$name;
$dummypost = mysql_query("SELECT * FROM Inbox_tbl ORDER BY InboxID DESC");
$msgid = mysql_result($dummypost, 0, "InboxID");
mysql_query("INSERT INTO Attachments_tbl(FileUrl,FileName,AttachType,AttachID)
VALUES('$fileurl','$name','Message',$msgid)");
$countto++;
}
//----------------------------------------------
$count++;
}
}
header('Location: ' . $_SERVER['HTTP_REFERER']);
?>
now the result after I put multiple recepients and multiples is that... The first recepient will get the attachments.. meaning the folder of attachment will be randomy generated and the files would be put in there.... but on the next recepient the attachments would not be moved on their respective folder.. I can see the folder have been made but the files arent moved..
MY question is.. does the "temp_name" disappear after you use the "move_uploaded_file" code? Because I think thats is the reason the files arent not move.. Is so can you suggest any alternate code i can use?
move_uploaded_file() relocates the file to the set target location with rendering the tmp_name useless afterwards.
What you should do is to create a "puffer" folder where you originally move the uploaded file, and then call copy() as many times as you need to deliver the file to the recipient folders. When the file is put to every needed location, you can unlink() the file from this puffer folder.
Alternatively, you might put the file to only one location (to eliminate redundancy and overuse of storage space), and make links in your Attachments_tbl to this same file in a set attachments folder. However, this needs remodelling of how your system works to make sure that the (now one and only) attachment file is only removed after every record pointing to it is removed also.
Yes, the file is moved, this is why you can't find it. I suggest that you:
Move the inner while loop (the one for the uploaded files) before the first while loop (for the recipients), and move the uploaded files to a location that you specify
Create a new inner while loop that copies the files from the location you specified earlier to each user's attachments folder
I have a simple page, which is sending an Email message and multiple attachments, through phpmailer.
I have to attach the multiple attachments to the Email message to send, and also upload these files o server at same time, For which i m using the following loop:
$MyUploads = array();
foreach(array_keys($_FILES['attach']['name']) as $key)
{ $Location="uploads/";
$name=$_FILES['attach']['name'][$key];
$filePath = $Location . $name;
$source = $_FILES['attach']['tmp_name'][$key]; // location of PHP's temporary file for
$tmp=$_FILES['attach']['tmp_name'][$key];
if($mail->AddAttachment($source, $name))
{if(move_uploaded_file($tmp, $filePath)){
$MyUploads[] = $filePath;}
else
{$MyUploads[]='';
echo "not uploaded";}
}
}
The problem is, when i use the function move_uploaded_file(), the files are uploaded to the server folder, but are not sent with the attachments. As i comment out this function the attachments are sended.
Can;t find out, why these two dnt work together. Please any body help
Here is the loop that sends Attachments, And move them to a target path, for further use. I hope any one else can be helped by this:
$MyUploads = array();
$numFiles = count(array_filter($_FILES['attach']['name']));
for ($i = 0; $i < $numFiles; ++$i) {
$target_path = 'uploads/' . basename($_FILES['attach']['name'][$i]);
if(move_uploaded_file($_FILES['attach']['tmp_name'][$i], $target_path)) {
echo "the file ".basename($_FILES['attach']['name'][$i])." has been uploaded<br />";
$MyUploads[] = $target_path;
echo $MyUploads;
$mail->AddAttachment($target_path);
}
}