mysql - php - remove first part of url upon INSERT - php

Im doing an image gallery CMS using Mysql database and PHP. Im a newbie.
Im having a path problem.
here is my file structure:
this php doc - root/php/upload_portrait.php.
My images are stored here - root/images/portrait_gallery/
So I added the ../ to save the images in root/images/portrait_gallery/
that works fine.
but in the db the url is stored with the ../ and that path is incorrect since they are being called from the root index file. So no images show up.
HOW can I remove the ../ upon INSERT INTO in the database??
I have tried with replace and update but cant figure out how.
Here Is my code
$portrait_url= $_FILES['upload'];
// 2. connect to database:
include 'connect.php';
// 4. handle moving image from temp location to images folder (using the function billedupload)
$billedurl = billedupload($portrait_url);
if($billedurl == false){
die("Something is wrong");
}
// 5. Insert imageupload in database:
$query = "INSERT INTO portrait (portrait_id, portrait_url) VALUES ('$portrait_id', '$billedurl')";
$result = mysqli_query($dblink, $query) or die( "Forespørgsel 2 kunne ikke udføres: " . mysqli_error($dblink) );
// 6. close connection
mysqli_close($dblink);
function billedupload($filearray){
if($filearray['type']=='image/jpeg' or $filearray['type']=='image/png'){
$tmp_navn = $filearray['tmp_name'];
$filnavn = $filearray['name'];
$url = '../images/portrait_gallery/' . time() . $filnavn;
move_uploaded_file($tmp_navn, $url);
return $url;
}
else{
return false;
}
}

I believe you have 2 choices.
Alter the $url line of billed upload() and remove the ../ there, since you know you won't need it when you go to read it.
Alter your function that reads from the database and remove the ../ there.
str_replace() is probably the function you need, as mentioned by previous poster.

If all you need to to remove '/..' -- then,
str_replace is a function in PHP that allows you to remove/change parts of strings on the fly, so, in your code,
replace
$billedurl = billedupload($portrait_url);
with
$billedurl = str_replace('/..','',billedupload($portrait_url));

Related

Remove Prestashop orphan images not stored in DB

