If the file is deleted, delete from the ElasticSearch index - php

I'm trying to make a piece of code that will be responsible for deleting an indexed file from the elasticsearch index, I pass with the indexed file md5(file name), to the id value. It is necessary to make sure that when deleting a file from a folder, the deletion code by id (md5) is executed. I wrote part of the script, but I understand that it is incorrect because if there is no file, then md5 will not be created, please help)
<?php
$path = __DIR__ . ("/uploads/Арне.pptx");
$filename = basename($path);
$md5 = md5_file($path);
print($md5); //Передаю переменную md5 в 'id' индексации elasticsearch
//echo 'MD5-хеш файла ' . $filename . ': ' . md5_file($path);
if (empty(md5_file($path))) {//Провожу проверку, если md5 не совпадает с именем файла в папке
$params = [ //Произвожу удаление индекса из ES
'index' => 'bower',
'id' => $md5
];
$respose = $client->delete($params);
} else {
echo '' . ' есть, файл существует';
}

You need to use the delete index method instead of deleting documents:
$params = ['index' => 'bower_' . $md5];
$response = $client->indices()->delete($params);

You can close the topic, the issue is resolved. Solved the problem: Iterating over the array in the uploads folder, and iterating over the elasticsearch array id, then used array_diff, compared the arrays to exclude files that are not in the uploads folder, but they were in the elasticsearch index

Related

Find string in text file then find 1st instance of another string then get the text that follows

I need to locate a string in a text file. Once found then find the first instance of a second string below the first string, then get the text that immediately follows the second string and add that text to a variable that I can use later.
Here is a sample of the text file I will need to search within ...
Tournament=Test
Number=897 // I need to locate this Number.
Currency=Primary
BuyIn=0.01+0.02
PrizeBonus=0
MultiplyBonus=No
Entrants=2
Late=0
Tickets=0
Removed=0
Rebuys=0
AddOns=0
RebuyCost=0+0
NetBonus=0
StopOnChop=No
Start=2020-03-02 04:07:56
Place2=Tuck (0)
Place1=TuckStream (0.02) // Then I need to locate "Place1=", then get the name that follows.
Stop=2020-03-02 04:08:47
Summary: I need to grab the Winner's name from a text file after locating the proper tournament number within the file. There are several tourneys stored in the same text file. The text file is updated after a tourney completes, then an event runs and provides me with the new tourney number in a string.
Right now I'm just grabbing all the contents of the file (like above) and posting the entire thing to discord with a webhook. I'd prefer to only post the Winner's name, "TuckStream" as in the sample above.
I also need to perform another action with just the Players name so I need it added to a $Winner variable (for instance). Here's the current code within the event handler that posts the entire contents of the file...
case "TourneyFinish":
fwrite($f,"Event = " . $event . "\n");
fwrite($f,"Name = " . $_POST["Name"] . "\n");
fwrite($f,"Number = " . $_POST["Number"] . "\n");
fwrite($f,"Time = " . $_POST["Time"] . "\n");
fwrite($f,"\n");
$TourneyName = $_POST["Name"];
// wait for file to be written to disk
sleep(10);
// find latest file
$path = "C:/TourneyResults";
$latest_ctime = 0;
$latest_filename = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
if (is_file($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_filename = $entry;
}
}
// post message in discord chan #tourney-annoucements
$getinfo = file_get_contents($path . "/" . $latest_filename);
$message = "**$TourneyName Results** \n $getinfo";
$data = ['content' => $message];
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents('https://discordapp.com/api/webhooks/mywebhook', false, $context);
break;
You can use preg_match_all to get both the number and the winner in one go.
$getinfo = file_get_contents($path . "/" . $latest_filename);
preg_match_all("/Number=(\d+).*?Place1=(.*?)\s/s", $getinfo, $info);
$message = "**$TourneyName Results** \nTournament Number " . $info[1][0] . "\nWinner " .$info[2][0];
echo $message;
returns:
**something undefined Results**
Tournament Number 897
Winner TuckStream
The regex pattern first finds Number and grabs the digits that follow with this part: Number=(\d+).
Then it skips ahead to Place1 with .*?, and use this part Place1=(.*?)\s to find the winners name.
The last part is /s which means it searches multi-lined.

Uploading a file into a Google Drive folder with PHP

