PHP Delete Multiple File Image in folder - php

I have trouble when i want delete Multiple File Image in folder, i can delete the image in folder but just 1 image, other image can't delete in folder although in DB the image is 1 id, this my script
if (ISSET($_POST['remove_product'])) {
require("../koneksi.php");
$id = $_POST['id'];
$cari=mysql_query("select * from t_productimage where id_product='$id'");
$dt=mysql_fetch_array($cari);
$gmbr=$dt['image'];
$tmpfile = "../images_product/$gmbr";
$sql=mysql_query("DELETE a.*, b.*, c.* FROM t_product a, t_productsize b, t_productimage c WHERE a.id = '$id' AND b.id_product = '$id' AND c.id_product = '$id'");
if(!$sql){
echo '<script language="javascript" type="text/javascript">
alert("delete gambar gagal !");</script>';
echo "<meta http-equiv='refresh' content='0; url=home.php?p=product'>";
}else{
unlink ($tmpfile);
echo "<meta http-equiv='refresh' content='0; url=home.php?p=product'>";
}
exit();
}
thks a lot for responsed

The use of mysql is no longer recommended as it has been deprecated for some time and the code is vulnerable to sql injection, but you could try like this.
Fetch the results and then iterate though using a simple loop and use the returned value to populate an array which can then be used to display a message or redirect as you see fit.
You ought to however look into using mysqli or PDO in conjunction with prepared statements
if( isset( $_POST['remove_product'] ) ) {
require("../koneksi.php");
$id = $_POST['id'];
$results=array();
$cari=mysql_query("select * from t_productimage where id_product='$id'");
if( $cari ){
while( $dt=mysql_fetch_array( $cari ) ){
$gmbr = $dt['image'];
$tmpfile = "../images_product/$gmbr";
$results[ $gmbr ]=#unlink( $tmpfile );
}
$result=mysql_query("DELETE
a.*,
b.*,
c.*
FROM
t_product a,
t_productsize b,
t_productimage c
WHERE
a.id = '$id' AND b.id_product = '$id' AND c.id_product = '$id'");
$results['product-deleted']=$result;
}
if( !empty( $results ) ){
foreach( $results as $key => $status ){
printf('<div>%s -> %s</div>', $key, $status ? 'deleted' : 'error' );
}
}
}

Using following function, you can delete multiple images or images in multi level folder structure like given example:
**folders**
folder1/d1 f1.png
folder1/d1 f2.png
folder1/file.png
deleted -file.png
folder1/folder2
folder1/folder2/d2 f1.png
folder1/folder2/d2 f2.png
folder1/folder2/file.png
deleted -file.png
folder1/folder2/folder 3
folder1/folder2/folder 3/d3 f1.png
folder1/folder2/folder 3/d3 f2.png
folder1/folder2/folder 3/file.png
deleted -file.png
rrmdir('folder1');
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir . "/" . $object) == "dir") {
echo $dir . "/" . $object . '<br>';
rrmdir($dir . "/" . $object);
} else {
// unlink($dir . "/" . $object);
echo $dir . "/" . $object . '<br>';
if ($object == 'file.png') {
echo "deleted -" . $object . '<br>';
unlink($dir . "/" . $object);
}
}
}
}
reset($objects);
// rmdir($dir);
}
}

Related

Improve performance of foreach inside another foreach