I need to clean a shop running Prestashop, actually 1.7, since many years.
With this script I removed all the images in the DB not connected to any product.
But there are many files not listed in the DB. For example, actually I have 5 image sizes in settings, so new products shows 6 files in the folder (the 5 above and the imageID.jpg file) but some old product had up to 18 files. Many of these old products have been deleted but in the folder I still find all the other formats, like "2026-small-cart.jpg".
So I tried creating a script to loop in folders, check image files in it and verify if that id_image is stored in the DB.
If not, I can delete the file.
It works but obviously the loop is huge and it stops working as long as I change the starting path folder.
I've tried to reduce the DB queries storing some data (to delete all the images with the same id with a single DB query), but it still crashes as I change the starting path.
It only works with two nested loops (really few...).
Here is the code. Any idea for a better way to get the result?
Thanks!
$shop_root = $_SERVER['DOCUMENT_ROOT'].'/';
include('./config/config.inc.php');
include('./init.php');
$image_folder = 'img/p/';
$image_folder = 'img/p/2/0/3/2/'; // TEST, existing product
$image_folder = 'img/p/2/0/2/6/'; // TEST, product deleted from DB but files in folder
//$image_folder = 'img/p/2/0/2/'; // test, not working...
$scan_dir = $shop_root.$image_folder;
// will check only images...
global $imgExt;
$imgExt = array("jpg","png","gif","jpeg");
// to avoid multiple queries for the same image id...
global $lastID;
global $delMode;
echo "<h1>Examined folder: $image_folder</h1>\r\n";
function checkFile($scan_dir,$name) {
global $lastID;
global $delMode;
$path = $scan_dir.$name;
$ext = substr($name,strripos($name,".")+1);
// if is an image and file name starts with a number
if (in_array($ext,$imgExt) && (int)$name>0){
// avoid extra queries...
if ($lastID == (int)$name) {
$inDb = $lastID;
} else {
$inDb = (int)Db::getInstance()->getValue('SELECT id_product FROM '._DB_PREFIX_.'image WHERE id_image ='.((int) $name));
$lastID = (int)$name;
$delMode = $inDb;
}
// if haven't found an id_product in the DB for that id_image
if ($delMode<1){
echo "- $path has no related product in the DB I'll DELETE IT<br>\r\n";
//unlink($path);
}
}
}
function checkDir($scan_dir,$name2) {
echo "<h3>Elements found in the folder <i>$scan_dir$name2</i>:</h3>\r\n";
$files = array_values(array_diff(scandir($scan_dir.$name2.'/'), array('..', '.')));
foreach ($files as $key => $name) {
$path = $scan_dir.$name;
if (is_dir($path)) {
// new loop in the subfolder
checkDir($scan_dir,$name);
} else {
// is a file, I'll check if must be deleted
checkFile($scan_dir,$name);
}
}
}
checkDir($scan_dir,'');
I would create two files with lists of images.
The first file is the result of a query from your database of every image file referenced in your data.
mysql -BN -e "select distinct id_image from ${DB}.${DB_PREFIX}image" > all_image_ids
(set the shell variables for DB and DB_PREFIX first)
The second file is every image file currently in your directories. Include only files that start with a digit and have an image extension.
find img/p -name '[0-9]*.{jpg,png,gif,jpeg}' > all_image_files
For each filename, check if it's in the list of image ids. If not, then output the command to delete the file.
cat all_image_files | while read filename ; do
# strip the directory name and convert filename to an integer value
b=$(basename $filename)
image_id=$((${b/.*/}))
grep -q "^${image_id}$" all_image_ids || echo "rm ${filename}"
done > files_to_delete
Read the file files_to_delete to visually check that the list looks right. Then run that file as a shell script:
sh files_to_delete
Note I have not tested this solution, but it should give you something to experiment with.

Windows Indexing Search through PHP Doesn't Return Images

I'm using Windows Indexing search together with PHP to search inside thousands of files.
I got it working by using the PHP COM class.
But the problem is that the search result only return found txt, docx, pdf and document types of files. It doesn't return images or videos no matter what properties I tried searching.
When I search for 001 as the string:
actual result: y:/sample001.txt, y:/book001.pdf
Expect to also see: y:/picture001.jpg
But the result doesn't show jpg or any other types of media files.
Why did it not search for images (or videos)?
Thanks in advance for any help.
<?php # searchfunction.php
function comsearch($string){
$path = "file:y:/";
$conn = new COM("ADODB.Connection") or die("Cannot start ADO");
$recordset = new COM("ADODB.Recordset");
//setting the limit for the query
$recordset->MaxRecords = 1000;
$conn->Open("Provider=Search.CollatorDSO;Extended Properties='Application=Windows';");
//creating the query against windows search indexer database.
//we specify the path and the string we are looking for
$recordset->Open("SELECT System.FileName, System.ItemPathDisplay, System.FileExtension FROM SYSTEMINDEX WHERE SCOPE='".$path."' AND CONTAINS('".$string."') AND System.FileExtension='.jpg'", $conn);
if(!$recordset->EOF){
$recordset->MoveFirst();
}
$files = array();
while(!$recordset->EOF) {
$filename = $recordset->Fields->Item("System.FileName")->value;
$files[]= $filename;
$recordset->MoveNext();
}
return $files;
}
?>
The code above returns nothing at all with the condition System.FileExtension='.jpg' even when I have thousands of .jpg in my directory.
But when I try it without this condition, the result successfully returns txt, pdf and other document types of files in the same directory.
What did I do wrong?

Using PHP how can you tell if the image already exists on your server regardless of name?