I have successfully uploaded a file into Google Drive. However, I'm still not sure on how to upload it into a folder. I need to upload it into a folder structure which looks like this:
Stats
ACLLeauge
ACLSydney
Sorted
Unsorted
{Username}
{FileHere}
The {Username} field is a variable that I will pass through. The {FileHere} field is where the image needs to go. Here is my current code:
public function __construct()
{
$this->instance = new \Google_Client();
$this->instance->setApplicationName('DPStatsBot');
$this->instance->setDeveloperKey(Config::getInstance()->getDriveDeveloperKey());
$this->instance->setAuthConfigFile(Config::getInstance()->getClientSecret());
$this->instance->addScope('https://www.googleapis.com/auth/drive');
if(!file_exists(DP_STATS_BOT_DIR . '/' . Config::getInstance()->getAuthFile())) {
Printer::write('Please navigate to this URL and authenticate with Google: ' . PHP_EOL . $this->instance->createAuthUrl());
Printer::raw('Authentication Code: ');
$code = trim(fgets(STDIN));
$token = $this->instance->authenticate($code);
file_put_contents(DP_STATS_BOT_DIR . '/' . Config::getInstance()->getAuthFile(), $token);
Printer::write('Saved auth token');
$this->instance->setAccessToken($token);
}
else
{
$this->instance->setAccessToken(file_get_contents(DP_STATS_BOT_DIR . '/' . Config::getInstance()->getAuthFile()));
}
if($this->instance->isAccessTokenExpired())
{
$this->instance->refreshToken($this->instance->getRefreshToken());
file_put_contents(DP_STATS_BOT_DIR . '/' . Config::getInstance()->getAuthFile(), $this->instance->getAccessToken());
}
$this->drive_instance = new \Google_Service_Drive($this->instance);
}
public function upload($image, $dpname)
{
$file = new \Google_Service_Drive_DriveFile();
$file->setTitle($dpname . '_' . RandomString::string() . '.jpg');
$upload = $this->drive_instance->files->insert($file,
[
'data' => $image,
'mimeType' => 'image/jpg',
'uploadType' => 'media'
]);
return $upload;
}
If anyone has a suggestion please tell me!
Thanks
For this you have insert the folders in the order you wanted. So add the Stats under the Drive root folder and then add all the folders in the order you needed. For adding a folder, you need to give mimeType as 'application/vnd.google-apps.folder'. Check this link for more mimeType values. Here is an external referring link on how to insert a folder in Drive.
After adding all the required folders you can now insert the actual file under the {Username} folder. You can also refer to this page on how to insert a file in Drive.
Hope that helps!

php Scan function not returning results as expected after moving script path:

note.. all folders chmod set to 777 for testing.
Okay, so i have been trying to design a simple cloud storage file system in php.After users log in they can upload and browse files in their account.
I am having an issue with my php code that scans the user's storage area. I have a script called scan.php that is called to return all of the users files and folders that they saved.
I originally placed the scan script in the directory called files and it worked properly, when the user logged in the scan script scanned the users files using "scan(files/usernamevalue)".
However I decided that I would prefer to move the scan script inside the files area that way the php script would only have to call scan using "scan(usernamevalue)". However now my script does not return the users files and folders.
<?php
session_start();
$userfileloc = $_SESSION["activeuser"];
$dir = $userfileloc;
// Run the recursive function
$response = scan($dir);
// This function scans the files folder recursively, and builds a large array
function scan($dir)
{
$files = array();
// Is there actually such a folder/file?
$i=0;
if(file_exists($dir))
{
foreach(scandir($dir) as $f)
{
if(!$f || $f[0] === '.')
{
continue; // Ignore hidden files
}
if(!is_dir($dir . '/' . $f))
{
// It is a file
$files[] = array
(
"name" => $f,
"type" => "file",
"path" => $dir . '/' . $f,
"size" => filesize($dir . '/' . $f) // Gets the size of this file
);
//testing that code actually finding files
echo "type = file, ";
echo $f .", ";
echo $dir . '/' . $f. ", ";
echo filesize($dir . '/' . $f)." ";
echo"\n";
}
else
{
// The path is a folder
$files[] = array
(
"name" => $f,
"type" => "folder",
"path" => $dir . '/' . $f,
"items" => scan($dir . '/' . $f) // Recursively get the contents of the folder
);
//testing that code actually finding files
echo "type = folder, ";
echo $f .", ";
echo $dir . '/' . $f. ", ";
echo filesize($dir . '/' . $f)." ";
echo"\n";
}
}
}
else
{
echo "dir does not exist";
}
}
// Output the directory listing as JSON
if(!$response)
{ echo"failes to respond \n";}
header('Content-type: application/json');
echo json_encode(array(
"name" => $userfileloc,
"type" => "folder",
"path" => $dire,
"items" => $response
));
?>
As you can see i added i echoed out all of the results to see if there
was any error in the scan process, here is what i get from the output as you
can see the function returns null, but the files are being scanned, i cant
seem to figure out where i am going wrong. Your help would be greatly
appreciated. Thank you.
type = file, HotAirBalloonDash.png, test/HotAirBalloonDash.png, 658616
type = folder, New directory, test/New directory, 4096
type = file, Transparent.png, test/Transparent.png, 213
failes to respond
{"name":"test","type":"folder","path":null,"items":null}
You forgot to return files or folders in scan function, just echo values. That is the reason why you get null values in the response.
Possible solution is to return $files variable in all cases.

