PageRenderTime 133ms CodeModel.GetById 24ms RepoModel.GetById 2ms app.codeStats 0ms

/administrator/components/com_virtuemart/classes/ps_product.php

https://bitbucket.org/dgough/annamaria-daneswood-25102012
PHP | 2743 lines | 1976 code | 250 blank | 517 comment | 367 complexity | 912628defcddc12db09e6304fee92fb8 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
  3. /**
  4. *
  5. * @version $Id: ps_product.php 1475 2008-07-16 17:35:35Z soeren_nb $
  6. * @package VirtueMart
  7. * @subpackage classes
  8. * @copyright Copyright (C) 2004-2008 soeren - All rights reserved.
  9. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  10. * VirtueMart is free software. This version may have been modified pursuant
  11. * to the GNU General Public License, and as distributed it includes or
  12. * is derivative of works licensed under the GNU General Public License or
  13. * other free or open source software licenses.
  14. * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
  15. *
  16. * http://virtuemart.net
  17. */
  18. /**
  19. * The class is is used to manage product repository.
  20. * @package virtuemart
  21. * @author pablo, jep, gday, soeren
  22. *
  23. */
  24. class ps_product extends vmAbstractObject {
  25. var $_key = 'product_id';
  26. var $_table_name = '#__{vm}_product';
  27. /**
  28. * Validates product fields and uploaded image files.
  29. *
  30. * @param array $d The input vars
  31. * @return boolean True when validation successful, false when not
  32. */
  33. function validate(&$d) {
  34. global $vmLogger, $database, $perm, $VM_LANG;
  35. require_once(CLASSPATH . 'imageTools.class.php' );
  36. $valid = true;
  37. $db = new ps_DB;
  38. $q = "SELECT product_id,product_thumb_image,product_full_image FROM #__{vm}_product WHERE product_sku='";
  39. $q .= $d["product_sku"] . "'";
  40. $db->setQuery($q); $db->query();
  41. if ($db->next_record()&&($db->f("product_id") != $d["product_id"])) {
  42. $vmLogger->err( "A Product with the SKU ".$d['product_sku']." already exists." );
  43. $valid = false;
  44. }
  45. if( !empty( $d['product_discount_id'] )) {
  46. if( $d['product_discount_id'] == "override" ) {
  47. $d['is_percent'] = "0";
  48. // If discount are applied before tax then base the discount on the untaxed price
  49. if( PAYMENT_DISCOUNT_BEFORE == '1' ) {
  50. $d['amount'] = (float)$d['product_price'] - (float)$d['discounted_price_override'];
  51. }
  52. // Otherwise, base the discount on the taxed price
  53. else {
  54. $d['amount'] = (float)$d['product_price_incl_tax'] - (float)$d['discounted_price_override'];
  55. }
  56. // Set the discount start date as today
  57. $d['start_date'] = date( 'Y-m-d' );
  58. require_once( CLASSPATH. 'ps_product_discount.php' );
  59. $ps_product_discount = new ps_product_discount;
  60. $ps_product_discount->add( $d );
  61. $d['product_discount_id'] = $database->insertid();
  62. vmRequest::setVar( 'product_discount_id', $d['product_discount_id'] );
  63. }
  64. }
  65. if (empty($d['manufacturer_id'])) {
  66. $d['manufacturer_id'] = "1";
  67. }
  68. if (empty( $d["product_sku"])) {
  69. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_MISSING_SKU',false) );
  70. $valid = false;
  71. }
  72. if (!$d["product_name"]) {
  73. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_MISSING_NAME',false) );
  74. $valid = false;
  75. }
  76. if (empty($d["product_available_date"])) {
  77. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_MISSING_AVAILDATE',false) );
  78. $valid = false;
  79. }
  80. else {
  81. $day = (int) substr ( $d["product_available_date"], 8, 2);
  82. $month= (int) substr ( $d["product_available_date"], 5, 2);
  83. $year = (int) substr ( $d["product_available_date"], 0, 4);
  84. $d["product_available_date_timestamp"] = mktime(0,0,0,$month, $day, $year);
  85. }
  86. /** Validate Product Specific Fields **/
  87. if (!$d["product_parent_id"]) {
  88. if( empty( $d['product_categories']) || !is_array(@$d['product_categories'])) {
  89. $d['product_categories'] = explode('|', $d['category_ids'] );
  90. }
  91. if (sizeof(@$d["product_categories"]) < 1) {
  92. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_MISSING_CATEGORY') );
  93. $valid = false;
  94. }
  95. }
  96. /** Image Upload Validation **/
  97. // do we have an image URL or an image File Upload?
  98. if (!empty( $d['product_thumb_image_url'] )) {
  99. // Image URL
  100. if (substr( $d['product_thumb_image_url'], 0, 4) != "http") {
  101. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_IMAGEURL_MUSTBEGIN',false) );
  102. $valid = false;
  103. }
  104. // if we have an uploaded image file, prepare this one for deleting.
  105. if( $db->f("product_thumb_image") && substr( $db->f("product_thumb_image"), 0, 4) != "http") {
  106. $_REQUEST["product_thumb_image_curr"] = $db->f("product_thumb_image");
  107. $d["product_thumb_image_action"] = "delete";
  108. if (!vmImageTools::validate_image($d,"product_thumb_image","product")) {
  109. return false;
  110. }
  111. }
  112. $d["product_thumb_image"] = $d['product_thumb_image_url'];
  113. }
  114. else {
  115. // File Upload
  116. if (!vmImageTools::validate_image($d,"product_thumb_image","product")) {
  117. $valid = false;
  118. }
  119. }
  120. if (!empty( $d['product_full_image_url'] )) {
  121. // Image URL
  122. if (substr( $d['product_full_image_url'], 0, 4) != "http") {
  123. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_IMAGEURL_MUSTBEGIN',false) );
  124. return false;
  125. }
  126. // if we have an uploaded image file, prepare this one for deleting.
  127. if( $db->f("product_full_image") && substr( $db->f("product_full_image"), 0, 4) != "http") {
  128. $_REQUEST["product_full_image_curr"] = $db->f("product_full_image");
  129. $d["product_full_image_action"] = "delete";
  130. if (!vmImageTools::validate_image($d,"product_full_image","product")) {
  131. return false;
  132. }
  133. }
  134. $d["product_full_image"] = $d['product_full_image_url'];
  135. }
  136. else {
  137. // File Upload
  138. if (!vmImageTools::validate_image($d,"product_full_image","product")) {
  139. $valid = false;
  140. }
  141. }
  142. // added for advanced attribute modification
  143. // strips the trailing semi-colon from an attribute
  144. if(isset($d["product_advanced_attribute"])) {
  145. if (';' == substr($d["product_advanced_attribute"], strlen($d["product_advanced_attribute"])-1,1) ) {
  146. $d["product_advanced_attribute"] =substr($d["product_advanced_attribute"], 0, strlen($d["product_advanced_attribute"])-1);
  147. }
  148. }
  149. // added for custom attribute modification
  150. // strips the trailing semi-colon from an attribute
  151. if(isset($d["product_custom_attribute"])) {
  152. if (';' == substr($d["product_custom_attribute"], strlen($d["product_custom_attribute"])-1,1) ) {
  153. $d["product_custom_attribute"] =substr($d["product_custom_attribute"], 0, strlen($d["product_custom_attribute"])-1);
  154. }
  155. }
  156. $d["clone_product"] = empty($d["clone_product"]) ? "N" : "Y";
  157. $d["product_publish"] = empty($d["product_publish"]) ? "N" : "Y";
  158. $d["product_special"] = empty($d["product_special"]) ? "N" : "Y";
  159. //parse quantity and child options
  160. $d['display_headers'] = vmGet($d,'display_headers', 'Y') =='Y' ? 'Y' : 'N';
  161. $d['product_list_child'] = vmGet($d,'product_list_child', 'Y') =='Y' ? 'Y' : 'N';
  162. $d['display_use_parent'] = vmGet($d,'display_use_parent', 'Y') =='Y' ? 'Y' : 'N';
  163. $d['product_list_type'] = vmGet($d,'product_list_type', 'Y') =='Y' ? 'Y' : 'N';
  164. $d['display_desc'] = vmGet($d,'display_desc', 'Y') =='Y' ? 'Y' : 'N';
  165. if (@$d['product_list'] =="Y") {
  166. if($d['list_style'] == "one")
  167. $d['product_list'] = "Y";
  168. else
  169. $d['product_list'] = "YM";
  170. }
  171. else {
  172. $d['product_list'] = "N";
  173. }
  174. $d['quantity_options'] = ps_product::set_quantity_options($d);
  175. $d['child_options'] = ps_product::set_child_options($d);
  176. $d['order_levels'] = vmRequest::getInt('min_order_level').",".vmRequest::getInt('max_order_level');
  177. return $valid;
  178. }
  179. /**
  180. * Validates that a product can be deleted
  181. *
  182. * @param array $d The input vars
  183. * @return boolean Validation sucessful?
  184. */
  185. function validate_delete( $product_id, &$d ) {
  186. global $vmLogger, $VM_LANG;
  187. require_once(CLASSPATH . 'imageTools.class.php' );
  188. /* Check that ps_vendor_id and product_id match
  189. if (!$this->check_vendor($d)) {
  190. $d["error"] = "ERROR: Cannot delete product. Wrong product or vendor." ;
  191. return false;
  192. }*/
  193. if (empty($product_id)) {
  194. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_SPECIFY_DELETE',false) );
  195. return false;
  196. }
  197. /* Get the image filenames from the database */
  198. $db = new ps_DB;
  199. $q = "SELECT product_thumb_image,product_full_image ";
  200. $q .= "FROM #__{vm}_product ";
  201. $q .= "WHERE product_id='$product_id'";
  202. $db->setQuery($q); $db->query();
  203. $db->next_record();
  204. /* Prepare product_thumb_image for Deleting */
  205. if( !stristr( $db->f("product_thumb_image"), "http") ) {
  206. $_REQUEST["product_thumb_image_curr"] = $db->f("product_thumb_image");
  207. $d["product_thumb_image_action"] = "delete";
  208. if (!vmImageTools::validate_image($d,"product_thumb_image","product")) {
  209. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_IMGDEL_FAILED',false) );
  210. return false;
  211. }
  212. }
  213. /* Prepare product_full_image for Deleting */
  214. if( !stristr( $db->f("product_full_image"), "http") ) {
  215. $_REQUEST["product_full_image_curr"] = $db->f("product_full_image");
  216. $d["product_full_image_action"] = "delete";
  217. if (!vmImageTools::validate_image($d,"product_full_image","product")) {
  218. return false;
  219. }
  220. }
  221. return true;
  222. }
  223. /**
  224. * Function to add a new product into the product table
  225. *
  226. * @param array $d The input vars
  227. * @return boolean True, when the product was added, false when not
  228. */
  229. function add( &$d ) {
  230. global $perm, $vmLogger, $VM_LANG;
  231. $database = new ps_DB();
  232. if (!$this->validate($d)) {
  233. return false;
  234. }
  235. if (!vmImageTools::process_images($d)) {
  236. return false;
  237. }
  238. $timestamp = time();
  239. $db = new ps_DB;
  240. $ps_vendor_id = $_SESSION["ps_vendor_id"];
  241. if( $perm->check( 'admin' )) {
  242. $vendor_id = $d['vendor_id'];
  243. }
  244. else {
  245. $vendor_id = $ps_vendor_id;
  246. }
  247. // Insert into DB
  248. $fields = array ( 'vendor_id' => $vendor_id,
  249. 'product_parent_id' => vmRequest::getInt('product_parent_id'),
  250. 'product_sku' => vmGet($d,'product_sku'),
  251. 'product_name' => vmGet($d,'product_name'),
  252. 'product_desc' => vmRequest::getVar('product_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
  253. 'product_s_desc' => vmRequest::getVar('product_s_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
  254. 'product_thumb_image' => vmGet($d,'product_thumb_image'),
  255. 'product_full_image' => vmGet($d,'product_full_image'),
  256. 'product_publish' => $d['product_publish'],
  257. 'product_weight' => vmRequest::getFloat('product_weight'),
  258. 'product_weight_uom' => vmGet($d,'product_weight_uom'),
  259. 'product_length' => vmRequest::getFloat('product_length'),
  260. 'product_width' => vmRequest::getFloat('product_width'),
  261. 'product_height' => vmRequest::getFloat('product_height'),
  262. 'product_lwh_uom' => vmGet($d,'product_lwh_uom'),
  263. 'product_unit' => vmGet($d,'product_unit'),
  264. 'product_packaging' => (($d["product_box"] << 16) | ($d["product_packaging"]&0xFFFF)),
  265. 'product_url' => vmGet($d,'product_url'),
  266. 'product_in_stock' => vmRequest::getInt('product_in_stock'),
  267. 'attribute' => ps_product_attribute::formatAttributeX(),
  268. 'custom_attribute' => vmGet($d,'product_custom_attribute'),
  269. 'product_available_date' => $d['product_available_date_timestamp'],
  270. 'product_availability' => vmGet($d,'product_availability'),
  271. 'product_special' => $d['product_special'],
  272. 'child_options' => $d['child_options'],
  273. 'quantity_options' => $d['quantity_options'],
  274. 'product_discount_id' => vmRequest::getInt('product_discount_id'),
  275. 'cdate' => $timestamp,
  276. 'mdate' => $timestamp,
  277. 'product_tax_id' => vmRequest::getInt('product_tax_id'),
  278. 'child_option_ids' => vmGet($d,'included_product_id'),
  279. 'product_order_levels' => $d['order_levels'] );
  280. $db->buildQuery('INSERT', '#__{vm}_product', $fields );
  281. if( $db->query() === false ) {
  282. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_ADDING_FAILED',false) );
  283. return false;
  284. }
  285. $d["product_id"] = $_REQUEST['product_id'] = $db->last_insert_id();
  286. // If is Item, add attributes from parent //
  287. if ($d["product_parent_id"]) {
  288. $q = "SELECT attribute_name FROM #__{vm}_product_attribute_sku ";
  289. $q .= "WHERE product_id='" . vmRequest::getInt('product_parent_id') . "' ";
  290. $q .= "ORDER BY attribute_list,attribute_name";
  291. $db->query($q);
  292. $db2 = new ps_DB;
  293. $i = 0;
  294. while($db->next_record()) {
  295. $i++;
  296. $q = "INSERT INTO #__{vm}_product_attribute (`product_id`,`attribute_name`,`attribute_value`) VALUES ";
  297. $q .= "('".$d["product_id"]."', '".$db->f("attribute_name", false)."', '".vmGet($d,'attribute_'.$i )."')";
  298. $db2->query( $q );
  299. }
  300. }
  301. else {
  302. // If is Product, Insert category ids
  303. if( empty( $d['product_categories']) || !is_array(@$d['product_categories'])) {
  304. $d['product_categories'] = explode('|', $d['category_ids'] );
  305. }
  306. foreach( $d["product_categories"] as $category_id ) {
  307. $db->query('SELECT MAX(`product_list`) as list_order FROM `#__{vm}_product_category_xref` WHERE `category_id`='.$category_id );
  308. $db->next_record();
  309. $q = "INSERT INTO #__{vm}_product_category_xref ";
  310. $q .= "(category_id,product_id,product_list) ";
  311. $q .= "VALUES ('$category_id','". $d["product_id"] . "', ".intval($db->f('max') +1 ) . ")";
  312. $db->setQuery($q); $db->query();
  313. }
  314. }
  315. $q = "INSERT INTO #__{vm}_product_mf_xref VALUES (";
  316. $q .= "'".$d['product_id']."', '".vmRequest::getInt('manufacturer_id')."')";
  317. $db->setQuery($q); $db->query();
  318. if( !empty($d["related_products"])) {
  319. /* Insert Pipe separated Related Product IDs */
  320. $related_products = vmGet( $d, "related_products" );
  321. $q = "INSERT INTO #__{vm}_product_relations ";
  322. $q .= "(product_id, related_products) ";
  323. $q .= "VALUES ('".$d["product_id"]."','".$db->getEscaped($related_products)."')";
  324. $db->setQuery($q); $db->query();
  325. }
  326. // ADD A PRICE, IF NOT EMPTY ADD 0
  327. if (!empty($d['product_price'])) {
  328. if(empty($d['product_currency'])) {
  329. $d['product_currency'] = $_SESSION['vendor_currency'];
  330. }
  331. $d["price_quantity_start"] = 0;
  332. $d["price_quantity_end"] = "";
  333. require_once ( CLASSPATH. 'ps_product_price.php');
  334. $my_price = new ps_product_price;
  335. $my_price->add($d);
  336. }
  337. if( !empty( $d['product_type_id'])) {
  338. require_once( CLASSPATH.'ps_product_product_type.php' );
  339. $ps_product_product_type = new ps_product_product_type();
  340. $ps_product_product_type->add( $d );
  341. // Product Type Parameters!
  342. $this->handleParameters( $d );
  343. }
  344. // CLONE PRODUCT additional code
  345. if( $d["clone_product"] == "Y" ) {
  346. // Clone Parent Product's Attributes
  347. $q = "INSERT INTO #__{vm}_product_attribute_sku
  348. SELECT '".$d["product_id"]."', attribute_name, attribute_list
  349. FROM #__{vm}_product_attribute_sku WHERE product_id='" . (int)$d["old_product_id"] . "' ";
  350. $db->query( $q );
  351. if( !empty( $d["child_items"] )) {
  352. $database->query( "SHOW COLUMNS FROM #__{vm}_product" );
  353. $rows = $database->record;
  354. while(list(,$Field) = each( $rows) ) {
  355. $product_fields[$Field->Field] = $Field->Field;
  356. }
  357. // Change the Field Names
  358. // leave empty for auto_increment
  359. $product_fields["product_id"] = "''";
  360. // Update Product Parent ID to the new one
  361. $product_fields["product_parent_id"] = "'".$d["product_id"]."'";
  362. // Rename the SKU
  363. $product_fields["product_sku"] = "CONCAT(product_sku,'_".$d["product_id"]."')";
  364. $rows = Array();
  365. $database->query( "SHOW COLUMNS FROM #__{vm}_product_price" );
  366. $rows = $database->record;
  367. while(list(,$Field) = each( $rows) ) {
  368. $price_fields[$Field->Field] = $Field->Field;
  369. }
  370. foreach( $d["child_items"] as $child_id ) {
  371. $q = "INSERT INTO #__{vm}_product ";
  372. $q .= "SELECT ".implode(",", $product_fields )." FROM #__{vm}_product WHERE product_id='$child_id'";
  373. $db->query( $q );
  374. $new_product_id = $db->last_insert_id();
  375. $q = "INSERT INTO #__{vm}_product_attribute
  376. SELECT NULL, '$new_product_id', attribute_name, attribute_value
  377. FROM #__{vm}_product_attribute WHERE product_id='$child_id'";
  378. $db->query( $q );
  379. $price_fields["product_price_id"] = "''";
  380. $price_fields["product_id"] = "'$new_product_id'";
  381. $q = "INSERT INTO #__{vm}_product_price ";
  382. $q .= "SELECT ".implode(",", $price_fields )." FROM #__{vm}_product_price WHERE product_id='$child_id'";
  383. $db->query( $q );
  384. }
  385. }
  386. // End Cloning
  387. }
  388. if( $d['clone_product'] == 'Y') {
  389. $vmLogger->info( $VM_LANG->_('VM_PRODUCT_CLONED',false) );
  390. }
  391. else {
  392. $vmLogger->info( $VM_LANG->_('VM_PRODUCT_ADDED',false) );
  393. }
  394. return true;
  395. }
  396. /**
  397. * Function to update product $d['product_id'] in the product table
  398. *
  399. * @param array $d The input vars
  400. * @return boolean True, when the product was updated, false when not
  401. */
  402. function update( &$d ) {
  403. global $vmLogger, $perm, $VM_LANG;
  404. require_once(CLASSPATH.'ps_product_attribute.php');
  405. if (!$this->validate($d)) {
  406. return false;
  407. }
  408. if (!vmImageTools::process_images($d)) {
  409. return false;
  410. }
  411. $timestamp = time();
  412. $db = new ps_DB;
  413. $ps_vendor_id = $_SESSION["ps_vendor_id"];
  414. if( $perm->check( 'admin' )) {
  415. $vendor_id = $d['vendor_id'];
  416. }
  417. else {
  418. $vendor_id = $ps_vendor_id;
  419. }
  420. $old_vendor_id = $this->get_field($d['product_id'], 'vendor_id');
  421. // Insert into DB
  422. $fields = array ( 'vendor_id' => $vendor_id,
  423. 'product_sku' => vmGet($d,'product_sku'),
  424. 'product_name' => vmGet($d,'product_name'),
  425. 'product_desc' => vmRequest::getVar('product_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
  426. 'product_s_desc' => vmRequest::getVar('product_s_desc', '', 'default', '', VMREQUEST_ALLOWHTML),
  427. 'product_thumb_image' => vmGet($d,'product_thumb_image'),
  428. 'product_full_image' => vmGet($d,'product_full_image'),
  429. 'product_publish' => $d['product_publish'],
  430. 'product_weight' => vmRequest::getFloat('product_weight'),
  431. 'product_weight_uom' => vmGet($d,'product_weight_uom'),
  432. 'product_length' => vmRequest::getFloat('product_length'),
  433. 'product_width' => vmRequest::getFloat('product_width'),
  434. 'product_height' => vmRequest::getFloat('product_height'),
  435. 'product_lwh_uom' => vmGet($d,'product_lwh_uom'),
  436. 'product_unit' => vmGet($d,'product_unit'),
  437. 'product_packaging' => (($d["product_box"] << 16) | ($d["product_packaging"]&0xFFFF)),
  438. 'product_url' => vmGet($d,'product_url'),
  439. 'product_in_stock' => vmRequest::getInt('product_in_stock'),
  440. 'attribute' => ps_product_attribute::formatAttributeX(),
  441. 'custom_attribute' => vmGet($d,'product_custom_attribute'),
  442. 'product_available_date' => $d['product_available_date_timestamp'],
  443. 'product_availability' => vmGet($d,'product_availability'),
  444. 'product_special' => $d['product_special'],
  445. 'child_options' => $d['child_options'],
  446. 'quantity_options' => $d['quantity_options'],
  447. 'product_discount_id' => vmRequest::getInt('product_discount_id'),
  448. 'mdate' => $timestamp,
  449. 'product_tax_id' => vmRequest::getInt('product_tax_id'),
  450. 'child_option_ids' => vmGet($d,'included_product_id'),
  451. 'product_order_levels' => $d['order_levels'] );
  452. $db->buildQuery( 'UPDATE', '#__{vm}_product', $fields, 'WHERE product_id='. (int)$d["product_id"] . ' AND vendor_id=' . (int)$old_vendor_id );
  453. $db->query();
  454. /* notify the shoppers that the product is here */
  455. /* see zw_waiting_list */
  456. if ($d["product_in_stock"] > "0" && @$d['notify_users'] == '1' && $d['product_in_stock_old'] == '0') {
  457. require_once( CLASSPATH . 'zw_waiting_list.php');
  458. $zw_waiting_list = new zw_waiting_list;
  459. $zw_waiting_list->notify_list($d["product_id"]);
  460. }
  461. $q = "UPDATE #__{vm}_product_mf_xref SET ";
  462. $q .= 'manufacturer_id='.vmRequest::getInt('manufacturer_id').' ';
  463. $q .= 'WHERE product_id = '.$d['product_id'];
  464. $db->query($q);
  465. /* If is Item, update attributes */
  466. if( !empty($d["product_parent_id"])) {
  467. $q = "SELECT attribute_name FROM #__{vm}_product_attribute_sku ";
  468. $q .= 'WHERE product_id=' .(int)$d["product_parent_id"] . ' ';
  469. $q .= "ORDER BY attribute_list,attribute_name";
  470. $db->query($q);
  471. $db2 = new ps_DB;
  472. $i = 0;
  473. while($db->next_record()) {
  474. $i++;
  475. $q2 = "UPDATE #__{vm}_product_attribute SET ";
  476. $q2 .= "attribute_value='" .vmGet($d,'attribute_'.$i ) . "' ";
  477. $q2 .= "WHERE product_id = '" . $d["product_id"] . "' ";
  478. $q2 .= "AND attribute_name = '" . $db->f("attribute_name", false ) . "' ";
  479. $db2->setQuery($q2); $db2->query();
  480. }
  481. /* If it is a Product, update Category */
  482. }
  483. else {
  484. // Handle category selection: product_category_xref
  485. $q = "SELECT `category_id` FROM `#__{vm}_product_category_xref` ";
  486. $q .= "WHERE `product_id` = '" . $d["product_id"] . "' ";
  487. $db->setQuery($q);
  488. $db->query();
  489. $old_categories = array();
  490. while( $db->next_record()) {
  491. $old_categories[$db->f('category_id')] = $db->f('category_id');
  492. }
  493. // NOW Insert new categories
  494. $new_categories = array();
  495. if( empty( $d['product_categories']) || !is_array(@$d['product_categories'])) {
  496. $d['product_categories'] = explode('|', $d['category_ids'] );
  497. }
  498. foreach( $d["product_categories"] as $category_id ) {
  499. if( !in_array( $category_id, $old_categories ) ) {
  500. $db->query('SELECT MAX(`product_list`) as list_order FROM `#__{vm}_product_category_xref` WHERE `category_id`='.(int)$category_id );
  501. $db->next_record();
  502. $q = "INSERT INTO #__{vm}_product_category_xref ";
  503. $q .= "(category_id,product_id,product_list) ";
  504. $q .= "VALUES ('".(int)$category_id."','". $d["product_id"] . "', ".intval($db->f('max') +1 ) . ")";
  505. $db->setQuery($q); $db->query();
  506. $new_categories[$category_id] = $category_id;
  507. }
  508. else {
  509. unset( $old_categories[$category_id]);
  510. }
  511. }
  512. // The rest of the old categories can be deleted
  513. foreach( $old_categories as $category_id ) {
  514. $q = "DELETE FROM `#__{vm}_product_category_xref` ";
  515. $q .= "WHERE `product_id` = '" . $d["product_id"] . "' ";
  516. $q .= "AND `category_id` = '" . $category_id . "' ";
  517. $db->query($q);
  518. }
  519. }
  520. if( !empty($d["related_products"])) {
  521. /* Insert Pipe separated Related Product IDs */
  522. $related_products = vmGet( $d, "related_products" );
  523. $q = "REPLACE INTO #__{vm}_product_relations (product_id, related_products)";
  524. $q .= " VALUES( '".$d["product_id"]."', '$related_products') ";
  525. $db->query($q);
  526. }
  527. else{
  528. $q = "DELETE FROM #__{vm}_product_relations WHERE product_id='".$d["product_id"]."'";
  529. $db->query($q);
  530. }
  531. // UPDATE THE PRICE, IF EMPTY ADD 0
  532. if(empty($d['product_currency'])) {
  533. $d['product_currency'] = $_SESSION['vendor_currency'];
  534. }
  535. // look if we have a price for this product
  536. $q = "SELECT product_price_id, price_quantity_start, price_quantity_end FROM #__{vm}_product_price ";
  537. $q .= "WHERE shopper_group_id=" . vmRequest::getInt('shopper_group_id');
  538. $q .= ' AND product_id = ' . $d["product_id"];
  539. $db->query($q);
  540. if ($db->next_record()) {
  541. $d["product_price_id"] = $db->f("product_price_id");
  542. require_once ( CLASSPATH. 'ps_product_price.php');
  543. $my_price = new ps_product_price;
  544. if (@$d['product_price'] != '') {
  545. // update prices
  546. $d["price_quantity_start"] = $db->f("price_quantity_start");
  547. $d["price_quantity_end"] = $db->f("price_quantity_end");
  548. $my_price->update($d);
  549. }
  550. else {
  551. // delete the price
  552. $my_price->delete( $d );
  553. }
  554. }
  555. else {
  556. if ( $d['product_price'] != '' ) {
  557. // add the price
  558. $d["price_quantity_start"] = 0;
  559. $d["price_quantity_end"] = "";
  560. require_once ( CLASSPATH. 'ps_product_price.php');
  561. $my_price = new ps_product_price;
  562. $my_price->add($d);
  563. }
  564. }
  565. // Product Type Parameters!
  566. $this->handleParameters( $d );
  567. $vmLogger->info( $VM_LANG->_('VM_PRODUCT_UPDATED',false) );
  568. return true;
  569. }
  570. /**
  571. * Handles adding or updating parameter values for a product an its product types
  572. * @since VirtueMart 1.1.0
  573. * @param array $d
  574. */
  575. function handleParameters( &$d ) {
  576. global $db;
  577. $product_id= intval( $d["product_id"] );
  578. $q = "SELECT `product_type_id` FROM `#__{vm}_product_product_type_xref` WHERE ";
  579. $q .= "`product_id`=$product_id";
  580. $db->query($q);
  581. $dbpt = new ps_DB;
  582. $dbp = new ps_DB;
  583. // For every Product Type
  584. while ($db->next_record()) {
  585. $product_type_id = $db->f("product_type_id");
  586. $q = "SELECT * FROM #__{vm}_product_type_parameter WHERE ";
  587. $q .= "product_type_id='$product_type_id' ";
  588. $q .= "ORDER BY parameter_list_order";
  589. $dbpt->query($q);
  590. $q = "SELECT COUNT(`product_id`) as num_rows FROM `#__{vm}_product_type_$product_type_id` WHERE ";
  591. $q .= "product_id='$product_id'";
  592. $dbp->query($q); $dbp->next_record();
  593. if ( $dbp->f('num_rows') == 0 ) { // Add record if not exist (Items)
  594. $q = "INSERT INTO #__{vm}_product_type_$product_type_id (product_id) ";
  595. $q .= "VALUES ('$product_id')";
  596. $dbp->query($q);
  597. }
  598. // Update record
  599. $q = "UPDATE #__{vm}_product_type_$product_type_id SET ";
  600. $q .= "product_id='$product_id'";
  601. while ($dbpt->next_record()) {
  602. if ($dbpt->f("parameter_type")!="B") { // if it is not breaker
  603. $value=$d["product_type_".$product_type_id."_".$dbpt->f("parameter_name")];
  604. if ($dbpt->f("parameter_type")=="V" && is_array($value)) {
  605. $value = join(';',$value);
  606. }
  607. if ($value=="") {
  608. $value='NULL';
  609. }
  610. else {
  611. $value="'".$dbpt->getEscaped($value)."'";
  612. }
  613. $q .= ',`'.$dbpt->f('parameter_name', false).'`='.$value;
  614. }
  615. }
  616. $q .= ' WHERE product_id = '.$d['product_id'];
  617. $dbp->query($q);
  618. }
  619. }
  620. /**
  621. * Function to delete product(s) $d['product_id'] from the product table
  622. *
  623. * @param array $d The input vars
  624. * @return boolean True, when the product was deleted, false when not
  625. */
  626. function delete(&$d) {
  627. $product_id = $d["product_id"];
  628. if( is_array( $product_id)) {
  629. foreach( $product_id as $product) {
  630. if( !$this->delete_product( $product, $d ))
  631. return false;
  632. }
  633. return true;
  634. }
  635. else {
  636. return $this->delete_product( $product_id, $d );
  637. }
  638. }
  639. /**
  640. * Move a product from one category to another
  641. *
  642. * @param array $d
  643. * @return boolean True on sucess, false on failure
  644. */
  645. function move( &$d ) {
  646. global $db, $vmLogger, $VM_LANG;
  647. if( !is_array( $d['product_id'])) {
  648. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_MOVE_NOTFOUND',false));
  649. return false;
  650. }
  651. if( empty( $d['category_id'])) {
  652. $vmLogger->err( $VM_LANG->_('VM_PRODUCT_MUSTSELECT_ONE_CAT',false));
  653. return false;
  654. }
  655. // Loop though each product
  656. foreach( $d['product_id'] as $product_id ) {
  657. // check if the product is already assigned to the category it should be moved to
  658. $db->query( 'SELECT product_id FROM `#__{vm}_product_category_xref` WHERE `product_id`='.intval($product_id).' AND `category_id`='.intval($d['category_id']));
  659. if( !$db->next_record()) {
  660. // If the product is not yet in this category, move it!
  661. $db->query( 'SELECT MAX(`product_list`) as max FROM `#__{vm}_product_category_xref` WHERE `category_id`='.intval($d['category_id']));
  662. $db->next_record();
  663. $db->query('INSERT INTO `#__{vm}_product_category_xref` VALUES ('.intval($d['category_id']).', '.intval($product_id).', '.intval( $db->f('max') + 1) .') ');
  664. }
  665. $db->query('DELETE FROM `#__{vm}_product_category_xref` WHERE `product_id`='.intval($product_id).' AND `category_id`='.intval($d['old_category_id']));
  666. }
  667. return true;
  668. }
  669. /**
  670. * The function that holds the code for deleting
  671. * one product from the database and all related tables
  672. * plus deleting files related to the product
  673. *
  674. * @param int $product_id
  675. * @param array $d The input vars
  676. * @return boolean True on success, false on error
  677. */
  678. function delete_product( $product_id, &$d ) {
  679. global $vmLogger, $VM_LANG;
  680. $db = new ps_DB;
  681. if (!$this->validate_delete($product_id, $d)) {
  682. return false;
  683. }
  684. /* If is Product */
  685. if ($this->is_product($product_id)) {
  686. /* Delete all items first */
  687. $q = "SELECT product_id FROM #__{vm}_product WHERE product_parent_id='$product_id'";
  688. $db->setQuery($q); $db->query();
  689. while($db->next_record()) {
  690. $d2["product_id"] = $db->f("product_id");
  691. if (!$this->delete($d2)) {
  692. return false;
  693. }
  694. }
  695. /* Delete attributes */
  696. $q = "DELETE FROM #__{vm}_product_attribute_sku WHERE product_id='$product_id' ";
  697. $db->setQuery($q); $db->query();
  698. /* Delete categories xref */
  699. $q = "DELETE FROM #__{vm}_product_category_xref WHERE product_id = '$product_id' ";
  700. $db->setQuery($q); $db->query();
  701. }
  702. /* If is Item */
  703. else {
  704. /* Delete attribute values */
  705. $q = "DELETE FROM #__{vm}_product_attribute WHERE product_id='$product_id'";
  706. $db->setQuery($q); $db->query();
  707. }
  708. /* For both Product and Item */
  709. /* Delete product - manufacturer xref */
  710. $q = "DELETE FROM #__{vm}_product_mf_xref WHERE product_id='$product_id'";
  711. $db->setQuery($q); $db->query();
  712. /* Delete Product - ProductType Relations */
  713. $q = "DELETE FROM `#__{vm}_product_product_type_xref` WHERE `product_id`=$product_id";
  714. $db->setQuery($q); $db->query();
  715. /* Delete product votes */
  716. $q = "DELETE FROM #__{vm}_product_votes WHERE product_id='$product_id'";
  717. $db->setQuery($q); $db->query();
  718. /* Delete product reviews */
  719. $q = "DELETE FROM #__{vm}_product_reviews WHERE product_id='$product_id'";
  720. $db->setQuery($q); $db->query();
  721. /* Delete Image files */
  722. if (!vmImageTools::process_images($d)) {
  723. return false;
  724. }
  725. /* Delete other Files and Images files */
  726. require_once( CLASSPATH.'ps_product_files.php' );
  727. $ps_product_files = new ps_product_files();
  728. $db->query( "SELECT file_id FROM #__{vm}_product_files WHERE file_product_id='$product_id'" );
  729. while($db->next_record()) {
  730. $d["file_id"] = $db->f("file_id");
  731. $ps_product_files->delete( $d );
  732. }
  733. /* Delete Product Relations */
  734. $q = "DELETE FROM #__{vm}_product_relations WHERE product_id = '$product_id'";
  735. $db->setQuery($q); $db->query();
  736. /* Delete Prices */
  737. $q = "DELETE FROM #__{vm}_product_price WHERE product_id = '$product_id'";
  738. $db->setQuery($q); $db->query();
  739. /* Delete entry FROM #__{vm}_product table */
  740. $q = "DELETE FROM #__{vm}_product WHERE product_id = '$product_id'";
  741. $db->setQuery($q); $db->query();
  742. /* If only deleting an item, go to the parent product page after
  743. ** the deletion. This had to be done here because the product id
  744. ** of the item to be deleted had to be passed as product_id */
  745. if (!empty($d["product_parent_id"])) {
  746. $d["product_id"] = $d["product_parent_id"];
  747. $d["product_parent_id"] = "";
  748. }
  749. $vmLogger->info( str_replace('{product_id}',$product_id,$VM_LANG->_('VM_PRODUCT_DELETED',false)) );
  750. return true;
  751. }
  752. /**
  753. * Function to check if the vendor_id of the product
  754. * $d['product_id'] matches the vendor_id associated with the
  755. * user that calls this function
  756. *
  757. * @param array $d
  758. * @return boolean True, when vendor_id matches, false when not
  759. */
  760. function check_vendor($d) {
  761. $ps_vendor_id = $_SESSION["ps_vendor_id"];
  762. $db = new ps_DB;
  763. $q = "SELECT vendor_id FROM #__{vm}_product ";
  764. $q .= "WHERE vendor_id = '$ps_vendor_id' ";
  765. $q .= "AND product_id = '" . $d["product_id"] . "' ";
  766. $db->query($q);
  767. if ($db->next_record()) {
  768. return true;
  769. } else {
  770. return false;
  771. }
  772. }
  773. /**
  774. * Function to create a ps_DB object holding the data of product $d['product_id']
  775. * from the table #__{vm}_product
  776. *
  777. * @param int $product_id
  778. * @return ps_DB DB object holding all data for product $product_id
  779. */
  780. function sql($product_id) {
  781. $db = new ps_DB;
  782. if( !empty( $product_id )) {
  783. $q = 'SELECT * FROM #__{vm}_product WHERE product_id=' . (int)$product_id;
  784. $db->setQuery($q); $db->query();
  785. }
  786. return $db;
  787. }
  788. /**
  789. * Function to create a db object holding the data of all child items of
  790. * product $product_id
  791. *
  792. * @param int $product_id
  793. * @return ps_DB object that holds all items of product $product_id
  794. */
  795. function items_sql($product_id) {
  796. $db = new ps_DB;
  797. if( !empty($product_id) ) {
  798. $q = "SELECT * FROM #__{vm}_product ";
  799. $q .= "WHERE product_parent_id=".(int)$product_id.' ';
  800. $q .= "ORDER BY product_name";
  801. $db->setQuery($q); $db->query();
  802. }
  803. return $db;
  804. }
  805. /**
  806. * Function to check whether a product is a parent product or not
  807. * If is is a child product, it has a non-empty value for "product_parent_id"
  808. *
  809. * @param int $product_id
  810. * @return boolean True when the product is a parent product, false when product is a child item
  811. */
  812. function is_product($product_id) {
  813. $product_parent_id = ps_product::get_field($product_id, 'product_parent_id');
  814. return $product_parent_id == 0;
  815. }
  816. /**
  817. * Function to check whether a product is published
  818. *
  819. *
  820. * @param int $product_id
  821. * @return boolean True when the product is a parent product, false when product is a child item
  822. */
  823. function is_published($product_id, $check_stock=false) {
  824. if( CHECK_STOCK != '1') $check_stock=false;
  825. return ps_product::get_field($product_id, 'product_publish') == 'Y';
  826. }
  827. /**
  828. * Checks if a product is a downloadable product
  829. *
  830. * @param int $product_id
  831. * @return boolean
  832. */
  833. function is_downloadable($product_id) {
  834. if( empty( $GLOBALS['product_info'][$product_id]['is_downloadable'] )) {
  835. $db_check = new ps_DB;
  836. $q_dl = "SELECT attribute_name,attribute_value
  837. FROM #__{vm}_product_attribute WHERE
  838. product_id=".(int)$product_id." AND attribute_name='download'";
  839. $db_check->query($q_dl);
  840. $db_check->next_record();
  841. if( $db_check->num_rows() > 0 ) {
  842. $GLOBALS['product_info'][$product_id]['is_downloadable'] = 'Y';
  843. } else {
  844. $GLOBALS['product_info'][$product_id]['is_downloadable'] = 'N';
  845. }
  846. }
  847. return $GLOBALS['product_info'][$product_id]['is_downloadable'] == 'Y';
  848. }
  849. /**
  850. * Function to create a DB object that holds all information
  851. * from the attribute tables about item $item_id AND/OR product $product_id
  852. *
  853. * @param int $item_id The product_id of the item
  854. * @param int $product_id The product_id of the parent product
  855. * @param string $attribute_name The name of the attribute to filter
  856. * @return ps_DB The db object...
  857. */
  858. function attribute_sql($item_id="",$product_id="",$attribute_name="") {
  859. $db = new ps_DB;
  860. if ($item_id and $product_id) {
  861. $q = "SELECT * FROM #__{vm}_product_attribute,#__{vm}_product_attribute_sku ";
  862. $q .= "WHERE #__{vm}_product_attribute.product_id = '$item_id' ";
  863. $q .= "AND #__{vm}_product_attribute_sku.product_id ='$product_id' ";
  864. if ($attribute_name) {
  865. $q .= "AND #__{vm}_product_attribute.attribute_name = $attribute_name ";
  866. }
  867. $q .= "AND #__{vm}_product_attribute.attribute_name = ";
  868. $q .= "#__{vm}_product_attribute_sku.attribute_name ";
  869. $q .= "ORDER BY attribute_list,#__{vm}_product_attribute.attribute_name";
  870. } elseif ($item_id) {
  871. $q = "SELECT * FROM #__{vm}_product_attribute ";
  872. $q .= "WHERE product_id=$item_id ";
  873. if ($attribute_name) {
  874. $q .= "AND attribute_name = '$attribute_name' ";
  875. }
  876. } elseif ($product_id) {
  877. $q = "SELECT * FROM #__{vm}_product_attribute_sku ";
  878. $q .= "WHERE product_id =".(int)$product_id.' ';
  879. if ($attribute_name) {
  880. $q .= "AND #__{vm}_product_attribute.attribute_name = $attribute_name ";
  881. }
  882. $q .= "ORDER BY attribute_list,attribute_name";
  883. } else {
  884. /* Error: no arguments were provided. */
  885. return 0;
  886. }
  887. $db->setQuery($q); $db->query();
  888. return $db;
  889. }
  890. /**
  891. * Function to return the product ids of all child items of product $pid
  892. *
  893. * @param int $pid The ID of the parent product
  894. * @return array $list
  895. */
  896. function get_child_product_ids($pid) {
  897. $db = new ps_DB;
  898. $q = "SELECT product_id FROM #__{vm}_product ";
  899. $q .= "WHERE product_parent_id='$pid' ";
  900. $db->setQuery($q); $db->query();
  901. $i = 0;
  902. $list = Array();
  903. while($db->next_record()) {
  904. $list[$i] = $db->f("product_id");
  905. $i++;
  906. }
  907. return $list;
  908. }
  909. /**
  910. * Function to quickly check whether a product has child products or not
  911. *
  912. * @param int $pid The id of the product to check
  913. * @return boolean True when the product has childs, false when not
  914. */
  915. function parent_has_children($pid) {
  916. $db = new ps_DB;
  917. if( empty($GLOBALS['product_info'][$pid]["parent_has_children"] )) {
  918. $q = "SELECT COUNT(product_id) as num_rows FROM #__{vm}_product WHERE product_parent_id='$pid' ";
  919. $db->query($q);
  920. $db->next_record();
  921. if( $db->f('num_rows') > 0 ) {
  922. $GLOBALS['product_info'][$pid]["parent_has_children"] = True;
  923. }
  924. else {
  925. $GLOBALS['product_info'][$pid]["parent_has_children"] = False;
  926. }
  927. }
  928. return $GLOBALS['product_info'][$pid]["parent_has_children"];
  929. }
  930. /**
  931. * Function to quickly check whether a product has attributes or not
  932. *
  933. * @param int $pid The id of the product to check
  934. * @return boolean True when the product has attributes, false when not
  935. */
  936. function product_has_attributes($pid, $checkSimpleAttributes=false ) {
  937. if( is_array($pid) || empty($pid)) {
  938. return false;
  939. }
  940. $pid = intval( $pid );
  941. $db = new ps_DB;
  942. if( empty($GLOBALS['product_info'][$pid]["product_has_attributes"] )) {
  943. $db->query( "SELECT `product_id` FROM `#__{vm}_product_attribute_sku` WHERE `product_id`=$pid");
  944. if ($db->next_record()) {
  945. $GLOBALS['product_info'][$pid]["product_has_attributes"] = True;
  946. }
  947. elseif( $checkSimpleAttributes ) {
  948. $db->query( "SELECT `attribute`,`custom_attribute` FROM `#__{vm}_product` WHERE `product_id`=$pid");
  949. $db->next_record();
  950. if( $db->f('attribute') || $db->f('custom_attribute')) {
  951. $GLOBALS['product_info'][$pid]["product_has_attributes"] = True;
  952. }
  953. else {
  954. $GLOBALS['product_info'][$pid]["product_has_attributes"] = False;
  955. }
  956. }
  957. else {
  958. $GLOBALS['product_info'][$pid]["product_has_attributes"] = False;
  959. }
  960. }
  961. return $GLOBALS['product_info'][$pid]["product_has_attributes"];
  962. }
  963. /**
  964. * Get the value of the field $field_name for product $product_id from the product table
  965. *
  966. * @param int $product_id
  967. * @param string $field_name
  968. * @return string The value of the field $field_name for that product
  969. */
  970. function get_field( $product_id, $field_name, $force = false ) {
  971. if( $product_id == 0 ) return '';
  972. $db = new ps_DB;
  973. if( !isset($GLOBALS['product_info'][$product_id][$field_name] ) || $force ) {
  974. $q = 'SELECT product_id, `#__{vm}_product`.* FROM `#__{vm}_product` WHERE `product_id`='.(int)$product_id;
  975. $db->query($q);
  976. if ($db->next_record()) {
  977. $values = get_object_vars( $db->getCurrentRow() );
  978. foreach( $values as $key => $value ) {
  979. $GLOBALS['product_info'][$product_id][$key] = $value;
  980. }
  981. if( !isset( $GLOBALS['product_info'][$product_id][$field_name] ) && !is_null($GLOBALS['product_info'][$product_id][$field_name])) {
  982. $GLOBALS['vmLogger']->debug( 'The Field '.$field_name. ' does not exist in the product table!');
  983. $GLOBALS['product_info'][$product_id][$field_name] = true;
  984. }
  985. }
  986. else {
  987. $GLOBALS['product_info'][$product_id][$field_name] = false;
  988. }
  989. }
  990. return $GLOBALS['product_info'][$product_id][$field_name];
  991. }
  992. /**
  993. * Sets a global value for a fieldname for a specific product
  994. * Is to be used by other scripts to populate a field value for a prodct
  995. * that was already fetched from the database - so it doesn't need to e fetched again
  996. * Can be also used to override a value
  997. *
  998. * @param int $product_id
  999. * @param string $field_name
  1000. * @param mixed $value
  1001. */
  1002. function set_field( $product_id, $field_name, $value ) {
  1003. $GLOBALS['product_info'][$product_id][$field_name] = $value;
  1004. }
  1005. /**
  1006. * This is a very time consuming function.
  1007. * It fetches the category flypage for a specific product id
  1008. *
  1009. * @param int $product_id
  1010. * @return string The flypage value for that product
  1011. */
  1012. function get_flypage($product_id) {
  1013. if( empty( $_SESSION['product_sess'][$product_id]['flypage'] )) {
  1014. $db = new ps_DB;
  1015. $productParentId = (int)$product_id;
  1016. do {
  1017. $q = "SELECT
  1018. `#__{vm}_product`.`product_parent_id` AS product_parent_id,
  1019. `#__{vm}_category`.`category_flypage`
  1020. FROM
  1021. `#__{vm}_product`
  1022. LEFT JOIN `#__{vm}_product_category_xref` ON `#__{vm}_product_category_xref`.`product_id` = `#__{vm}_product`.`product_id`
  1023. LEFT JOIN `#__{vm}_category` ON `#__{vm}_product_category_xref`.`category_id` = `#__{vm}_category`.`category_id`
  1024. WHERE `#__{vm}_product`.`product_id`='$productParentId'
  1025. ";
  1026. $productParentId = $db->f("product_parent_id");
  1027. $db->query($q);
  1028. $db->next_record();
  1029. }
  1030. while( $db->f("product_parent_id") && !$db->f("category_flypage"));
  1031. if ($db->f("category_flypage")) {
  1032. $_SESSION['product_sess'][$product_id]['flypage'] = $db->f("category_flypage");
  1033. } else {
  1034. $_SESSION['product_sess'][$product_id]['flypage'] = FLYPAGE;
  1035. }
  1036. }
  1037. return $_SESSION['product_sess'][$product_id]['flypage'];
  1038. }
  1039. /**
  1040. * Function to get the name of the vendor the product is associated with
  1041. *
  1042. * @param int $product_id
  1043. * @return string The name of the vendor
  1044. */
  1045. function get_vendorname($product_id) {
  1046. $db = new ps_DB;
  1047. $q = "SELECT #__{vm}_vendor.vendor_name FROM #__{vm}_product, #__{vm}_vendor ";
  1048. $q .= "WHERE #__{vm}_product.product_id='$product_id' ";
  1049. $q .= "AND #__{vm}_vendor.vendor_id=#__{vm}_product.vendor_id";
  1050. $db->query($q);
  1051. $db->next_record();
  1052. if ($db->f("vendor_name")) {
  1053. return $db->f("vendor_name");
  1054. }
  1055. else {
  1056. return "";
  1057. }
  1058. }
  1059. /**
  1060. * Function to get the name of a vendor by its id
  1061. * @author pablo
  1062. * @param int $vendor_id
  1063. * @return string The name of the vendor
  1064. */
  1065. function get_vend_idname($vendor_id) {
  1066. $db = new ps_DB;
  1067. $q = "SELECT vendor_name,vendor_id FROM #__{vm}_vendor ";
  1068. $q .= "WHERE vendor_id='$vendor_id'";
  1069. $db->query($q);
  1070. $db->next_record();
  1071. if ($db->f("vendor_name")) {
  1072. return $db->f("vendor_name");
  1073. }
  1074. else {
  1075. return "";
  1076. }
  1077. }
  1078. /**
  1079. * Function to get the vendor_id of a product
  1080. * @author pablo
  1081. * @param int $product_id
  1082. * @return int The vendor id
  1083. */
  1084. function get_vendor_id($product_id) {
  1085. $db = new ps_DB;
  1086. if( empty( $_SESSION['product_sess'][$product_id]['vendor_id'] )) {
  1087. $q = "SELECT vendor_id FROM #__{vm}_product ";
  1088. $q .= "WHERE product_id='$product_id' ";
  1089. $db->query($q);
  1090. $db->next_record();
  1091. if ($db->f("vendor_id")) {
  1092. $_SESSION['product_sess'][$product_id]['vendor_id'] = $db->f("vendor_id");
  1093. }
  1094. else {
  1095. $_SESSION['product_sess'][$product_id]['vendor_id'] = "";
  1096. }
  1097. }
  1098. return $_SESSION['product_sess'][$product_id]['vendor_id'];
  1099. }
  1100. /**
  1101. * Function to get the manufacturer id the product $product_id is assigned to
  1102. * @author soeren
  1103. * @param int $product_id
  1104. * @return int The manufacturer id
  1105. */
  1106. function get_manufacturer_id($product_id) {
  1107. $db = new ps_DB;
  1108. $q = "SELECT manufacturer_id FROM #__{vm}_product_mf_xref ";
  1109. $q .= "WHERE product_id='$product_id' ";
  1110. $db->query($q);
  1111. $db->next_record();
  1112. if ($db->f("manufacturer_id")) {
  1113. return $db->f("manufacturer_id");
  1114. }
  1115. else {
  1116. return false;
  1117. }
  1118. }
  1119. /**
  1120. * Functon to get the name of the manufacturer this product is assigned to
  1121. *
  1122. * @param int $product_id
  1123. * @return string the manufacturer name
  1124. */
  1125. function get_mf_name($product_id) {
  1126. $db = new ps_DB;
  1127. $q = "SELECT mf_name,#__{vm}_manufacturer.manufacturer_id FROM #__{vm}_product_mf_xref,#__{vm}_manufacturer ";
  1128. $q .= "WHERE product_id='$product_id' ";
  1129. $q .= "AND #__{vm}_manufacturer.manufacturer_id=#__{vm}_product_mf_xref.manufacturer_id";
  1130. $db->query($q);
  1131. $db->next_record();
  1132. if ($db->f("mf_name")) {
  1133. return $db->f("mf_name");
  1134. }
  1135. else {
  1136. return "";
  1137. }
  1138. }
  1139. /**
  1140. * This function retrieves the "neighbor" products of a product specified by $product_id
  1141. * Neighbors are the previous and next product in the current list
  1142. *
  1143. * @param int $product_id
  1144. * @return array
  1145. */
  1146. function get_neighbor_products( $product_id ) {
  1147. global $perm, $orderby, $my, $auth, $keyword, $DescOrderBy, $limit, $limitstart, $search_limiter, $search_op,
  1148. $category_id, $manufacturer_id, $vm_mainframe, $vmInputFilter, $product_type_id, $keyword1, $keyword2;
  1149. $limit = 2000;
  1150. $limitstart = 0;
  1151. if( !empty( $_SESSION['last_browse_parameters'])) {
  1152. foreach( $_SESSION['last_browse_parameters'] as $paramName => $paramValue ) {
  1153. $$paramName = $paramValue;
  1154. }
  1155. }
  1156. $db = new ps_DB();
  1157. $db_browse = new ps_DB();
  1158. include( PAGEPATH . 'shop_browse_queries.php' );
  1159. $db->query( $list );
  1160. $neighbors = array('previous'=>'',
  1161. 'next'=>'');
  1162. while( $db->next_record() ) {
  1163. if( $db->f( 'product_id' ) == $product_id ) {
  1164. $previous_row = $db->previousRow();
  1165. $next_row = $db->nextRow();
  1166. if( !empty( $previous_row->product_id )) {
  1167. $neighbors['previous']['product_id'] = $previous_row->product_id;
  1168. $neighbors['previous']['product_name'] = $previous_row->product_name;
  1169. }
  1170. if( !empty( $next_row->product_id )) {
  1171. $neighbors['next']['product_id'] = $next_row->product_id;
  1172. $neighbors['next']['product_name'] = $next_row->product_name;
  1173. }
  1174. }
  1175. }
  1176. return $neighbors;
  1177. }
  1178. /**
  1179. * Prints the img tag for the given product image
  1180. *
  1181. * @param string $image The name of the imahe OR the full URL to the image
  1182. * @param string $args Additional attributes for the img tag
  1183. * @param int $resize
  1184. * (1 = resize the image by using height and width attributes,
  1185. * 0 = do not resize the image)
  1186. * @param string $path_appendix The path to be appended to IMAGEURL / IMAGEPATH
  1187. */
  1188. function show_image($image, $args="", $resize=1, $path_appendix="product") {
  1189. echo $this->image_tag($image, $args, $resize, $path_appendix);
  1190. }
  1191. /**
  1192. * Returns the img tag for the given product image
  1193. *
  1194. * @param string $image The name of the imahe OR the full URL to the image
  1195. * @param string $args Additional attributes for the img tag
  1196. * @param int $resize
  1197. * (1 = resize the image by using height and width attributes,
  1198. * 0 = do not resize the image)
  1199. * @param string $path_appendix The path to be appended to IMAGEURL / IMAGEPATH
  1200. * @return The HTML code of the img tag
  1201. */
  1202. function image_tag($image, $args="", $resize=1, $path_appendix='product', $thumb_width=0, $thumb_height=0 ) {
  1203. global $mosConfig_live_site, $mosConfig_absolute_path;
  1204. require_once( CLASSPATH . 'imageTools.class.php');
  1205. $border="";
  1206. if( strpos( $args, "border=" )===false ) {
  1207. $border = 'border="0"';
  1208. }
  1209. $height = $width = '';
  1210. if ($image != "") {
  1211. // URL
  1212. if( substr( $image, 0, 4) == "http" ) {
  1213. $url = $image;
  1214. }
  1215. // local image file
  1216. else {
  1217. if(PSHOP_IMG_RESIZE_ENABLE == '1' || $resize==1) {
  1218. $url = $mosConfig_live_site."/components/com_virtuemart/show_image_in_imgtag.php?filename=".urlencode($image)."&amp;newxsize=".PSHOP_IMG_WIDTH."&amp;newysize=".PSHOP_IMG_HEIGHT."&amp;fileout=";
  1219. if( !strpos( $args, "height=" )) {
  1220. $arr = @getimagesize( vmImageTools::getresizedfilename( $image, $path_appendix, '', $thumb_width, $thumb_height ) );
  1221. $width = $arr[0]; $height = $arr[1];
  1222. }
  1223. }
  1224. else {
  1225. $url = IMAGEURL.$path_appendix.'/'.$image;
  1226. if( file_exists($image)) {
  1227. $url = str_replace( $mosConfig_absolute_path, $mosConfig_live_site, $image );
  1228. } elseif( file_exists($mosConfig_absolute_path.'/'.$image)) {
  1229. $url = $mosConfig_live_site.'/'.$image;
  1230. }
  1231. if( !strpos( $args, "height=" ) ) {
  1232. $arr = getimagesize( str_replace( IMAGEURL, IMAGEPATH, $url ) );
  1233. $width = $arr[0]; $height = $arr[1];
  1234. }
  1235. if( $resize ) {
  1236. if( $height < $width ) {
  1237. $width = round($width / ($height / PSHOP_IMG_HEIGHT));
  1238. $height = PSHOP_IMG_HEIGHT;
  1239. } else {
  1240. $height = round($height / ($width / PSHOP_IMG_WIDTH ));
  1241. $width = PSHOP_IMG_WIDTH;
  1242. }
  1243. }
  1244. }
  1245. $url = str_replace( basename( $url ), $GLOBALS['VM_LANG']->convert(basename($url)), $url );
  1246. }
  1247. }
  1248. else {
  1249. $url = VM_THEMEURL.'images/'.NO_IMAGE;
  1250. }
  1251. return vmCommonHTML::imageTag( $url, '', '', $height, $width, '', '', $args.' '.$border );
  1252. }
  1253. /**
  1254. * Get the tax rate...
  1255. * @author soeren
  1256. * @return int The tax rate found
  1257. */
  1258. function get_taxrate() {
  1259. global $page;
  1260. $ps_vendor_id = $_SESSION["ps_vendor_id"];
  1261. $auth = $_SESSION['auth'];
  1262. if( !defined('_PSHOP_ADMIN' ) || $page == 'product.product_list') {
  1263. $db = new ps_DB;
  1264. if ($auth["show_price_including_tax"] == 1) {
  1265. require_once( CLASSPATH . 'ps_checkout.php' );
  1266. if (! ps_checkout::tax_based_on_vendor_address ()) {
  1267. if( $auth["user_id"] > 0 ) {
  1268. $q = "SELECT state, country FROM #__{vm}_user_info WHERE user_id='". $auth["user_id"] . "'";
  1269. $db->query($q);
  1270. $db->next_record();
  1271. $state = $db->f("state");
  1272. $country = $db->f("country");
  1273. $q = "SELECT tax_rate FROM #__{vm}_tax_rate WHERE tax_country='$country' ";
  1274. if( !empty($state)) {
  1275. $q .= "AND tax_state='$state'";
  1276. }
  1277. $db->query($q);
  1278. if ($db->next_record()) {
  1279. $_SESSION['taxrate'][$ps_vendor_id] = $db->f("tax_rate");
  1280. }
  1281. else {
  1282. $_SESSION['taxrate'][$ps_vendor_id] = 0;
  1283. }
  1284. }
  1285. else {
  1286. $_SESSION['taxrate'][$ps_vendor_id] = 0;
  1287. }
  1288. }
  1289. else {
  1290. if( empty( $_SESSION['taxrate'][$ps_vendor_id] )) {
  1291. // let's get the store's tax rate
  1292. $q = "SELECT `tax_rate` FROM #__{vm}_vendor, #__{vm}_tax_rate ";
  1293. $q .= "WHERE tax_country=vendor_country AND #__{vm}_vendor.vendor_id=1 ";
  1294. // !! Important !! take the highest available tax rate for the store's country
  1295. $q .= "ORDER BY `tax_rate` DESC";
  1296. $db->query($q);
  1297. if ($db->next_record()) {
  1298. $_SESSION['taxrate'][$ps_vendor_id] = $db->f("tax_rate");
  1299. }

Large files files are truncated, but you can click here to view the full file