I have seen several websites where if you upload an image and an identical image already exists on there servers they will reject the submission. Using PNGs is there an easy way to check one image against a massive folder of images?
http://www.imagemagick.org/discourse-server/viewtopic.php?t=12618
I did find this with imagemagick, but I am looking for one vs many and not one to one a million
You can transform the file content into a sha1. That will give you a way to identify two pictures strictly identical.
see http://php.net/manual/fr/function.sha1-file.php
Then after you save it into a NFS, or use some kind of database to test if the hash already exists.
Details of the images are probably maintained in a database; while the images are stored in the filesystem. And that database probably has a hash column which is used to store an md5 hash of the image file itself, calculated when the image is first uploaded. When a new image is uploaded, it calculates the hash for that image, and then checks to see if any other image detail in the database has a matching hash. If not, it stores the newly uploaded image with that hash; otherwise it can respond with details of the previous upload. If the hash column is indexed in the table, then this check is pretty quick.
If I understood your question correctly. You want to find out if a specific image exists in a Directory with so many images, right? If so, take a look at the solution:
<?php
// CREATE A FUNCTION WHICH RETURNS AN ARRAY OF ALL IMAGES IN A SPECIFIC FOLDER
function getAllImagesInFolder($dir_full_path){
$returnable = array();
$files_in_dir = scandir($dir_full_path);
$reg_fx = '#(\.png|\.jpg|\.bmp|\.gif|\.jpeg)#';
foreach($files_in_dir as $key=>$val){
$temp_file_or_dir = $dir_full_path . DIRECTORY_SEPARATOR . $val;
if(is_file($temp_file_or_dir) && preg_match($reg_fx, $val) ){
$regx_dot_wateva = '/\.{2,4}$/';
$regx_dot = '/\./';
$regx_array = array($regx_dot_wateva, $regx_dot);
$replace_array = array("", "_");
$return_val = preg_replace($regx_array, $replace_array, $val);
$returnable[$return_val] = $temp_file_or_dir ;
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
}
return $returnable;
}
// CREATE ANOTHER FUNCTION TO CHECK IF THE SPECIFIED IMAGE EXISTS IN THE GIVEN DIRECTORY.
// THE FIRST PARAMETER SHOULD BE THE RESULT OF CALLING THE PREVIOUS FUNCTION: getAllImagesInFolder(...)
// THE SECOND PARAMETER IS THE IMAGE YOU WANT TO SEARCH WHETHER IT EXISTS IN THE SAID FOLDER OR NOT
function imageExistsInFolder($arrImagesInFolder, $searchedImage){
if(!is_array($arrImagesInFolder) && count($arrImagesInFolder) < 1){
return false;
}
foreach($arrImagesInFolder as $strKey=>$imgPath){
if(stristr($imgPath, $searchedImage)){
return true;
}
}
return false;
}
// NOW GET ALL THE IMAGES IN A SPECIFIED FOLDER AND ASSIGN THE RESULTING ARRAY TO A VARIABLE: $imgFiles
$imgFolder = "/path/to/directory/where/there/are/images";
$arrImgFiles = getAllImagesInFolder($imgFolder);
$searchedImage = "sandwich.jpg"; //<== OR EVEN WITHOUT THE EXTENSION, JUST "sandwich"
// ASSUMING THE SPECIFIC IMAGE YOU WANT TO MATCH IS CALLED sandwich.jpg
// YOU CAN USE THE imageExistsInFolder(...) FUNCTION TO RETURN A BOOLEAN FLAG OF true OR false
// DEPENDING ON IF IT DOES OR NOT.
var_dump($arrImgFiles);
var_dump( imageExistsInFolder($arrImgFiles, $searchedImage) );

Copy single template to multiple file names

I'm having a little trouble with a multi file creation. I've taken the code
from my another project that actually creates pages one at a time in order.
Trying to get it to create multiple pages of a given template.php file.
I'm not getting any errors in the logs and nothing in destination.
With not understanding loops well enough it's getting lost.
Thanks in advance
<?php
// copy template.php -> page1.php, page2.php, page3.php etc...
$area = $_POST["area"];
// Get number of needed pages
$numberofpages = $_POST["pagenumber"];
// Location of template.php
$templatelocation = "/var/work.files/template.php";
// Send copied files to the requested location.
$filedestination = "/var/work.files/$area";
for ($i = 1; $i < $numberofpages; ++$i) {
// Check if file name is already there. If there is continue to next in order
if (!file_exists($filedestination . '/page'. $i . '.php')) {
// get filename and copy template to it ...
$filename = "page$i.php";
copy('$templatelocation', '$filedestination/$filename');
//continue until number of requested pages created
}
}
?>
You used quotes incorrectly in your code.
Variables are not interpolated inside single quotes.
Change
copy('$templatelocation', '$filedestination/$filename');
to
copy($templatelocation, "$filedestination/$filename");
Your code is incorrect just remove the quotes '' and insert another type of quotes "".
copy($templatelocation, $filedestination."/".$filename);
OR
copy($templatelocation, "$filedestination/$filename");
instead of
copy('$templatelocation', '$filedestination/$filename');
Hope this helps you

Deleting Files In A Directory Based On A Table

First of all, i would like to explain my condition right now.
I'm using PHP as my programming language.
I have a table named "Produk". It keeps every product name. Example value "TWC0001" in its id_produk column.
Every product have its own images, and stored in ./images/Produk/ directory.
the problem is, this project has been working about 1 years ago, and when the users delete a product, the product's images didn't deleted too. So, it still staying in ./images/Produk/ directory. It means, that file become a garbage right?
Case Example :
in the "Produk" table, column "id_produk" i have 3 rows :
"TWC0001","TWC0002","TWC0003".
Of course each of those rows have its own images that stored in ./images/Produk/
Each of those files named :
"TWC0001.jpg", "TWC0002.jpg", "TWC0003.jpg"
Case : A user logged in and deleted row "TWC0002", of course the "TWC0002.jpg" file still exist.
Problem : I want to delete all ".jpg" files that didn't listed in the "Produk" table anymore.
I've been doing this :
//listing all the ".jpg" files
$arrayfiles=scandir("../images/Produk/");
//getting all the product list
$sql="select * from produk";
$produk=mysql_query($sql,$conn) or die("Error : ".mysql_error());
foreach($arrayfiles as $key=>$value)
{
while($row=mysql_fetch_array($produk,MYSQL_ASSOC))
{
///here is the part i've been confused of.
}
}
PHP function to delete file is "unlink()";
Please anybody help me out of this.
The following code will produce an array with all the images that have no corresponding product record. I've left off the unlink command so you can do some reviewing process first.
$sql = "SELECT * FROM Produk";
$result = mysql_query($sql);
$existing_products = array();
while ($row = mysql_fetch_array($result))
$existing_products[] = $row["id_produk"] . ".jpg";
$existing_images = array();
foreach(glob("../images/Produk/*.jpg") as $v)
$existing_images[] = str_replace("../images/Produk/", "", $v);
$images_to_delete = array_diff($existing_images, $existing_products);
try this
$it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator('../images/Produk/'));
$regx = new RegexIterator( $it, '/^.*\.jpg$/i', // only matched text will be returned
RecursiveRegexIterator::GET_MATCH );
foreach ($regx as $file) {
echo $file[0] , "\n";
unlink($file[0]);
}
this will find all JPG files in the given folders and subfolders and will delete it
I would recommend following:
make directory listing of "Images" direcotry by
dir /b > filelist.txt (windows)
or
ls -1 > filelist.txt (linux)
You will have now list of existing files which should be imported to some temp table in mysql.
Now write simple SQL to select files without apropriate products (don't forget to append .JPG suffix).
with list of files to be deleted you can simply create file_get_contents and foreach loop unlink.
Reason why I recommend this is security.You can review what will be deleted.
Once you run script, there is no undo (just from backup).
foreach(glob('../images/Produk/*.jpg') as $file) {
if(is_file($file))
#unlink($file);
}

Categories