Check if file exist before renaming file upon upload

I need help with adding the feature to check whether a file exists when uploading.
This is how the upload.php code looks like for uploading:
$file_name = $HTTP_POST_FILES['ljudfil']['name'];
$random_digit=rand(0000,9999);
$mp3 ='.mp3';
$pdf ='.pdf';
$datum = date('Ymd');
$new_file_name=$random_digit.$file_name;
$target_path1 = $target_path . $orgnr . '_' . $gsm . $pdf;
$target_path3 = $target_path . 'AC' . $datum . $new_file_name . $mp3;
$target_path11 = $target_path4 . $orgnr . '_' . $gsm . $pdf;
$target_path33 = $target_path4 . 'AC' . $datum . $new_file_name . $mp3;
$targetljudfilftp = 'AC' . $datum . $new_file_name . $mp3;
move_uploaded_file($_FILES['avtalsfil1']['tmp_name'], $target_path1);
move_uploaded_file($_FILES["ljudfil"]["tmp_name"], $target_path3);
$sql = "INSERT INTO affarer (tid, cid, orgnr, ljudfilftp) VALUES
(CURDATE(),'$date','$cid','$orgnr', '$targetljudfilftp')";
As you can see, it renames the uploaded file including a random number.
Sometimes, it happens that it renames the file to a number that already exists.
When that happens, it overwrites the previous file on my server.
So, how can I add a function to check whether the target name exists before it is used for renaming?
You can use
if (file_exists($target_path1))
to verify whether a file exists.
You would do better, though, to change strategy and employ tempnam:
$target_path = tempnam ($target_path, 'AC' . $datum . $file_name . $mp3)
This will create a file such as "AC_2012_Anacreon.mp3_xTfKxy" but you have the guarantee of it being unique, while even using file_exists would expose you to the risk of a concurrency collision.
Of course the file no longer has a .mp3 extension, so you have to take it into account when you scan the directory and supply files for download.
A still not secure, but maybe easier way is this:
for(;;)
{
$newname = // some strategy to generate newname, including a random
if (!file_exists($newname))
touch($newname);
if (!filesize($newname))
break;
}
or you can use a lock file to guarantee no concurrency (and therefore, that file_exists will return the truth and it will stay the truth):
$fp = fopen('.flock', 'r+');
if (flock($fp, LOCK_EX))
{
for(;;)
{
$newname = // some strategy to generate newname, including a random
if (!file_exists($newname))
{
// this creates the file uniquely for us.
// all other writers will find the file already there
touch($newname);
}
}
flock($fp, LOCK_UN);
}
else
die("Locking error");
fclose($fp);
// $newname is now useable.
Use the file_exists builtin function.
You could change the way your random digists are created by using (for example) a time based method
$random_digit = microtime(TRUE);
You can use as below
$random_digit = time();
Instead off using 'rand' function which can generate a duplicated number, you can use 'uniqid'php function, it returns a unique id ( http://www.php.net/manual/en/function.uniqid.php ).
If you still want to use the 'rand' you can use 'file_exists' function with the generated file name as param ( http://www.php.net/manual/en/function.file-exists.php ), but if a file exists you must regenerate the file name, so you will iterate each time the file exists.
At last, think to use full time date('Ymdhis') format instead off date('Ymd'), it's also better to use timestamp by calling time() function ( http://www.php.net/manual/en/function.time.php )
Anas,
if (file_exists($random_digit)) {
$random_digit = rand(0000,9999);
}

Save 'Username' as Filename

I wonder whether someone could help me please.
I'm using Image Uploader from Aurigma, and to save the uploaded images, I've put this script together.
<?php
//This variable specifies relative path to the folder, where the gallery with uploaded files is located.
//Do not forget about the slash in the end of the folder name.
$galleryPath = 'UploadedFiles/';
require_once 'Includes/gallery_helper.php';
require_once 'ImageUploaderPHP/UploadHandler.class.php';
/**
* FileUploaded callback function
* #param $uploadedFile UploadedFile
*/
function onFileUploaded($uploadedFile) {
$packageFields = $uploadedFile->getPackage()->getPackageFields();
$userid = $packageFields["userid"];
$locationid= $packageFields["locationid"];
global $galleryPath;
$absGalleryPath = realpath($galleryPath) . DIRECTORY_SEPARATOR;
$absThumbnailsPath = $absGalleryPath . 'Thumbnails' . DIRECTORY_SEPARATOR;
if ($uploadedFile->getPackage()->getPackageIndex() == 0 && $uploadedFile->getIndex() == 0) {
initGallery($absGalleryPath, $absThumbnailsPath, FALSE);
}
$dirName = $_POST['folder'];
$dirName = preg_replace('/[^a-z0-9_\-\.()\[\]{}]/i', '_', $dirName);
if (!is_dir($absGalleryPath . $dirName)) {
mkdir($absGalleryPath . $dirName, 0777);
}
$path = rtrim($dirName, '/\\') . '/';
$originalFileName = $uploadedFile->getSourceName();
$files = $uploadedFile->getConvertedFiles();
// save converter 1
$sourceFileName = getSafeFileName($absGalleryPath, $originalFileName);
$sourceFile = $files[0];
/* #var $sourceFile ConvertedFile */
if ($sourceFile) {
$sourceFile->moveTo($absGalleryPath . $sourceFileName);
}
// save converter 2
$thumbnailFileName = getSafeFileName($absThumbnailsPath, $originalFileName);
$thumbnailFile = $files[1];
/* #var $thumbnailFile ConvertedFile */
if ($thumbnailFile) {
$thumbnailFile->moveTo($absThumbnailsPath . $thumbnailFileName);
}
//Load XML file which will keep information about files (image dimensions, description, etc).
//XML is used solely for brevity. In real-life application most likely you will use database instead.
$descriptions = new DOMDocument('1.0', 'utf-8');
$descriptions->load($absGalleryPath . 'files.xml');
//Save file info.
$xmlFile = $descriptions->createElement('file');
$xmlFile->setAttribute('name', $_POST['folder'] . '/' . $originalFileName);
$xmlFile->setAttribute('source', $sourceFileName);
$xmlFile->setAttribute('size', $uploadedFile->getSourceSize());
$xmlFile->setAttribute('originalname', $originalFileName);
$xmlFile->setAttribute('thumbnail', $thumbnailFileName);
$xmlFile->setAttribute('description', $uploadedFile->getDescription());
//Add additional fields
$xmlFile->setAttribute('userid', $userid);
$xmlFile->setAttribute('locationid', $locationid);
$xmlFile->setAttribute('folder', $dirName);
$descriptions->documentElement->appendChild($xmlFile);
$descriptions->save($absGalleryPath . 'files.xml');
}
$uh = new UploadHandler();
$uh->setFileUploadedCallback('onFileUploaded');
$uh->processRequest();
?>
What I'd like to do is replace the files element of the filename and replace it with the username, so each saved folder and associated files can be indentified to each user.
I've added a username text field to the form which this script saves from
I think I'm right in saying that this is line that needs to change $descriptions->save($absGalleryPath . 'files.xml');.
So amongst many attempts I've tried changing this to $descriptions->save($absGalleryPath . '$username.xml, $descriptions->save($absGalleryPath . $username '.xml, but none of these have worked, so I'm not quite sure what I need to change.
I just wondered whether someone could perhaps have a look at this please and let me know where I'm going wrong.
Many thanks
'$username.xml' will be interpreted as $username.xml, you need to use "$username.xml". Single quotes "disable" the variable use inside strings.
What you are tryiing can be a bad idea, as you are making so a username can't contain 'special characters' like "/". Perhaps is not a problem if you aready have a rule that stop "/" being part of a username.

Categories