Solving PHP Issue with FireBellyLawnCare.com CMS

  • PHP
  • Thread starter bigdawg723
  • Start date
  • Tags
    Cms Php
In summary: Dir . $imagePath); $imagePath = $thumbnailPath = ''; } } } return array('image' => $imagePath, 'thumbnail' => $thumbnailPath);}function modifyProduct(){ $catId = $_POST['cboCategory']; $pdId = (int)$_POST['hidProductId']; $sku = $_POST['txtSku']; $name = $_POST['txtName']; $description = $_POST['mtxDescription']; $direction = $_POST['txtDirection']; $benefits = $_POST['txtBenefites']; $size1 =
  • #1
bigdawg723
13
0
Good Evening All!

Well... that registration was fun. I'm red/green colorblind (I guessed green and got it right!).

Anyways... I've got a problem (other than my color blindness).

My website, www.FireBellyLawnCare.com, is up and running. The designer... sadly... is out of contact. I would have him fix it... as it should have been done in the beginning... but it's just my luck that he has remained silent via email.

I have strong HTML skills... CSS... but my PHP knowledge is extremely limited... I can merely troubleshoot... to an extent.

Here's the issue... in my admin backend, I have a screen to add products.

I enter all the information into the fields, and when I click "Add Product"... nothing happens. Here's the main form code:

Code:
<form action="processProduct.php?action=addProduct" method="post" enctype="multipart/form-data" name="frmAddProduct" id="frmAddProduct">

and here's the submit button ("Add Product") code:

Code:
<input name="btnAddProduct" type="button" id="btnAddProduct" value="Add Product" onClick="checkAddProductForm();" class="box">

I'm not sure if that helps AT ALL... but I desperately need your help! I need to add more products and make it easy for my wife to add products. I believe I can still do so via editing the database... but that's nothing my wife would ever want to do (nor would I really want her in the DB messing around)... so it'd be great if there was a simple fix here.

It looks like all the code is there... something isn't quite working right though.

What else can I post to help troubleshoot this issue?

Thank You in advance! I'm definitely willing to throw some Paypal money in your direction if you can help me out here!

Josh
 
Technology news on Phys.org
  • #2
You'll need to post the code from the processProduct.php file. We are happy to help you for free :)
 
  • #3
Two places to start.

First, clicking the addProduct button invokes the javascript function checkAddProductForm() to validate the form before submitting. You'll want to make sure that's complete and working correctly (i.e., it submits the form after a successful validation). If this submission isn't being done, then nothing is actually being sent to the server.

The fact that you say "nothing happens" leads me to believe that this may be the culprit. Also, if you have access to the webserver logs, not seeing any entries with "processProduct.php?action=addProduct" in it (after trying to submit) would also indicate that the form may not be getting submitted properly.

If the form IS getting submitted, you'll want to look at processProduct.php. From the looks of it, there's probably an if/else or switch statement that sees the "addProduct" from the url, then pulls in the rest of the form data from the $_POST (or $_REQUEST) array.
 
  • #4
That makes sense... has to be one of those two.

On the top of my add product page source... there's some code that includes a product.js file:
Code:
<script language="JavaScript" type="text/javascript" src="[PLAIN]http://www.firebellylawncare.com/admin/library/product.js"></script>
[/PLAIN]

In that file, I located this code for the submit button:
Code:
function checkAddProductForm()
{
	with (window.document.frmAddProduct) {
		if (cboCategory.selectedIndex == 0) {
			alert('Choose the product category');
			cboCategory.focus();
			return;
		} else if (isEmpty(txtName, 'Enter Product name')) {
			return;
		} else {
			submit();
		}
	}
}

Let me snag the code from the ProcessProducts page and post it right after this post...
 
Last edited by a moderator:
  • #5
This is the ProcessProduct.php page code... hope it helps in troubleshooting? I'm not really sure how to check logs... but I'll start digging now.

Thanks a ton guys!

PHP:
<?php
require_once '../../library/config.php';
require_once '../library/functions.php';

checkUser();

$action = isset($_GET['action']) ? $_GET['action'] : '';

switch ($action) {
	
	case 'addProduct' :
		addProduct();
		break;
		
	case 'modifyProduct' :
		modifyProduct();
		break;
		
	case 'deleteProduct' :
		deleteProduct();
		break;
	
	case 'deleteImage' :
		deleteImage();
		break;
	
	case 'addOffert' :
		addOffert();
		break;
		
	case 'modifyOffer' :
		modifyOffer();
		break;
    

	default :
	    // if action is not defined or unknown
		// move to main product page
		header('Location: index.php');
}function addProduct()
{
    $catId       = $_POST['cboCategory'];
	$sku = $_POST['txtSku'];
    $name        = $_POST['txtName'];
	$description = $_POST['mtxDescription'];
	$direction = $_POST['txtDirection'];
	$benefits = $_POST['txtBenefites'];
	$size1 = $_POST['txtSize1'];
	$coverage1 = $_POST['txtCoverage1'];
	$price1       = str_replace(',', '', (double)$_POST['txtPrice1']);
	$qty1         = (int)$_POST['txtQty1'];
	$size2 = $_POST['txtSize2'];
	$coverage2 = $_POST['txtCoverage2'];
	$price2       = str_replace(',', '', (double)$_POST['txtPrice2']);
	$qty2         = (int)$_POST['txtQty2'];
	$size3 = $_POST['txtSize3'];
	$coverage3 = $_POST['txtCoverage3'];
	$price3       = str_replace(',', '', (double)$_POST['txtPrice3']);
	$qty3         = (int)$_POST['txtQty3'];
	if(!empty($_POST['txtSize4'])) {
		$size4 = $_POST['txtSize4'];
	} else {
		$size4 = '';
	}
	if(!empty($_POST['txtCoverage4'])) {
		$coverage4 = $_POST['txtCoverage4'];
	} else {
		$coverage4 = '';
	}
	if(!empty($_POST['txtPrice4'])) {
		$price4       = str_replace(',', '', (double)$_POST['txtPrice4']);
	} else {
		$price4       = '';
	}
	if(!empty($_POST['txtQty4'])) {
		$qty4         = (int)$_POST['txtQty4'];
	} else {
		$qty4         = '';
	}
	if(!empty($_POST['txtSize5'])) {
		$size5 = $_POST['txtSize5'];
	} else {
		$size5 = '';
	}
	if(!empty($_POST['txtCoverage5'])) {
		$coverage5 = $_POST['txtCoverage5'];
	} else {
		$coverage5 = '';
	}
	if(!empty($_POST['txtPrice5'])) {
		$price5       = str_replace(',', '', (double)$_POST['txtPrice5']);
	} else {
		$price5       = '';
	}
	if(!empty($_POST['txtQty5'])) {
		$qty5         = (int)$_POST['txtQty5'];
	} else {
		$qty5         = '';
	}
	
	$shipWithIn = $_POST['txtShipWithin'];
	
	
	$images = uploadProductImage('fleImage', SRV_ROOT . 'images/product/');

	$mainImage = $images['image'];
	$thumbnail = $images['thumbnail'];
	
	$sql   = "INSERT INTO tbl_product (cat_id, pd_sku, pd_name, pd_description, pd_direction, pd_benefits, pd_size1, pd_coverage1,  pd_price1, pd_qty1, pd_size2, pd_coverage2,  pd_price2, pd_qty2, pd_size3, pd_coverage3,  pd_price3, pd_qty3, pd_size4, pd_coverage4,  pd_price4, pd_qty4, pd_size5, pd_coverage5,  pd_price5, pd_qty5, pd_shipwithin, pd_image, pd_thumbnail, pd_date)
	          VALUES ('$catId', '$sku', '$name', '$description', '$direction', '$benefits', '$size1', '$coverage1', $price1, '$qty1', '$size2', '$coverage2', $price2, '$qty2', '$size3', '$coverage3', $price3, '$qty3', '$size4', '$coverage4', $price4, '$qty4','$size5', '$coverage5', $price5, '$qty5','$shipWithIn', '$mainImage', '$thumbnail', NOW())";

	$result = dbQuery($sql);
	
	header("Location: index.php");	
}

/*
	Upload an image and return the uploaded image name 
*/
function uploadProductImage($inputName, $uploadDir)
{
	$image     = $_FILES[$inputName];
	$imagePath = '';
	$thumbnailPath = '';
	
	// if a file is given
	if (trim($image['tmp_name']) != '') {
		$ext = substr(strrchr($image['name'], "."), 1); //$extensions[$image['type']];

		// generate a random new file name to avoid name conflict
		$imagePath = md5(rand() * time()) . ".$ext";
		
		list($width, $height, $type, $attr) = getimagesize($image['tmp_name']); 

		// make sure the image width does not exceed the
		// maximum allowed width
		if (LIMIT_PRODUCT_WIDTH && $width > MAX_PRODUCT_IMAGE_WIDTH) {
			$result    = createThumbnail($image['tmp_name'], $uploadDir . $imagePath, MAX_PRODUCT_IMAGE_WIDTH);
			$imagePath = $result;
		} else {
			$result = move_uploaded_file($image['tmp_name'], $uploadDir . $imagePath);
		}	
		
		if ($result) {
			// create thumbnail
			$thumbnailPath =  md5(rand() * time()) . ".$ext";
			$result = createThumbnail($uploadDir . $imagePath, $uploadDir . $thumbnailPath, THUMBNAIL_WIDTH);
			
			// create thumbnail failed, delete the image
			if (!$result) {
				unlink($uploadDir . $imagePath);
				$imagePath = $thumbnailPath = '';
			} else {
				$thumbnailPath = $result;
			}	
		} else {
			// the product cannot be upload / resized
			$imagePath = $thumbnailPath = '';
		}
		
	}

	
	return array('image' => $imagePath, 'thumbnail' => $thumbnailPath);
}

/*
	Modify a product
*/
function modifyProduct()
{
	$proId = (int)$_GET['productId'];
	$catId       = $_POST['cboCategory'];
	$sku = $_POST['txtSku'];
    $name        = $_POST['txtName'];
	$description = $_POST['mtxDescription'];
	$direction = $_POST['txtDirection'];
	$benefits = $_POST['txtBenefites'];
	$size1 = $_POST['txtSize1'];
	$coverage1 = $_POST['txtCoverage1'];
	$price1       = str_replace(',', '', (double)$_POST['txtPrice1']);
	$qty1         = (int)$_POST['txtQty1'];
	$size2 = $_POST['txtSize2'];
	$coverage2 = $_POST['txtCoverage2'];
	$price2       = str_replace(',', '', (double)$_POST['txtPrice2']);
	$qty2         = (int)$_POST['txtQty2'];
	$size3 = $_POST['txtSize3'];
	$coverage3 = $_POST['txtCoverage3'];
	$price3       = str_replace(',', '', (double)$_POST['txtPrice3']);
	$qty3         = (int)$_POST['txtQty3'];
	if(!empty($_POST['txtSize4'])) {
		$size4 = $_POST['txtSize4'];
	} else {
		$size4 = '';
	}
	if(!empty($_POST['txtCoverage4'])) {
		$coverage4 = $_POST['txtCoverage4'];
	} else {
		$coverage4 = '';
	}
	if(!empty($_POST['txtPrice4'])) {
		$price4       = str_replace(',', '', (double)$_POST['txtPrice4']);
	} else {
		$price4       = '';
	}
	if(!empty($_POST['txtQty4'])) {
		$qty4         = (int)$_POST['txtQty4'];
	} else {
		$qty4         = '';
	}
	if(!empty($_POST['txtSize5'])) {
		$size5 = $_POST['txtSize5'];
	} else {
		$size5 = '';
	}
	if(!empty($_POST['txtCoverage5'])) {
		$coverage5 = $_POST['txtCoverage5'];
	} else {
		$coverage5 = '';
	}
	if(!empty($_POST['txtPrice5'])) {
		$price5       = str_replace(',', '', (double)$_POST['txtPrice5']);
	} else {
		$price5       = '';
	}
	if(!empty($_POST['txtQty5'])) {
		$qty5         = (int)$_POST['txtQty5'];
	} else {
		$qty5         = '';
	}
	
	$shipWithIn = $_POST['txtShipWithin'];
	
	
	$images = uploadProductImage('fleImage', SRV_ROOT . 'images/product/');

	$mainImage = $images['image'];
	$thumbnail = $images['thumbnail'];

	// if uploading a new image
	// remove old image
	if ($mainImage != '') {
		_deleteImage($proId);
		
		$mainImage = "'$mainImage'";
		$thumbnail = "'$thumbnail'";
	} else {
		// if we're not updating the image
		// make sure the old path remain the same
		// in the database
		$mainImage = 'pd_image';
		$thumbnail = 'pd_thumbnail';
	}
			
	$sql   = "UPDATE tbl_product 
	          SET cat_id = '$catId', pd_sku = '$sku', pd_name = '$name', pd_description = '$description', pd_direction = '$direction', pd_benefits = '$benefits', pd_size1 = '$size1', pd_coverage1 = '$coverage1', pd_price1 = '$price1', pd_qty1 = '$qty1', pd_size2 = '$size2', pd_coverage2 = '$coverage2', pd_price2 = '$price2', pd_qty2 = '$qty2', pd_size3 = '$size3', pd_coverage3 = '$coverage3', pd_price3 = '$price3', pd_qty3 = '$qty3', pd_size4 = '$size4', pd_coverage4 = '$coverage4',  pd_price4 = '$price4', pd_qty4 = '$qty4', pd_size5 = '$size5', pd_coverage5 = '$coverage5',  pd_price5 = '$price4', pd_qty5 = '$qty5', pd_image = $mainImage, pd_thumbnail = $thumbnail
			  WHERE pd_id = $proId";  

	$result = dbQuery($sql);
	
	header('Location: index.php');			  
}

/*
	Remove a product
*/
function deleteProduct()
{
	if (isset($_GET['productId']) && (int)$_GET['productId'] > 0) {
		$productId = (int)$_GET['productId'];
	} else {
		header('Location: index.php');
	}
	
	// remove any references to this product from
	// tbl_order_item and tbl_cart
	$sql = "DELETE FROM tbl_order_item
	        WHERE pd_id = $productId";
	dbQuery($sql);
			
	$sql = "DELETE FROM tbl_cart
	        WHERE pd_id = $productId";	
	dbQuery($sql);
			
	// get the image name and thumbnail
	$sql = "SELECT pd_image, pd_thumbnail
	        FROM tbl_product
			WHERE pd_id = $productId";
			
	$result = dbQuery($sql);
	$row    = dbFetchAssoc($result);
	
	// remove the product image and thumbnail
	if ($row['pd_image']) {
		unlink(SRV_ROOT . 'images/product/' . $row['pd_image']);
		unlink(SRV_ROOT . 'images/product/' . $row['pd_thumbnail']);
	}
	
	// remove the product from database;
	$sql = "DELETE FROM tbl_product 
	        WHERE pd_id = $productId";
	dbQuery($sql);
	
	header('Location: index.php?catId=' . $_GET['catId']);
}/*
	Remove a product image
*/
function deleteImage()
{
	if (isset($_GET['productId']) && (int)$_GET['productId'] > 0) {
		$productId = (int)$_GET['productId'];
	} else {
		header('Location: index.php');
	}
	
	$deleted = _deleteImage($productId);

	// update the image and thumbnail name in the database
	$sql = "UPDATE tbl_product
			SET pd_image = '', pd_thumbnail = ''
			WHERE pd_id = $productId";
	dbQuery($sql);		

	header("Location: index.php?view=modify&productId=$productId");
}

function _deleteImage($productId)
{
	// we will return the status
	// whether the image deleted successfully
	$deleted = false;
	
	$sql = "SELECT pd_image, pd_thumbnail 
	        FROM tbl_product
			WHERE pd_id = $productId";
	$result = dbQuery($sql) or die('Cannot delete product image. ' . mysql_error());
	
	if (dbNumRows($result)) {
		$row = dbFetchAssoc($result);
		extract($row);
		
		if ($pd_image && $pd_thumbnail) {
			// remove the image file
			$deleted = @unlink(SRV_ROOT . "images/product/$pd_image");
			$deleted = @unlink(SRV_ROOT . "images/product/$pd_thumbnail");
		}
	}
	
	return $deleted;
}function addOffert() {
	$pdId = (int)$_GET['offId'];
	$offerAmount = $_POST['offerAmount'];
	$offDescription = $_POST['description'];
	
	$sql = "UPDATE tbl_product SET pd_offer_amount = '$offerAmount', pd_offer_description = '$offDescription' WHERE pd_id = '$pdId'";
	$result = dbQuery($sql);
	header("Location:index.php");
	
}

function modifyOffer() {
	$pdId = (int)$_GET['offId'];
	$offerAmount = $_POST['offerAmount'];
	$offDescription = $_POST['description'];
	
	$sql = "UPDATE tbl_product SET pd_offer_amount = '$offerAmount', pd_offer_description = '$offDescription' WHERE pd_id = '$pdId'";
	$result = dbQuery($sql);
	header("Location:index.php");
	
}

?>
 
Last edited by a moderator:
  • #6
I tried posting this before the above code... so I'll try again.

In the header of the Add Product page... I found an include to a product.js file:
Code:
<script language="JavaScript" type="text/javascript" src="[PLAIN]http://www.firebellylawncare.com/admin/library/product.js"></script>[/PLAIN]

I went to that file and grabbed the code for checkAddProductForm() - the SUBMIT button:
Code:
// JavaScript Document
function viewProduct()
{
	with (window.document.frmListProduct) {
		if (cboCategory.selectedIndex == 0) {
			window.location.href = 'index.php';
		} else {
			window.location.href = 'index.php?catId=' + cboCategory.options[cboCategory.selectedIndex].value;
		}
	}
}

function checkAddProductForm()
{
	with (window.document.frmAddProduct) {
		if (cboCategory.selectedIndex == 0) {
			alert('Choose the product category');
			cboCategory.focus();
			return;
		} else if (isEmpty(txtName, 'Enter Product name')) {
			return;
		} else {
			submit();
		}
	}
}
function checkAddOfferForm()
{
	with (window.document.frmAddOffer) {
		if (isEmpty(offerAmount, 'Enter Product Offer Amount')) {
			return;
		} else {
			submit();
		}
	}
}

function addProduct(catId)
{
	window.location.href = 'index.php?view=add&catId=' + catId;
}

function modifyProduct(productId)
{
	window.location.href = 'index.php?view=modify&productId=' + productId;
}

function deleteProduct(productId, catId)
{
	if (confirm('Delete this product?')) {
		window.location.href = 'processProduct.php?action=deleteProduct&productId=' + productId + '&catId=' + catId;
	}
}

function deleteImage(productId)
{
	if (confirm('Delete this image')) {
		window.location.href = 'processProduct.php?action=deleteImage&productId=' + productId;
	}
}

function offerProduct(offerId)
{
	window.location.href = 'index.php?view=offer&offerId=' + offerId;
}

function offerEdit(offerId)
{
	window.location.href = 'index.php?view=offer&offerId=' + offerId + '&action=edit';
}

So that's the code for the button... and above is the code for processProduct.php... my fingers are crossed!
 
Last edited by a moderator:
  • #7
Not sure what dbQuery is (that is, name is obvious, but as far as I can tell there is no such function in PHP documentation). So I would start checking what dbQUery does and what it returns. Or add some print("<p>I am here, ready to call dbQuery to add $name to database!</p>"); tracers to check what is executed and what is not.

But then my php skills are rather low.
 
  • #8
@Borek - It looks like dbQuery (and the rest of the code, for that matter) is part of http://www.phpwebcommerce.com/shopping-cart-source-code.php"

@bigdawg723 - I don't see anything offhand that would cause it not to work (at least nothing jumps out at me). More information about what you're seeing might be helpful: you said nothing happens - does nothing happen at all (like the button isn't being clicked), or is there a page refresh but the data isn't added? Also, webserver logs (if you can find and/or access them) may still be helpful.

Also, this is unrealted to your current problem, but I am concerned that the PHP code you posted appears to be susceptible to what's known as a SQL injection attack. This could allow an attacker to compromise your database and potentially your entire server. This is an extremely serious (but unfortunately common) issue. I strongly suggest having something done about it.
 
Last edited by a moderator:
  • #9
Bill_B said:
@Borek - It looks like dbQuery (and the rest of the code, for that matter) is part of this package

Thanks.

Also, this is unrealted to your current problem, but I am concerned that the PHP code you posted appears to be susceptible to what's known as a SQL injection attack. This could allow an attacker to compromise your database and potentially your entire server. This is an extremely serious (but unfortunately common) issue. I strongly suggest having something done about it.

http://xkcd.com/327/
 
  • #10
lol @ xkcd.com

Anyways... yeah - I know it's not the most secure... I regularly backup everything (especially the DBs)... until more funding rolls around... it is what it is I suppose?

In regards to my problem... when I click "Add Product"... the button does move, it reacts normally to my mouse click... but it's almost as if there was no code... just code for a darn submit button. I k now this isn't true after looking at the source code... but that's how it acts. No refresh, no nothing except for a regular 'ol submit button reacting to a mouse-click.

I've searched and searched my FTP... there are no stinking log files anywhere?? I see one log file... it just logs visitors and their IPs and when they visited and what they visited (files). No error log - which is what I assume I'm looking for.

I'm not sure if the store uses those files... the FTP structure is completely different... not even similar - but perhaps the source files were used? It was open-source if I read it correctly.

I'm at a complete loss. I don't trust posting this issue on Freelancer or eLance for a programmer that may have ZERO experience... any chance anyone could recommend a reliable, trustworthy, perhaps affordable PHP expert (maybe with references?) that I could contact for some paid assistance?

I don't mind being PMd (if that's possible here). I'm just at a complete loss here - I've posted this on PHPFreaks as well... I guess there's just too many possibilities and I don't have the know-how to troubleshoot it properly with those print php commands and stuff?

Again, thanks for the input gents!
 
  • #11
If there's no refresh (or page change) at all, then I'd focus on the javascript, since without a successful form POST, the PHP isn't getting executed.

Out of curiosity, what browser are you using, and have you tried a different one? (in case of a browser-specific javascript bug)

I've downloaded the cart package and put it on one of my development servers - it appears to work correctly.

Can you post the (html) source of the add product page? (so we can see all of the form, etc.) I'd like to try to reproduce what you're seeing.
 
  • #12
That makes sense... you'd think there would be SOME action if the JS was working.

So... when I'm on the add product page... this is the URL:
http://www.firebellylawncare.com/admin/product/index.php?view=add&catId=0

Now... here's the code from /admin/product/index.php:
PHP:
<?php
require_once '../../library/config.php';
require_once '../library/functions.php';
include '../FCKeditor/fckeditor.php';

$_SESSION['login_return_url'] = $_SERVER['REQUEST_URI'];
checkUser();

$view = (isset($_GET['view']) && $_GET['view'] != '') ? $_GET['view'] : '';

switch ($view) {
	case 'list' :
		$content 	= 'list.php';		
		$pageTitle 	= 'Shop Admin Control Panel - View Product';
		break;

	case 'add' :
		$content 	= 'add.php';		
		$pageTitle 	= 'Shop Admin Control Panel - Add Product';
		break;

	case 'modify' :
		$content 	= 'modify.php';		
		$pageTitle 	= 'Shop Admin Control Panel - Modify Product';
		break;

	case 'offer' :
		$content    = 'offer.php';
		$pageTitle  = 'Shop Admin Control Panel - View Product Detail';
		break;
		
	default :
		$content 	= 'list.php';		
		$pageTitle 	= 'Shop Admin Control Panel - View Product';
}




$script    = array('product.js');

require_once '../include/template.php';
?>

and here's the code from /admin/product/add.php:
PHP:
<?php
if (!defined('WEB_ROOT')) {
	exit;
}

$catId = (isset($_GET['catId']) && $_GET['catId'] > 0) ? $_GET['catId'] : 0;

$categoryList = buildCategoryOptions($catId);
?> 
<p>&nbsp;</p>
<form action="processProduct.php?action=addProduct" method="post" enctype="multipart/form-data" name="frmAddProduct" id="frmAddProduct">
  <table width="100%" border="0" align="center" cellpadding="5" cellspacing="1" class="entryTable">
  <tr><td colspan="2" id="entryTableHeader">Add Product</td></tr>
  <tr> 
   <td width="150" class="label">Category</td>
   <td class="content"> <select name="cboCategory" id="cboCategory" class="box">
     <option value="" selected>-- Choose Category --</option>
<?php
	echo $categoryList;
?>	 
    </select></td>
  </tr>
  <tr> 
   <td width="150" class="label">SKU</td>
   <td class="content"> <input name="txtSku" type="text" class="box" id="txtSku" size="50" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Product Name</td>
   <td class="content"> <input name="txtName" type="text" class="box" id="txtName" size="50" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Description</td>
   <td class="content">
   <?php
   $oFCKeditor = new FCKeditor('mtxDescription') ;
   $oFCKeditor->BasePath	= "../FCKeditor/" ;
   $oFCKeditor -> Width ="600px";
   $oFCKeditor -> Height = "300px";
   $oFCKeditor->Create() ;
   ?>
   </td>
  </tr>
  <tr> 
   <td width="150" class="label">Directions</td>
   <td class="content">
   <?php
   $oFCKeditor = new FCKeditor('txtDirection') ;
   $oFCKeditor->BasePath	= "../FCKeditor/" ;
   $oFCKeditor -> Width ="600px";
   $oFCKeditor -> Height = "300px";
   $oFCKeditor->Create() ;
   ?>
  </td>
  </tr>
  <tr> 
   <td width="150" class="label">Benefites</td>
   <td class="content"> <input name="txtBenefites" type="text" class="box" id="txtBenefites" size="50" maxlength="100"></td>
  </tr>
  <tr>
  <td>Quart</td>
  </tr>
  <tr> 
   <td width="150" class="label">Size</td>
   <td class="content"> <input name="txtSize1" type="text" class="box" id="txtSize1" size="10" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Sq.Feet Coverage</td>
   <td class="content"> <input name="txtCoverage1" type="text" class="box" id="txtCoverage1" size="10" maxlength="100"></td>
  </tr>
 
  <tr> 
   <td width="150" class="label">Price</td>
   <td class="content"><input name="txtPrice1" type="text" id="txtPrice1" size="10" maxlength="7" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr> 
   <td width="150" class="label">Qty In Stock</td>
   <td class="content"><input name="txtQty1" type="text" id="txtQty1" size="10" maxlength="10" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
   <tr>
  <td>Gallon</td>
  </tr>
   <tr> 
   <td width="150" class="label">Size</td>
   <td class="content"> <input name="txtSize2" type="text" class="box" id="txtSize2" size="10" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Sq.Feet Coverage</td>
   <td class="content"> <input name="txtCoverage2" type="text" class="box" id="txtCoverage2" size="10" maxlength="100"></td>
  </tr>
 
  <tr> 
   <td width="150" class="label">Price</td>
   <td class="content"><input name="txtPrice2" type="text" id="txtPrice2" size="10" maxlength="7" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr> 
   <td width="150" class="label">Qty In Stock</td>
   <td class="content"><input name="txtQty2" type="text" id="txtQty1" size="10" maxlength="10" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
   <tr>
  <td>5 Gallon</td>
  </tr>
  <tr> 
   <td width="150" class="label">Size</td>
   <td class="content"> <input name="txtSize3" type="text" class="box" id="txtSize3" size="10" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Sq.Feet Coverage</td>
   <td class="content"> <input name="txtCoverage3" type="text" class="box" id="txtCoverage3" size="10" maxlength="100"></td>
  </tr>
   <tr> 
   <td width="150" class="label">Price</td>
   <td class="content"><input name="txtPrice3" type="text" id="txtPrice3" size="10" maxlength="7" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr> 
   <td width="150" class="label">Qty In Stock</td>
   <td class="content"><input name="txtQty3" type="text" id="txtQty3" size="10" maxlength="10" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr>
  <td>55 Gallon</td>
  </tr>
  <tr> 
   <td width="150" class="label">Size</td>
   <td class="content"> <input name="txtSize4" type="text" class="box" id="txtSize4" size="10" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Sq.Feet Coverage</td>
   <td class="content"> <input name="txtCoverage4" type="text" class="box" id="txtCoverage4" size="10" maxlength="100"></td>
  </tr>
   <tr> 
   <td width="150" class="label">Price</td>
   <td class="content"><input name="txtPrice4" type="text" id="txtPrice4" size="10" maxlength="7" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr> 
   <td width="150" class="label">Qty In Stock</td>
   <td class="content"><input name="txtQty4" type="text" id="txtQty4" size="10" maxlength="10" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr>
  <td>Other</td>
  </tr>
  <tr> 
   <td width="150" class="label">Size</td>
   <td class="content"> <input name="txtSize5" type="text" class="box" id="txtSize5" size="10" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Sq.Feet Coverage</td>
   <td class="content"> <input name="txtCoverage5" type="text" class="box" id="txtCoverage5" size="10" maxlength="100"></td>
  </tr>
   <tr> 
   <td width="150" class="label">Price</td>
   <td class="content"><input name="txtPrice5" type="text" id="txtPrice5" size="10" maxlength="7" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr> 
   <td width="150" class="label">Qty In Stock</td>
   <td class="content"><input name="txtQty5" type="text" id="txtQty5" size="10" maxlength="10" class="box" onKeyUp="checkNumber(this);"> </td>
  </tr>
  <tr><td>&nbsp;</td></tr>
   <tr> 
   <td width="150" class="label">Ship Within (Days)</td>
   <td class="content"> <input name="txtShipWithin" type="text" class="box" id="txtShipWithin" size="10" maxlength="100"></td>
  </tr>
  <tr> 
   <td width="150" class="label">Image</td>
   <td class="content"> <input name="fleImage" type="file" id="fleImage" class="box"> 
    </td>
  </tr>
 </table>
 <p align="center"> 
  <input name="btnAddProduct" type="button" id="btnAddProduct" value="Add Product" onClick="checkAddProductForm();" class="box">
  &nbsp;&nbsp;<input name="btnCancel" type="button" id="btnCancel" value="Cancel" onClick="window.location.href='index.php';" class="box">  
 </p>
</form>

Not sure if I already posted this... but here's /admin/product/processProduct.php:
PHP:
<?php
require_once '../../library/config.php';
require_once '../library/functions.php';

checkUser();

$action = isset($_GET['action']) ? $_GET['action'] : '';

switch ($action) {
	
	case 'addProduct' :
		addProduct();
		break;
		
	case 'modifyProduct' :
		modifyProduct();
		break;
		
	case 'deleteProduct' :
		deleteProduct();
		break;
	
	case 'deleteImage' :
		deleteImage();
		break;
	
	case 'addOffert' :
		addOffert();
		break;
		
	case 'modifyOffer' :
		modifyOffer();
		break;
    

	default :
	    // if action is not defined or unknown
		// move to main product page
		header('Location: index.php');
}


function addProduct()
{
    $catId       = $_POST['cboCategory'];
	$sku = $_POST['txtSku'];
    $name        = $_POST['txtName'];
	$description = $_POST['mtxDescription'];
	$direction = $_POST['txtDirection'];
	$benefits = $_POST['txtBenefites'];
	$size1 = $_POST['txtSize1'];
	$coverage1 = $_POST['txtCoverage1'];
	$price1       = str_replace(',', '', (double)$_POST['txtPrice1']);
	$qty1         = (int)$_POST['txtQty1'];
	$size2 = $_POST['txtSize2'];
	$coverage2 = $_POST['txtCoverage2'];
	$price2       = str_replace(',', '', (double)$_POST['txtPrice2']);
	$qty2         = (int)$_POST['txtQty2'];
	$size3 = $_POST['txtSize3'];
	$coverage3 = $_POST['txtCoverage3'];
	$price3       = str_replace(',', '', (double)$_POST['txtPrice3']);
	$qty3         = (int)$_POST['txtQty3'];
	if(!empty($_POST['txtSize4'])) {
		$size4 = $_POST['txtSize4'];
	} else {
		$size4 = '';
	}
	if(!empty($_POST['txtCoverage4'])) {
		$coverage4 = $_POST['txtCoverage4'];
	} else {
		$coverage4 = '';
	}
	if(!empty($_POST['txtPrice4'])) {
		$price4       = str_replace(',', '', (double)$_POST['txtPrice4']);
	} else {
		$price4       = '';
	}
	if(!empty($_POST['txtQty4'])) {
		$qty4         = (int)$_POST['txtQty4'];
	} else {
		$qty4         = '';
	}
	if(!empty($_POST['txtSize5'])) {
		$size5 = $_POST['txtSize5'];
	} else {
		$size5 = '';
	}
	if(!empty($_POST['txtCoverage5'])) {
		$coverage5 = $_POST['txtCoverage5'];
	} else {
		$coverage5 = '';
	}
	if(!empty($_POST['txtPrice5'])) {
		$price5       = str_replace(',', '', (double)$_POST['txtPrice5']);
	} else {
		$price5       = '';
	}
	if(!empty($_POST['txtQty5'])) {
		$qty5         = (int)$_POST['txtQty5'];
	} else {
		$qty5         = '';
	}
	
	$shipWithIn = $_POST['txtShipWithin'];
	
	
	$images = uploadProductImage('fleImage', SRV_ROOT . 'images/product/');

	$mainImage = $images['image'];
	$thumbnail = $images['thumbnail'];
	
	$sql   = "INSERT INTO tbl_product (cat_id, pd_sku, pd_name, pd_description, pd_direction, pd_benefits, pd_size1, pd_coverage1,  pd_price1, pd_qty1, pd_size2, pd_coverage2,  pd_price2, pd_qty2, pd_size3, pd_coverage3,  pd_price3, pd_qty3, pd_size4, pd_coverage4,  pd_price4, pd_qty4, pd_size5, pd_coverage5,  pd_price5, pd_qty5, pd_shipwithin, pd_image, pd_thumbnail, pd_date)
	          VALUES ('$catId', '$sku', '$name', '$description', '$direction', '$benefits', '$size1', '$coverage1', $price1, '$qty1', '$size2', '$coverage2', $price2, '$qty2', '$size3', '$coverage3', $price3, '$qty3', '$size4', '$coverage4', $price4, '$qty4','$size5', '$coverage5', $price5, '$qty5','$shipWithIn', '$mainImage', '$thumbnail', NOW())";

	$result = dbQuery($sql);
	
	header("Location: index.php");	
}

/*
	Upload an image and return the uploaded image name 
*/
function uploadProductImage($inputName, $uploadDir)
{
	$image     = $_FILES[$inputName];
	$imagePath = '';
	$thumbnailPath = '';
	
	// if a file is given
	if (trim($image['tmp_name']) != '') {
		$ext = substr(strrchr($image['name'], "."), 1); //$extensions[$image['type']];

		// generate a random new file name to avoid name conflict
		$imagePath = md5(rand() * time()) . ".$ext";
		
		list($width, $height, $type, $attr) = getimagesize($image['tmp_name']); 

		// make sure the image width does not exceed the
		// maximum allowed width
		if (LIMIT_PRODUCT_WIDTH && $width > MAX_PRODUCT_IMAGE_WIDTH) {
			$result    = createThumbnail($image['tmp_name'], $uploadDir . $imagePath, MAX_PRODUCT_IMAGE_WIDTH);
			$imagePath = $result;
		} else {
			$result = move_uploaded_file($image['tmp_name'], $uploadDir . $imagePath);
		}	
		
		if ($result) {
			// create thumbnail
			$thumbnailPath =  md5(rand() * time()) . ".$ext";
			$result = createThumbnail($uploadDir . $imagePath, $uploadDir . $thumbnailPath, THUMBNAIL_WIDTH);
			
			// create thumbnail failed, delete the image
			if (!$result) {
				unlink($uploadDir . $imagePath);
				$imagePath = $thumbnailPath = '';
			} else {
				$thumbnailPath = $result;
			}	
		} else {
			// the product cannot be upload / resized
			$imagePath = $thumbnailPath = '';
		}
		
	}

	
	return array('image' => $imagePath, 'thumbnail' => $thumbnailPath);
}

/*
	Modify a product
*/
function modifyProduct()
{
	$proId = (int)$_GET['productId'];
	$catId       = $_POST['cboCategory'];
	$sku = $_POST['txtSku'];
    $name        = $_POST['txtName'];
	$description = $_POST['mtxDescription'];
	$direction = $_POST['txtDirection'];
	$benefits = $_POST['txtBenefites'];
	$size1 = $_POST['txtSize1'];
	$coverage1 = $_POST['txtCoverage1'];
	$price1       = str_replace(',', '', (double)$_POST['txtPrice1']);
	$qty1         = (int)$_POST['txtQty1'];
	$size2 = $_POST['txtSize2'];
	$coverage2 = $_POST['txtCoverage2'];
	$price2       = str_replace(',', '', (double)$_POST['txtPrice2']);
	$qty2         = (int)$_POST['txtQty2'];
	$size3 = $_POST['txtSize3'];
	$coverage3 = $_POST['txtCoverage3'];
	$price3       = str_replace(',', '', (double)$_POST['txtPrice3']);
	$qty3         = (int)$_POST['txtQty3'];
	if(!empty($_POST['txtSize4'])) {
		$size4 = $_POST['txtSize4'];
	} else {
		$size4 = '';
	}
	if(!empty($_POST['txtCoverage4'])) {
		$coverage4 = $_POST['txtCoverage4'];
	} else {
		$coverage4 = '';
	}
	if(!empty($_POST['txtPrice4'])) {
		$price4       = str_replace(',', '', (double)$_POST['txtPrice4']);
	} else {
		$price4       = '';
	}
	if(!empty($_POST['txtQty4'])) {
		$qty4         = (int)$_POST['txtQty4'];
	} else {
		$qty4         = '';
	}
	if(!empty($_POST['txtSize5'])) {
		$size5 = $_POST['txtSize5'];
	} else {
		$size5 = '';
	}
	if(!empty($_POST['txtCoverage5'])) {
		$coverage5 = $_POST['txtCoverage5'];
	} else {
		$coverage5 = '';
	}
	if(!empty($_POST['txtPrice5'])) {
		$price5       = str_replace(',', '', (double)$_POST['txtPrice5']);
	} else {
		$price5       = '';
	}
	if(!empty($_POST['txtQty5'])) {
		$qty5         = (int)$_POST['txtQty5'];
	} else {
		$qty5         = '';
	}
	
	$shipWithIn = $_POST['txtShipWithin'];
	
	
	$images = uploadProductImage('fleImage', SRV_ROOT . 'images/product/');

	$mainImage = $images['image'];
	$thumbnail = $images['thumbnail'];

	// if uploading a new image
	// remove old image
	if ($mainImage != '') {
		_deleteImage($proId);
		
		$mainImage = "'$mainImage'";
		$thumbnail = "'$thumbnail'";
	} else {
		// if we're not updating the image
		// make sure the old path remain the same
		// in the database
		$mainImage = 'pd_image';
		$thumbnail = 'pd_thumbnail';
	}
			
	$sql   = "UPDATE tbl_product 
	          SET cat_id = '$catId', pd_sku = '$sku', pd_name = '$name', pd_description = '$description', pd_direction = '$direction', pd_benefits = '$benefits', pd_size1 = '$size1', pd_coverage1 = '$coverage1', pd_price1 = '$price1', pd_qty1 = '$qty1', pd_size2 = '$size2', pd_coverage2 = '$coverage2', pd_price2 = '$price2', pd_qty2 = '$qty2', pd_size3 = '$size3', pd_coverage3 = '$coverage3', pd_price3 = '$price3', pd_qty3 = '$qty3', pd_size4 = '$size4', pd_coverage4 = '$coverage4',  pd_price4 = '$price4', pd_qty4 = '$qty4', pd_size5 = '$size5', pd_coverage5 = '$coverage5',  pd_price5 = '$price4', pd_qty5 = '$qty5', pd_image = $mainImage, pd_thumbnail = $thumbnail
			  WHERE pd_id = $proId";  

	$result = dbQuery($sql);
	
	header('Location: index.php');			  
}

/*
	Remove a product
*/
function deleteProduct()
{
	if (isset($_GET['productId']) && (int)$_GET['productId'] > 0) {
		$productId = (int)$_GET['productId'];
	} else {
		header('Location: index.php');
	}
	
	// remove any references to this product from
	// tbl_order_item and tbl_cart
	$sql = "DELETE FROM tbl_order_item
	        WHERE pd_id = $productId";
	dbQuery($sql);
			
	$sql = "DELETE FROM tbl_cart
	        WHERE pd_id = $productId";	
	dbQuery($sql);
			
	// get the image name and thumbnail
	$sql = "SELECT pd_image, pd_thumbnail
	        FROM tbl_product
			WHERE pd_id = $productId";
			
	$result = dbQuery($sql);
	$row    = dbFetchAssoc($result);
	
	// remove the product image and thumbnail
	if ($row['pd_image']) {
		unlink(SRV_ROOT . 'images/product/' . $row['pd_image']);
		unlink(SRV_ROOT . 'images/product/' . $row['pd_thumbnail']);
	}
	
	// remove the product from database;
	$sql = "DELETE FROM tbl_product 
	        WHERE pd_id = $productId";
	dbQuery($sql);
	
	header('Location: index.php?catId=' . $_GET['catId']);
}


/*
	Remove a product image
*/
function deleteImage()
{
	if (isset($_GET['productId']) && (int)$_GET['productId'] > 0) {
		$productId = (int)$_GET['productId'];
	} else {
		header('Location: index.php');
	}
	
	$deleted = _deleteImage($productId);

	// update the image and thumbnail name in the database
	$sql = "UPDATE tbl_product
			SET pd_image = '', pd_thumbnail = ''
			WHERE pd_id = $productId";
	dbQuery($sql);		

	header("Location: index.php?view=modify&productId=$productId");
}

function _deleteImage($productId)
{
	// we will return the status
	// whether the image deleted successfully
	$deleted = false;
	
	$sql = "SELECT pd_image, pd_thumbnail 
	        FROM tbl_product
			WHERE pd_id = $productId";
	$result = dbQuery($sql) or die('Cannot delete product image. ' . mysql_error());
	
	if (dbNumRows($result)) {
		$row = dbFetchAssoc($result);
		extract($row);
		
		if ($pd_image && $pd_thumbnail) {
			// remove the image file
			$deleted = @unlink(SRV_ROOT . "images/product/$pd_image");
			$deleted = @unlink(SRV_ROOT . "images/product/$pd_thumbnail");
		}
	}
	
	return $deleted;
}


function addOffert() {
	$pdId = (int)$_GET['offId'];
	$offerAmount = $_POST['offerAmount'];
	$offDescription = $_POST['description'];
	
	$sql = "UPDATE tbl_product SET pd_offer_amount = '$offerAmount', pd_offer_description = '$offDescription' WHERE pd_id = '$pdId'";
	$result = dbQuery($sql);
	header("Location:index.php");
	
}

function modifyOffer() {
	$pdId = (int)$_GET['offId'];
	$offerAmount = $_POST['offerAmount'];
	$offDescription = $_POST['description'];
	
	$sql = "UPDATE tbl_product SET pd_offer_amount = '$offerAmount', pd_offer_description = '$offDescription' WHERE pd_id = '$pdId'";
	$result = dbQuery($sql);
	header("Location:index.php");
	
}

?>

I feel like you guys haven't given up on this yet - Thanks :)
 
  • #13
I dropped your files into my test installation, went to the page, filled out the form, and was able to submit it (my db schema doesn't match yours, so I got DB errors, but that was expected). So as far as I can tell, the code you posted should work well enough to submit the form. This makes me think that it may be something with your installation.

Since I still think it's a javascript issue, I'd suggest loading the page, then checking the javascript console for errors. (at least on firefox - I don't know which other browsers also have this).

Looking at the product.js and common.js, it doesn't look that complicated. However, your add.php is using FCKeditor for the description and directions. This is a lot of complicated javascript and css, so it's possible that it has something to do with this. Do all of your forms (add category, etc.) use this? If not, do the ones without it work? If they do, you might try upgrading FCKeditor.
 
  • #14
Interesting. So you know what open source shopping was used... for a fact?

I never knew about that ability of FireFox to catch errors... but I just opened it up and see a couple things... that may be of interest.

Oh, I also noticed... I forgot to input the category on the add product page and it successfully caught that error - "Oops - You forgot to select a category"... I entered that again clicked the button - nothing.

Now... for the errors!

The first one, in bold, say exactly this:
Error: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMEventTarget.removeEventListener]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: chrome://searchshield/content/avgls-active.js :: avg_ls_content_loaded :: line 11" data: no]​

I'm not really sure if that has something to do with the site or not... so moving on to the 2 other errors that I know apply to this situation:

1.
Error: checkNumber is not defined
Source File: http://www.firebellylawncare.com/admin/product/index.php?view=add&catId=0
Line: 1​

2.
Error: isEmpty is not defined
Source File: http://www.firebellylawncare.com/admin/library/product.js
Line: 20​

Surprisingly nothing for the Add.php... but index.php (#1) and product.js (#2). They don't seem like anything huge... but I don't know php (or is that JS?).

Again, fingeres crossed...
 
  • #15
UPDATE:

Error #1 (checkNumber is not defined) only occurs when I enter a number into the "Qty In Stock" field on my admin page.

Error #2 (isEmpty is not defined) occurs each time I hit the "Add Product" submit button.

Somehow, I feel like we're getting close?
 
  • #16
Interesting. So you know what open source shopping was used... for a fact?

Yes, the cart software is definitely what I linked earlier. The code is almost identical (some stuff was added to your version).



checkNumber and isEmpty are both defined in library/common.js which should be included. For example, if I "view source" from the product add page, I see
Code:
<script language="JavaScript" type="text/javascript" src="/test_cart/plaincart/library/common.js"></script>
<script language="JavaScript" type="text/javascript" src="/test_cart/plaincart/admin/library/product.js"></script></head>

You should have something similar.


Error: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMEventTarget.removeEventListener]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: chrome://searchshield/content/avgls-active.js :: avg_ls_content_loaded :: line 11" data: no]

This looks like something being injected by your antivirus (AVG). I don't know if it's related, but for troubleshooting purposes, it might be worth temporarily disabling it (or at least the browser-integrated features). The uncaught exception *might* be what's killing the rest of your JS.
 

1. What is the issue with FireBellyLawnCare.com CMS?

The issue with FireBellyLawnCare.com CMS is that it is experiencing problems with PHP, a server-side scripting language commonly used for web development.

2. How can I solve the PHP issue with FireBellyLawnCare.com CMS?

To solve the PHP issue with FireBellyLawnCare.com CMS, you can start by checking for any syntax errors in the PHP code. You can also try updating the PHP version and ensuring that all necessary PHP extensions are enabled.

3. Why is it important to solve the PHP issue with FireBellyLawnCare.com CMS?

It is important to solve the PHP issue with FireBellyLawnCare.com CMS because PHP is a crucial component of the website's functionality. If the issue is not resolved, the website may not function properly and could potentially lead to a loss of business or traffic.

4. Can the PHP issue with FireBellyLawnCare.com CMS be caused by other factors?

Yes, the PHP issue with FireBellyLawnCare.com CMS can also be caused by other factors such as conflicting plugins, incorrect server configurations, or outdated software. It is important to thoroughly troubleshoot and identify the root cause of the issue.

5. What are some resources for solving PHP issues with FireBellyLawnCare.com CMS?

Some resources for solving PHP issues with FireBellyLawnCare.com CMS include online forums, developer communities, and documentation from the PHP and CMS providers. You can also consider hiring a web developer with experience in PHP to assist with troubleshooting and resolving the issue.

Similar threads

  • Programming and Computer Science
Replies
13
Views
2K
  • Programming and Computer Science
Replies
7
Views
5K
  • Programming and Computer Science
Replies
5
Views
3K
  • Programming and Computer Science
Replies
4
Views
6K
  • Programming and Computer Science
Replies
2
Views
2K
  • Electrical Engineering
Replies
33
Views
530
  • Programming and Computer Science
Replies
3
Views
2K
  • Programming and Computer Science
Replies
1
Views
3K
  • Programming and Computer Science
Replies
4
Views
2K
  • Programming and Computer Science
Replies
2
Views
1K
Back
Top