Location: PHPKode > projects > Grocery List > include/upc.php
<?php
########################################################################
#
# Project: Grocery List
# URL: http://sourceforge.net/projects/grocery-list/
# E-mail: hide@address.com
#
# Copyright: (C) 2010, Neil McNab
# License: GNU General Public License Version 3
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Filename: $URL: https://grocery-list.svn.sourceforge.net/svnroot/grocery-list/releases/1.0/include/upc.php $
# Last Updated: $Date: 2010-03-07 21:53:54 -0800 (Sun, 07 Mar 2010) $
# Author(s): Neil McNab
#
# Description:
#   Generic UPC functions.
#
########################################################################

include_once("db.php");
include_once("cuecat.php");

// define database lookup order
if (!isset($UPC_DBS)) {
    $UPC_DBS = array('upcdatabase');
}

// define database cache timeout
if (!isset($UPCCACHE_TIMEOUT)) {
    $UPCCACHE_TIMEOUT=3600*24*30;
}

// define database cache record limit
if (!isset($UPCCACHE_LIMIT)) {
    $UPCCACHE_LIMIT=10000000;
}

function get_upc($db, $upc) {
    $result = array();

    if (empty($upc)) {
        return $result;
    }
    if ((substr($upc, 0, 1) == ".") AND (substr($upc, -1, 1) == ".")) {
	$upc = cuecat_decode($upc);
    }
    $upc = trim(convert_upce($upc));

    $response = upc_lookup_cached($db,$upc);
    //overwrite with our custom data
    $newresult = get_item_by_upc($db, $upc);

    if ($response === FALSE) {
        echo "<p>Errors detected during UPCdatabase lookup<br>Please confirm results before continuing</p>";
    } elseif (is_array($response)) {
        if (array_key_exists('description', $response)) {
                $desc = trim($response['description']);
        }

        if (array_key_exists('size', $response)) {
                $pattern = "/^([xX\.0-9\/]*)(.*)/";
                preg_match($pattern, trim($response['size']), $matches);
                $size = trim($matches[1]);
                $units = measure_unit_normalize($matches[2]);
        }
        $result = array_merge($result, array('itemname' => $desc, 'size' => $size, 'units' => $units));
        $result['upc'] = $response['upc'];
    } elseif ($response !== TRUE AND $newresult === NULL) {
        print "<p>Bar code not found: " . $response . "</p>";
        $result['upc'] = $upc;
    }

    foreach (array('upc','size','units','itemname','productid','itemid') as $key) {
        if (!empty($newresult[$key])) {
            $result[$key] = $newresult[$key];
        }
    }
    return $result;
}

function upc_lookup_cached($connection, $upc) {
	global $UPCCACHE_TIMEOUT, $UPCCACHE_LIMIT, $UPC_DBS;

	// check if exists in database, ignore if older than one month
        $sql = "SELECT * FROM upccache WHERE upc='$upc'";

        $sql_result = $connection->query($sql);

        $row = $sql_result->fetch();
	$updatesql = "INSERT INTO upccache SET upc=%s,itemname=%s,sizeweight=%s,timestamp=NULL";
        if ($row !== FALSE) {
		//print sprintf("%s", time() - strtotime($row['timestamp']));
		if ((time() - strtotime($row['timestamp'])) < $UPCCACHE_TIMEOUT ) {
			// if exist, return value 
			$connection = NULL;
			return array('description' => $row['itemname'], 'size' => $row['sizeweight'], 'upc' => $upc);
		}
		$updatesql = "UPDATE upccache SET upc=%s,itemname=%s,sizeweight=%s,timestamp=NULL WHERE upc=$upc";
	}
	// do lookup here
        $result = upc_backend_lookup_search($upc, $UPC_DBS);

            // remove if too many entries
            $count = intval(dboneshot($connection, "SELECT count(*) FROM upccache"));
            if ($count > $UPCCACHE_LIMIT) {
                $connection->exec("DELETE FROM upccache ORDER BY timestamp LIMIT " . strval($count - $UPCCACHE_LIMIT));
            }

		// add upc_lookup results to database
        	$sql = sprintf($updatesql, $connection->quote($upc), $connection->quote($result['description']), $connection->quote($result['size']));
        	$sql_result = $connection->exec($sql);
                if (!$sql_result) {
                    print "update failed 50";
                }
	
	return array_merge(array("upc" => $upc), $result);
}

function upc_backend_lookup_search($upc, $searches=array('upcdatabase')) {
    $result = array();
    // this prioritizes lookups
    for($i = 0; $i < sizeof($searches); $i++) {
        $tempresult = upc_backend_lookup($upc, $searches[$i]);
        // add results here
        if (!empty($tempresult['description']) AND empty($result['description'])) {
            $result['description'] = $tempresult['description'];
        }
        if (!empty($tempresult['size']) AND empty($result['size'])) {
            $result['size'] = $tempresult['size'];
        }
    }

    return $result;
}

function upc_backend_lookup($upc, $db='upcdatabase') {
    // this connects to the various backends
    if ($db == 'upcdatabase') {
        @include_once('upcdb.php');
        if (function_exists('upc_lookup'))
            return upc_lookup($upc);
    }
    if ($db == 'upcdata') {
        @include_once('upcdata.php');
        if (function_exists('upcdata_lookup'))
            return upcdata_lookup($upc);
    }
    if ($db == 'amazon') {
        @include_once('amazon.php');
        if (function_exists('amazon_upc_lookup'))
            return amazon_upc_lookup($upc);
    }
    return array();
}

function compute_check_digit($upc) {
    $upca = convert_upce($upc);
    if (strlen($upca) == 13) {
        $upca = substr($upca, 1);
    }
    $check = 0;
    for ($i = 0; $i < strlen($upca); $i++) {
        if ($i % 2) {
            $check += intval(substr($upca, $i, 1));
        } else {
            $check += intval(substr($upca, $i, 1)) * 3;
        }
    }
    $check = $check % 10;
    if ($check != 0) {
        $check = 10 - $check;
    }
    return substr($upc, 0, -1) . strval($check);
}

function convert_upce($Item) {
  // http://www.barcodeisland.com/upce.phtml
  if (strlen($Item) == 8) {
    $upca = '';
    if ($Item[6] == '0' OR $Item[6] == '1' OR $Item[6] == '2') {
      $upca .= $Item[1] . $Item[2] . $Item[6] . '0000' . $Item[3] . $Item[4] . $Item[5];
    } elseif ($Item[6] == '3') {
      $upca .= $Item[1] . $Item[2] . $Item[3] . '00000' . $Item[4] . $Item[5];
    } elseif ($Item[6] == '4') {
      $upca .= $Item[1] . $Item[2] . $Item[3] . $Item[4] . '00000' . $Item[5];
    } else {
      $upca .= $Item[1] . $Item[2] . $Item[3] . $Item[4] . $Item[5] . '0000' . $Item[6];
    }
    return $Item[0] . $upca . $Item[7];
  }
  return $Item;
}

//print compute_check_digit('0872710X');
//print compute_check_digit('0522580X');

?>
Return current item: Grocery List