I have this code:
<?php
$episodios = $SQL->query("SELECT * FROM episodios order by id desc LIMIT 500");
$temporadas = $SQL->query("SELECT * from temporadas");
foreach($episodios as $episodio) {
//review performance
foreach($temporadas as $temporada) {
if ($episodio['url_anime'] == $temporada['url_anime'] && $episodio['temporada'] == $temporada['temporada']) {
$tempName = (($temporada['showname'] == 1) ? '- '.$temporada['nome'].'' : '');
}
}
}
?>
But i'm worried about the code performance, because this loop inside another..
Someone told me to use cache and only update when get new data, but have other way to do the same thing with better performance? this code is displayed on my home website page.
Thanks in advance.
Please use the below query for improve code performance:-
$tempName = $SQL->query("Select temporadas.nome from temporadas INNER JOIN episodios ON
temporadas.url_anime = episodios.url_anime AND temporadas.temporada =
episodios.temporada WHERE temporadas.nome = 1 LIMIT 500");
pls check
<?php
//with code
$episodios = $SQL->query("SELECT * FROM episodios order by id desc LIMIT 500");
$temporadas = $SQL->query("SELECT * from temporadas");
$items = [];
foreach ($episodios as $episodio) {
if (!isset($items[$episodio['url_anime'] . "||" . $episodio['temporada']])) {
$items[$episodio['url_anime'] . "||" . $episodio['temporada']] = "-";
}
}
foreach ($temporadas as $temporada) {
if (isset($items[$temporada['url_anime'] . "||" . $temporada['temporada']])) {
$items[$temporada['url_anime'] . "||" . $temporada['temporada']] = (($temporada['showname'] == 1) ? '- ' . $temporada['nome'] . '' : '');
}
}
var_dump($items);
//There is a possibility of a minor error because I have real data
//or with query
#"SELECT * from temporadas join episodios on temporadas.url_anime==episodios.url_anime and temporadas.temporada==episodios.temporada"

Why is do while loop creating/overwriting 2 separate arrays

I have the following code that is overwriting my array on the second pass through of the while loop.
Here is my code:
<?php
require '../vendor/autoload.php';
require_once 'constants/constants.php';
use net\authorize\api\contract\v1 as AnetAPI;
use net\authorize\api\controller as AnetController;
require('includes/application_top.php');
define("AUTHORIZENET_LOG_FILE", "phplog");
function getUnsettledTransactionList()
{
//get orders that are in the exp status
$orders_pending_query = tep_db_query("select orders_id as invoice_number from " . TABLE_ORDERS . " where orders_status = '14' order by invoice_number");
$orders_pending = array();
while ($row = mysqli_fetch_array($orders_pending_query, MYSQLI_ASSOC)) {
$orders_pending[] = $row;
}
/* Create a merchantAuthenticationType object with authentication details
retrieved from the constants file */
$merchantAuthentication = new AnetAPI\MerchantAuthenticationType();
$merchantAuthentication->setName(\SampleCodeConstants::MERCHANT_LOGIN_ID);
$merchantAuthentication->setTransactionKey(\SampleCodeConstants::MERCHANT_TRANSACTION_KEY);
// Set the transaction's refId
$refId = 'ref' . time();
$pagenum = 1;
do {
$request = new AnetAPI\GetUnsettledTransactionListRequest();
$request->setMerchantAuthentication($merchantAuthentication);
$paging = new AnetAPI\PagingType;
$paging->setLimit("1000");
$paging->setOffset($pagenum);
$request->setPaging($paging);
$controller = new AnetController\GetUnsettledTransactionListController($request);
$response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::PRODUCTION);
$transactionArray = array();
$resulttrans = array();
if (($response != null) && ($response->getMessages()->getResultCode() == "Ok")) {
if (null != $response->getTransactions()) {
foreach ($response->getTransactions() as $tx) {
$transactionArray[] = array(
'transaction_id' => $tx->getTransId(),
'invoice_number' => $tx->getInvoiceNumber()
);
// echo "TransactionID: " . $tx->getTransId() . "order ID:" . $tx->getInvoiceNumber() . "Amount:" . $tx->getSettleAmount() . "<br/>";
}
$invoiceNumbers = array_column($orders_pending, "invoice_number");
$result = array_filter($transactionArray, function ($x) use ($invoiceNumbers) {
return in_array($x["invoice_number"], $invoiceNumbers);
});
$resulttrans = array_column($result, "transaction_id");
} else {
echo "No unsettled transactions for the merchant." . "\n";
}
} else {
echo "ERROR : Invalid response\n";
$errorMessages = $response->getMessages()->getMessage();
echo "Response : " . $errorMessages[0]->getCode() . " " . $errorMessages[0]->getText() . "\n";
}
$numResults = (int) $response->getTotalNumInResultSet();
$pagenum++;
print_r($resulttrans);
} while ($numResults === 1000);
return $resulttrans;
}
getUnsettledTransactionList();
?>
the print_r($resulttrans); is actually printing 2 separate arrays, instead of my desired 1 array.
If I move the print_r($resulttrans) to after the while loop, I am only seeing the second array, meaning the first array was overwritten. I am not seeing where this is happening though as to me it seems like all results should be added onto the array.
Your code is supposed to work as you described because you are reassigning the array variable in your loop like this
$resulttrans = array_column($result, "transaction_id");
If you need to get all the resulting values in the same array you need to append it to the array. you can do that by merging the new result into your array variable like this
$resulttrans = array_merge($resulttrans, array_column($result, "transaction_id"));

Delete data with checkboxes in foreach

Im selecting multiple rows with checkboxes, and then i delete them with ajax with the code below. (it works fine..)
<?php
include_once("../../files/connect.php");
if(isset($_POST['val']))
{
$p = &$_POST['val'];
foreach($p as &$v)
{
$v = "'". mysqli_escape_string($kapcs, $v) ."'";
}
$values = '('.implode(',',$p).')';
mysqli_query($kapcs, "DELETE FROM kereses WHERE kereses_id IN $values") or die(mysqli_error($kapcs));
echo 'Selected rows deleted.';
}
else
{
exit("No rows selected with checkbox.");
}
?>
How can i put this code into that? I want to delete the images or files also from a folder, not just only the record from the sql table. Can someone help me?
$DestinationDirectory = "../../images/news/";
if(file_exists($DestinationDirectory.$data['hir_thumb']))
{
unlink($DestinationDirectory . $data['hir_thumb']);
}
if(file_exists($DestinationDirectory.$data['hir_big']))
{
unlink($DestinationDirectory . $data['hir_big']);
}
I hope I can understand your question.
Code does not checked, but try to adapt it to your enviroment.
<?php
include_once("../../files/connect.php");
if(isset($_POST['val']))
{
$p = &$_POST['val'];
foreach($p as &$v)
{
$v = "'". mysqli_escape_string($kapcs, $v) ."'";
//select all the row
$sor = $kapcs->query("SELECT * FROM kereses WHERE kereses_value = {$v}");
//fetch the row
while ($data = mysqli_fetch_row($sor)){
//delete selected rows
$delete = $kapcs->query("DELETE FROM kereses WHERE id= {$data['id']}");
// if delete success
if ($delete) {
$DestinationDirectory = "../../images/news/";
echo 'Selected row deleted from database.';
// unlink the thumbnail if exists
if(file_exists($DestinationDirectory.$data['hir_thumb']))
{
unlink($DestinationDirectory . $data['hir_thumb']);
echo 'Selected thumbnail deleted from filesystem.';
}
//unlink the big picture if exists
if(file_exists($DestinationDirectory.$data['hir_big']))
{
unlink($DestinationDirectory . $data['hir_big']);
echo 'Selected picture deleted from filesystem.';
}
}
}
}
}
else
{
exit("No rows selected with checkbox.");
}
?>
I hope that helps.

ADOdb and null fields

I'm using the last version of ADOdb PHP (5.18) to make some queries in a SQL Server database.
I select data in this way:
$rS = $localDb->Execute($sql);
if (!$rS) {
echo "Error: " . $localDb->ErrorMsg() . "\n";
}
else {
$tot = $rS->RecordCount();
echo " " . $tot . " record da inserire...\n";
while (!$rS->EOF) {
$id = $rS->fields['id'];
$field1 = $rS->fields['field1'];
$field2 = $rS->fields['field2'];
$rS->MoveNext();
}
}
All works, and I fetch data, but when a field in the database's current row is NULL, the relative element in $rS->fields has the value of the value of the last not-NULL row for the same field.
This is a big problem because I don't have correct data in the current row.
I tried search for this problem but I did not find any solution.
Coud you help me, please?
Look into adodb5/adodb.inc.php and find the GetRowAssoc function. It should be the following defintion:
function GetRowAssoc($upper=ADODB_ASSOC_CASE_UPPER)
{
$record = array();
if (!$this->bind) {
$this->GetAssocKeys($upper);
}
foreach($this->bind as $k => $v) {
if( array_key_exists( $v, $this->fields ) ) {
$record[$k] = $this->fields[$v];
} elseif( array_key_exists( $k, $this->fields ) ) {
$record[$k] = $this->fields[$k];
} else {
# This should not happen... trigger error ?
$record[$k] = null;
}
}
return $record;
}

Delete all sublevels of categories in select using PHP

Problem:
I am trying to delete all sublevels of a category by using a class. Currently I can only make it delete two sublevels, not three.
The database table:
CREATE TABLE betyg_category (
CID int(11) NOT NULL AUTO_INCREMENT,
Item varchar(100) NOT NULL,
Parent int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (CID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The PHP class:
<?php
class ItemTree
{
var $itemlist = array();
function ItemTree($query)
{
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
while ($row = mysql_fetch_assoc($result))
{
$this->itemlist[$row['CID']] = array(
'name' => $row['Name'],
'parent' => $row['Parent']
);
}
}
function get_tree($parent, $with_parent=0)
{
$item_tree = array();
if ($with_parent == 1 && $parent != 0)
{
$item_tree[$parent]['name'] = $this->itemlist[$parent]['name'];
$item_tree[$parent]['parent'] = $this->itemlist[$parent]['parent'];
$item_tree[$parent]['child'] = $this->get_tree($parent);
return $item_tree;
}
foreach ($this->itemlist as $key => $val)
{
if ($val['parent'] == $parent)
{
$item_tree[$key]['name'] = $val['name'];
$item_tree[$key]['parent'] = $val['parent'];
$item_tree[$key]['child'] = $this->get_tree($key);
}
}
return $item_tree;
}
function make_optionlist ($id, $class='', $delimiter='/')
{
$option_list = '';
$item_tree = $this->get_tree(0);
$options = $this->make_options($item_tree, '', $delimiter);
if (!is_array($id))
{
$id = array($id);
}
foreach($options as $row)
{
list($index, $text) = $row;
$selected = in_array($index, $id) ? ' selected="selected"' : '';
$option_list .= "<option value=\"$index\" class=\"$class\"$selected>$text</option>\n";
}
return $option_list;
}
function make_options ($item_tree, $before, $delimiter='/')
{
$before .= empty($before) ? '' : $delimiter;
$options = array();
foreach ($item_tree as $key => $val)
{
$options[] = array($key, '- '.$before.$val['name']);
if (!empty($val['child'])) {
$options = array_merge($options, $this->make_options($val['child'], $before.$val['name'], $delimiter));
}
}
return $options;
}
function get_navlinks ($navid, $tpl, $startlink='', $delimiter=' ยป ')
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$navlink = array();
while (isset($this->itemlist[$navid]))
{
$replace = array($navid, $this->itemlist[$navid]['name']);
$navlink[] = str_replace($search, $replace, $tpl);
$navid = $this->itemlist[$navid]['parent'];
}
if (!empty($startlink))
{
$navlink[] = str_replace($search, array(0, $startlink), $tpl);
}
$navlink = array_reverse($navlink);
return implode($delimiter, $navlink);
}
function show_tree ($parent=0, $tpl='%s', $ul_class='', $li_class='')
{
$item_tree = $this->get_tree($parent);
return $this->get_node($item_tree, $parent, $tpl, $ul_class, $li_class);
}
function get_node ($item_tree, $parent, $tpl, $ul_class, $li_class)
{
// $tpl typ: {name}
$search = array('{id}', '{name}');
$output = "\n<ul class=\"$ul_class\">\n";
foreach ($item_tree as $id => $item)
{
$replace = array($id, $item['name']);
$output .= "<li class=\"$li_class\">".str_replace($search, $replace, $tpl);
$output .= !empty($item['child']) ? "<br />".$this->get_node ($item['child'], $id, $tpl, $ul_class, $li_class) : '';
$output .= "</li>\n";
}
return $output . "</ul>\n";
}
function get_id_in_node ($id)
{
$id_list = array($id);
if (isset($this->itemlist[$id]))
{
foreach ($this->itemlist as $key => $row)
{
if ($row['parent'] == $id)
{
if (!empty($row['child']))
{
$id_list = array_merge($id_list, get_id_in_node($key));
} else
{
$id_list[] = $key;
}
}
}
}
return $id_list;
}
function get_parent ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['parent'] : false;
}
function get_item_name ($id)
{
return isset($this->itemlist[$id]) ? $this->itemlist[$id]['name'] : false;
}
}
?>
Scenario:
Say you have the following structure in a :
Literature
-- Integration of sources
---- Test 1
It will result in the following in the database table:
When I try to delete this sublevel, it will leave the last sublevel in the database while it should delete it. The result will be:
The PHP code:
//Check if delete button is set
if (isset($_POST['submit-deletecategory']))
{
//Get $_POST variables for category id
$CategoryParent = intval($_POST['CategoryList']);
//Check if category is selected
if ($CategoryParent != "#")
{
//Get parent category and subsequent child categories
$query = "SELECT CID, Item AS Name, Parent FROM " . TB_CATEGORY . " ORDER BY Name";
$items = new ItemTree($query);
if ($items->get_item_name($_POST['CategoryList']) !== false)
{
//Build up erase list
$CategoryErase = $items->get_id_in_node($CategoryParent);
$CategoryEraseList = implode(", ", $CategoryErase);
}
else
{
$CategoryEraseList = 0;
}
//Remove categories from database
$query = "DELETE FROM " . TB_CATEGORY . " WHERE CID IN ($CategoryEraseList)";
$result = mysql_query($query) or die ('Database Error (' . mysql_errno() . ') ' . mysql_error());
//Return a confirmation notice
header("Location: settings.php");
exit;
}
}
Thank you in advance for any guidance I can get to solve the issue.
Here is a way to do it : use a recursive function, which will first look for the leaf item (the deepest in your tree). You remove children first, then the parent. And for each child, you remove child's children first, etc...
deleteSub(1);
function deleteSub($cat_id) {
$request = "SELECT * FROM ". TB_CATEGORY ." WHERE Parent = ".$cat_id;
$results = mysql_query($request);
while($child = mysql_fetch_array($results))
{
deleteSub($child["CID"]);
}
$request = "DELETE FROM ". TB_CATEGORY ." WHERE CID = ".$cat_id;
return mysql_query($request);
}
A better way could be use this kind of recursive function to store CIDs in an array, then make a single DELETE request, but I think you'll be able to adapt this code.
I'm not going to read or try to understand the entire code, but it seems to me you need some sort of recursion function. What I basicly would do is create a function that goes up in the hierachy and one that goes down.
Note: It has been a while since i've written anything in procedural mysql, so please check if the mysql_num_rows(),mysql_fetch_array and so on is written in the correct manner
EDIT: I've just noticed you only wanted a downwards deletion and therefore zessx's answer is more valid
<?php
function recursiveParent($id) {
$sql = 'SELECT parent FROM betyg_category WHERE CID=' . $id;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveParent($r['parent']);
}
}
$sql = 'DELETE FROM betyg_category WHERE CID=' . $id;
mysql_query($sql);
}
function recursiveChild($parent) {
$sql = 'SELECT CID FROM betyg_category WHERE parent=' . $parent;
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result,MYSQLI_ASSOC)) {
recursiveChild($r['CID']);
}
}
$sql = 'DELETE FROM betyg_category WHERE parent=' . $parent;
mysql_query($sql);
}
function delete($id) {
recursiveParent($id);
recursiveChild($id);
}
?>
This is my way to do. instead of recursive the query to run, i get all the child's id first then only run query. here the code refer:-
First, defined a variable called $delete_node_list as array. (to store all node id that need to be delete)
function delete_child_nodes($node_id)
{
$childs_node = $this->edirectory_model->get_child_nodes($node_id);
if(!empty($childs_node))
{
foreach($childs_node as $node)
{
$this->delete_child_nodes($node['id']);
}
}
$this->delete_node_list[] = $node_id;
}
in mysql..
$sql = 'DELETE FROM betyg_category WHERE CID IN '.$this->delete_node_list;
mysql_query($sql);

Categories