API Docs for: WebTemplate API v2.0
Show:

File: /data/www/webtemplate/wtv2/codedoc/wtProduct.php

<?php

/**
 *  WebTemplate Core
 *
 *  @version 2.0
 *  @module WebTemplate Core
 */

/**
 *  The class representing wtType Nodes
 *
 *  @class WTProduct
 *  @extends WTNode
 */
class WTProduct extends WTNode
{


  /**
   *  Get the javascript for displaying product options in the office
   *
   *  @method productOptionJS
   *  @static
   *  @param {Array} attributeInfo
   *  @param {Array} values
   */
  function productOptionJS($attributeInfo, $values) {

//print_r($values);
    $results = Array();
    $q = Array();
    $q["Path"] = "/Products/Options/*";
    $q["Node Type"] = "wtProductOptionSet";
    $q["Results Array"] = &$results;
    $GLOBALS["WT"]->query($q);

    ob_start();
?>
<script language="javascript">
<!--

var g_productOptions = new Array();

function productOption(optionSet, optionName, optionSetID, optionID) {
  this.m_optionSet = optionSet;
  this.m_optionName = optionName;
  this.m_optionSetID = optionSetID;
  this.m_optionID = optionID;
  this.m_pricing = 0;
  this.m_priceValue = 0;
  this.m_stock = 0;
  this.m_freight = 0;
  this.m_freightValue = 0;
  this.m_available = 1;
  this.m_code = '';
}

var g_productOptionSets = new Array();

function productOptionSet(optionSet, optionSetID) {
  this.m_optionSet = optionSet;
  this.m_optionSetID = optionSetID;
}

<?php
  foreach($results as $result) {
?>
g_productOptionSets[g_productOptionSets.length] = new productOptionSet('<?= str_replace("'", "\\'", $result["__name"]) ?>', <?= $result["__guid"] ?>);
<?php
  }

  if($values["Options"] != "") {
    $optionSets = unserialize($values["Options"]);
//print_r($optionSets);
    if(is_array($optionSets)) {
      foreach($optionSets as $optionSetGuid => $optionsArray) {
        $optionSet = $GLOBALS["WT"]->getNode($optionSetGuid);
        if($optionSet) {
          foreach($optionsArray as $optionGuid => $optionData) {
            $option = $GLOBALS["WT"]->getNode($optionGuid);
            if($option) {
              $optionSetName = str_replace("'", "\\'", $optionSet->getName());
              $optionName = str_replace("'", "\\'", $option->getName());
              $pricing = 0;
              $priceValue = $optionData["price"];
              if(strlen($priceValue) > 0) {
                if($priceValue[0] == '+' || $priceValue[0] == '-') {
                  $pricing = 2;
                  $priceValue = substr($priceValue, 1);
                } else if($priceValue == 0) {
                  $pricing = 0;
                } else {
                  $pricing = 1;
                }
              }
              $stock = 0;
              if(WTConfig::get("Orders/Stock/Options Have Stock") == "Yes") {
                $stock = $optionData["stock"];
              }
              if($stock == '') {
                $stock = "0";
              }

              $freight = 0;
              $freightValue = '0';
              if(WTConfig::get("Orders/Options Have Freight") == "Yes") {
                $freightValue = $optionData["freight"];
              }
              if($freightValue == '') {
                $freightValue = '0';
              }
              
              if(strlen($freightValue) > 0) {
                if($freightValue[0] == '+' || $freightValue == '-') {
                  $freight = 2;
                  $freightValue = substr($freightValue, 1);
                } else if($freightValue == 0) {
                  $freight = 0;
                } else {                
                  $freight = 1;
                }                
              }
 


              $available = $optionData["available"];
              $code = $optionData["code"];
              $code = str_replace("'", "\\'", $code);
?>
var index = g_productOptions.length;
g_productOptions[index] = new productOption('<?= $optionSetName ?>', '<?= $optionName ?>', <?= $optionSetGuid ?>, <?= $optionGuid ?>);
g_productOptions[index].m_pricing = <?= $pricing ?>;
g_productOptions[index].m_priceValue = <?= $priceValue ?>;
g_productOptions[index].m_available = <?= $available ?>;
g_productOptions[index].m_stock = <?= $stock ?>;
g_productOptions[index].m_freight = <?= $freight ?>;
g_productOptions[index].m_freightValue = <?= $freightValue ?>;
g_productOptions[index].m_code = '<?= $code ?>';
<?php
            }
          }
        }
      }
    }
  }


  $productOptionArray = explode("|", $values["Options"]);
//  for($i = 0; $i < count($productOptionArray); $i++) {
  if(false) {
    $productOption = trim($productOptionArray[$i]);
    if($productOption != "") {
      $elements = explode("-", $productOption);
      $optionSet = "";
      $node = $GLOBALS["WT"]->getNode($elements[0]);
      $optionSet = str_replace("'", "\\'", $node->getName());
      $node = $GLOBALS["WT"]->getNode($elements[1]);
      $option = str_replace("'", "\\'", $node->getName());
?>
var index = g_productOptions.length;
g_productOptions[index] = new productOption('<?= $optionSet ?>', '<?= $option ?>', <?= $elements[0] ?>, <?= $elements[1] ?>);
g_productOptions[index].m_pricing = <?= $elements[2] ?>;
g_productOptions[index].m_priceValue = <?= $elements[3] ?>;
g_productOptions[index].m_available = <?= $elements[4] ?>;
<?php
    } 
  }
?>
   


function setProductOptions() {
  var value = "";
  for(var i = 0; i < g_productOptions.length; i++) {
    var pricingElement = document.getElementById("option" + i + "pricing");
    var priceValueElement = document.getElementById("option" + i + "value");

//    var freightElement = document.getElementById("option" + i + "freight");
//    var freightValueElement = document.getElementById("option" + i + "freightValue");

    var availableElement = document.getElementById("option" + i + "available");

    g_productOptions[i].m_pricing = pricingElement.value;
    g_productOptions[i].m_priceValue = priceValueElement.value;

//    g_productOptions[i].m_freight = freightElement.value;
//    g_productOptions[i].m_freightValue = freightValueElement.value;

    if(availableElement.checked) {
      g_productOptions[i].m_available = 1;
    } else {
      g_productOptions[i].m_available = 0;
    }

<?php
  if(WTConfig::get("Orders/Options Have Code") == "Yes") {
?>

  var codeElement = document.getElementById("option" + i + "code");
  g_productOptions[i].m_code = codeElement.value;
<?php
  }
?>

<?php
  if(WTConfig::get("Orders/Stock/Options Have Stock") == "Yes") {
?>
  var stockElement = document.getElementById("option" + i + "stock");
  g_productOptions[i].m_stock = stockElement.value;
<?php
  }
?>

<?php
  if(WTConfig::get("Orders/Options Have Freight") == "Yes") {
?>
  var freightElement = document.getElementById("option" + i + "freight");
  g_productOptions[i].m_freight = freightElement.value;
  var freightValueElement = document.getElementById("option" + i + "freightValue");
  g_productOptions[i].m_freightValue = freightValueElement.value;

<?php
  }
?>


    if(value != "") {
      value += ",";
    }

    value += "{";
    value += " optionSetID: " + g_productOptions[i].m_optionSetID + ",";
    value += " optionID: " + g_productOptions[i].m_optionID + ",";
    value += " pricing: " + g_productOptions[i].m_pricing + ",";
    value += " priceValue: " + g_productOptions[i].m_priceValue + ",";
    value += " available: " + g_productOptions[i].m_available + ",";
    value += " stock: " + g_productOptions[i].m_stock + ",";
    value += " freight: " + g_productOptions[i].m_freight + ",";
    value += " freightValue: " + g_productOptions[i].m_freightValue + ",";
    value += " code: '" + g_productOptions[i].m_code + "'";
    value += "}";

/*
    value += g_productOptions[i].m_optionSetID + '-' + g_productOptions[i].m_optionID;
    value += '-' + g_productOptions[i].m_pricing + '-' + g_productOptions[i].m_priceValue;

//    value += '-' + g_productOptions[i].m_freight + '-' + g_productOptions[i].m_freightValue;

    value += '-' + g_productOptions[i].m_available;
    value += "|";
*/

  }

  value = "[" + value + "]";

  var productOptionsElement = document.getElementById("attr<?= $attributeInfo["__guid"] ?>");
  productOptionsElement.value = value;

  if(typeof(outputStockControl) != 'undefined') {
    outputStockControl();
  }


}

function renderProductOptions() {
  var html = '<table style="border-collapse: collapse; border: 1px solid #aaa">';
  html += "<tr>";
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Option Set</td>';
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Option</td>';
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Available</td>';
<?php
  if(WTConfig::get("Orders/Options Have Code") == "Yes") {
?>
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Code</td>';
<?php
  }
  if(WTConfig::get("Orders/Options Have Price") != "No") {
?>
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Price Effect</td>';
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Amount</td>';
<?php
  }

  if(WTConfig::get("Orders/Stock/Options Have Stock") == "Yes") {
?>
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Stock</td>';
<?php
  }
?>

<?php
  if(WTConfig::get("Orders/Options Have Freight") == "Yes") {
?>
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Freight Effect</td>';
  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">Freight Amount</td>';
<?php
  }
?>



  html += '<td style="border:1px solid #aaa; font-weight: bold; padding: 4px" class="attributeHeading">&nbsp;</td>';
  html += "</tr>";
  var i = 0;
  var j = 0;
  if(g_productOptions.length == 0) {
    html += '<tr>';
    html += '<td colspan="8" style="border: 1px solid #aaa; padding: 4px" class="attributeHeading">No Options Defined</td>';
    html += '</tr>';
  }

  for(j = 0; j < g_productOptionSets.length; j++) {
    for(i = 0; i < g_productOptions.length; i++) {
      if(g_productOptions[i].m_optionSetID == g_productOptionSets[j].m_optionSetID) {
      html += '<tr>';
      html += '<td style="border:1px solid #aaa; padding: 4px" class="attributeHeading">' + g_productOptions[i].m_optionSet + '</td>';
      html += '<td style="border:1px solid #aaa; padding: 4px" class="attributeHeading">' + g_productOptions[i].m_optionName;
      <?php if(WTConfig::get("Orders/Options Have Price") == "No") { ?>
        html += '  <input type="hidden" name="option' + i + 'pricing" id="option' + i + 'pricing" value="0">';
	html += '<input type="hidden" name="option' + i + 'value" id="option' + i + 'value" size="3" onchange="setProductOptions()" value="' + g_productOptions[i].m_priceValue + '">';
      
      <?php } ?>
      html += '</td>';

      html += '<td style="border: 1px solid #aaa; padding: 4px; text-align: center">';

      if(g_productOptions[i].m_available == 1) {
        html += '<input type="checkbox" name="option' + i + 'available" id="option' + i + 'available" checked="checked" onchange="setProductOptions()"/>';
      } else {
        html += '<input type="checkbox" name="option' + i + 'available" id="option' + i + 'available" onchange="setProductOptions()"/>';
      }
      html += '</td>';

<?php
  if(WTConfig::get("Orders/Options Have Code") == "Yes") {
?>
      html += '<td style="border:1px solid #aaa; padding: 4px" class="attributeHeading">';
      html += '<input name="option' + i + 'code" id="option' + i + 'code" size="6" onchange="setProductOptions()" value="' + g_productOptions[i].m_code + '">';
      html += '</td>';
<?php
  }
  
  if(WTConfig::get("Orders/Options Have Price") != "No") {
?>

      html += '<td style="border:1px solid #aaa; padding: 4px" class="attributeHeading">';
      html += '  <select name="option' + i + 'pricing" id="option' + i + 'pricing" onchange="setProductOptions()">';
      html += '  <option value="0">No Effect</option>';
      if(g_productOptions[i].m_pricing == 1) {
        html += '  <option value="1" selected="selected">Absolute</option>';
      } else {
        html += '  <option value="1">Absolute</option>';
      }

      if(g_productOptions[i].m_pricing == 2) {
        html += '  <option value="2" selected="selected">Additional</option>';
      } else {
        html += '  <option value="2">Additional</option>';
      }
      html += '  </select>';
      html += '</td>';

      html += '<td style="border:1px solid #aaa; padding: 4px">';
      html += '<input name="option' + i + 'value" id="option' + i + 'value" size="3" onchange="setProductOptions()" value="' + g_productOptions[i].m_priceValue + '">';
      html += '</td>';


<?php
  }

  if(WTConfig::get("Orders/Stock/Options Have Stock") == "Yes") {
?>
      html += '<td style="border:1px solid #aaa; padding: 4px">';
      html += '<input name="option' + i + 'stock" id="option' + i + 'stock" size="3" onchange="setProductOptions()" value="' + g_productOptions[i].m_stock + '">';
      html += '</td>';
<?php
  }
?>


<?php
  if(WTConfig::get("Orders/Options Have Freight") == "Yes") {
?>
      html += '<td style="border:1px solid #aaa; padding: 4px" class="attributeHeading">';
      html += '  <select name="option' + i + 'freight" id="option' + i + 'freight" onchange="setProductOptions()">';
      html += '  <option value="0">No Effect</option>';
      if(g_productOptions[i].m_freight == 1) {
        html += '  <option value="1" selected="selected">Absolute</option>';
      } else {
        html += '  <option value="1">Absolute</option>';
      }

      if(g_productOptions[i].m_freight == 2) {
        html += '  <option value="2" selected="selected">Additional</option>';
      } else {
        html += '  <option value="2">Additional</option>';
      }
      html += '  </select>';
      html += '</td>';

      html += '<td style="border:1px solid #aaa; padding: 4px">';
      html += '<input name="option' + i + 'freightValue" id="option' + i + 'freightValue" size="3" onchange="setProductOptions()" value="' + g_productOptions[i].m_freightValue + '">';
      html += '</td>';

<?php
  }
?>


      html += '<td style="border: 1px solid #aaa; padding: 4px">';
      html += '<input type="button" value="Remove" onclick="removeProductOption(' + i + ')"/>';
      html += '</td>';



      html += "</tr>";
      }
    }
  }
  html += "</table>";
  var productoptionsElement = document.getElementById("productoptionsdiv");
  productoptionsElement.innerHTML = html;
}

function removeProductOption(index) {
  var temp = Array();
  for(var i = 0; i < g_productOptions.length; i++) {
    if(i != index) {
      temp[temp.length] = g_productOptions[i];
    }
  }
  g_productOptions = temp;
  renderProductOptions();
  setProductOptions();
}

function addProductOption() {
  var selectElement = document.getElementById("productoptionselect");
  if(selectElement.value == "") {
    alert("Please select an option");
    return;
  }
  var cmd = 'var newOption = new productOption' + selectElement.value + ";";
  eval(cmd);
  if(newOption.m_optionSet == 'Prices' || newOption.m_optionSet == 'Price') {
    newOption.m_pricing = 1;
    newOption.m_priceValue = newOption.m_optionName;
  }
  for(var i = 0; i < g_productOptions.length; i++) {
    if(g_productOptions[i].m_optionID == newOption.m_optionID) {
      alert("Option already exists");
      return;
    }
  }
  g_productOptions[g_productOptions.length] = newOption;

  //alert(selectElement.value);
//  g_productOptions[g_productOptions.length] = new productOption(optionSet, optionName, optionID);
  renderProductOptions();
  setProductOptions();
}
//-->
</script>

<input type="hidden" name="attr<?= $attributeInfo["__guid"] ?>" id="attr<?= $attributeInfo["__guid"] ?>" value="">
<div id="productoptionsdiv">
</div>

<table>
<tr>
<td class="attributeHeading">Add Option:</td>
<td>
<select id="productoptionselect">
<option value="">Please Select</option>
<?php foreach($results as $result) { ?>
<optgroup label="<?= $result["__name"] ?>">
<?php
  $options = Array();
  $q = Array();
  $q["Path"] = $result["__guid"] . "/*";
  $q["Results Array"] = &$options;
  $GLOBALS["WT"]->query($q);
  foreach($options as $option) {
?>
<option value="('<?= str_replace("'", "\\'", $result["__name"]) ?>', '<?= str_replace("'", "\\'", $option["__name"]) ?>', <?= $result["__guid"] ?>, <?= $option["__guid"] ?>)"><?= $option["__name"] ?></option>
<?php
  }
?>
</optgroup>
<?php } ?>
</select>
</td>
<td>
<input type="button" value="Add" onclick="addProductOption()"/>
</td>
</tr>
</table>

<script language="javascript">
<!--
renderProductOptions();
setProductOptions();
//-->
</script>

<?php
    $content = ob_get_contents();
    ob_end_clean();
    return $content;
  }

  function getPriceRulesFromForm($productGuid)
  {
    $groupCount = 0;
    $ruleCount = 0;

    $parentGuid = $GLOBALS["WT"]->getRequestValue("parentGuid");
    $category = $GLOBALS["WT"]->getNode($parentGuid);
    $priceModelGuid = $category->getAttribute("Price Model ID");

    $priceModel = $GLOBALS["WT"]->getNode($priceModelGuid);
    $priceGroups = $priceModel->getAttribute("Price Groups IDs");
    if($priceGroups == "") {
      $priceGroups = "0";
    } else {
      $priceGroups = "0,$priceGroups";
    }
    $priceGroupArray = explode(",", $priceGroups);
    $groupCount = count($priceGroups);

    $results = Array();
    $q = Array();
    $q["Node Type"] = "Price Rule";
    $q["Path"] = $priceModelGuid . "/*";
    $q["Results Array"] = &$results;
    $GLOBALS["WT"]->query($q);
    $ruleCount = count($results);

    $values = Array();
    foreach($priceGroupArray as $groupGuid) {
      $name = "g" . $groupGuid . "r0";
      $value = $GLOBALS["WT"]->getRequestValue($name);
      $values[$name] = $value;

      $rules = Array();
      foreach($results as $result) {
        $name = "g" . $groupGuid . "r" . $result["__guid"];
        $value = $GLOBALS["WT"]->getRequestValue($name);
        $values[$name] = $value;
      }
    }

    $returnValue = Array("Price Model ID" => $priceModelGuid, "Values" => $values, "Group Count" => $groupCount, "Rule Count" => $ruleCount);
    return serialize($returnValue);
   
  }

  function getPriceRuleHTML($productGuid, $priceModelGuid)
  {
    $values = Array();
    $defaultPrice = 0;
    if($productGuid != 0) {
      $product = $GLOBALS["WT"]->getNode($productGuid);
      $defaultPrice = $product->getAttribute("Price");
      $priceRules = unserialize($product->getAttribute("Price Rules"));
      if(is_array($priceRules) && array_key_exists("Values", $priceRules)) {
        $values = $priceRules["Values"];
      }
      
    }
    $values["g0r0"] = $defaultPrice;
    
    $priceModel = $GLOBALS["WT"]->getNode($priceModelGuid);
    $priceGroups = $priceModel->getAttribute("Price Groups IDs");
    if($priceGroups == "") {
      $priceGroups = "0";
    } else {
      $priceGroups = "0,$priceGroups";
    }
    $priceGroupArray = explode(",", $priceGroups);
    $html = "";
    $results = Array();
    $q = Array();
    $q["Node Type"] = "Price Rule";
    $q["Path"] = $priceModelGuid . "/*";
    $q["Results Array"] = &$results;
    $GLOBALS["WT"]->query($q);
    $html .= '<table cellpadding="0" cellspacing="0" border="1">';
    $html .= '<tr>';
    $html .= '<td>Group</td>';
    $html .= '<td>Default</td>';
    foreach($results as $result) {
      $html .= '<td align="center">';
      $quantity = $result["Quantity"];
      switch($quantity) {
        case 'Less Than':
          $html .= "&lt;" . $result["To"];
          break;
        case 'Greater Or Equal To':
          $html .= $result["From"] . "+";
          break;
        case 'Between':
          $html .= $result["From"] . " - " . $result["To"];
          break;
        case 'Divisible By':
          $html .= "Per " . $result["Value"];
          break;
      }
      $html .= '</td>';
    }
    $html .= '</tr>';

    foreach($priceGroupArray as $groupGuid) {
      $groupName = "Default";
      if($groupGuid != 0) {
        $group = $GLOBALS["WT"]->getNode($groupGuid);
        $groupName = $group->getName();
      }
      $html .= '<tr>';
      $html .= '<td>' . $groupName . '</td>';
      // naming scheme, g = group, r = rule
      $name = "g" . $groupGuid . "r0";
      $value = "";
      if(array_key_exists($name, $values)) {
        $value = $values[$name];
      }
      $html .= '<td><input name="' . $name . '" onkeypress="return wtCheckKeys(event, \'0123456789.\')" size="5" value="' . $value . '"></td>';
      foreach($results as $result) {
        $name = "g" . $groupGuid . "r" . $result["__guid"];
        $value = "";
        if(array_key_exists($name, $values)) {
          $value = $values[$name];
        }
        $html .= '<td><input name="' . $name . '" onkeypress="return wtCheckKeys(event, \'0123456789.\')" size="5" value="' . $value . '"></td>';
      
      }
      $html .= '</tr>';
    }
    $html .= '</table>';

    return $html;
  }

  function getFormAttributeHTML($attributeInfo, $values)
  {
    $attributeName = $attributeInfo["Attribute Name"];

    if($attributeName == "Options") {
      $label = "Options";
      $control = WTProduct::productOptionJS($attributeInfo, $values);
      return WTNode::getFormRowHTML('<label for="attr' . $attributeInfo["__guid"] . '">' . $label . '</label>:', $control, "attr" . $attributeInfo["__guid"] . "row");        
    }

    if($attributeName == "Price Rules") {
      $label = "Prices:";
      $categoryGuid = $GLOBALS["WT"]->getRequestValue("parentGuid");
      $category = $GLOBALS["WT"]->getNode($categoryGuid);
      $priceModel = $category->getAttribute("Price Model ID");
      $productGuid = $GLOBALS["WT"]->getRequestValue("guid");

      $control = WTProduct::getPriceRuleHTML($productGuid, $priceModel) . '<input name="attr' . $attributeInfo["__guid"] . '" type="hidden" value="pricerules"/>';
      return WTNode::getFormRowHTML($label, $control);
    }
    return parent::getFormAttributeHTML($attributeInfo, $values);
   // if($attributeName == "Groups") {
  }

  function parseJSONProductOptions($options) {

    $options = trim($options);
    $options = substr($options, 1);
    $options = substr($options, 0, strlen($options) - 1);

    $options = trim($options);
    $results = Array();

    if(strlen($options) > 0) {
      $options = substr($options, 1);
      $options = substr($options, 0, strlen($options) - 1);
 
      $options = explode("},{", $options);

      foreach($options as $option) {
        $optionValues = explode(",", $option);
        $result = Array();
        foreach($optionValues as $optionValue) {
          $value = explode(':', $optionValue);
          if(count($value) == 2) {
            $result[trim($value[0])] = trim($value[1]);
          }
        }

        $priceEffect = (int)$result["pricing"];
        if($priceEffect == 0) {
          $price = 0;
        } else if($priceEffect == 1) {
          $price = $result["priceValue"];
        } else if($priceEffect == 2) {
          $price = "+" . $result["priceValue"];
        }

        $freightEffect = (int)$result["freight"];
        if($freightEffect == 0) {
          $freight = 0;
        } else if($freightEffect == 1) {
          $freight = $result["freightValue"];
        } else if($freightEffect == 2) {
          $freight = "+" . $result["freightValue"];
        }



        $result["code"] = trim($result["code"]);
        $result["code"] = substr($result["code"], 1);
        $result["code"] = substr($result["code"], 0, strlen($result["code"]) - 1);

        $results[$result["optionSetID"]][$result["optionID"]] = Array("guid" => $result["optionID"], "price" => $price, "available" => $result["available"], "stock" => $result["stock"], "freight" => $freight, "code" => $result["code"]);

     

      }
    }


    return serialize($results);
  }

  function setAttributes($attributes) 
  {
   if(array_key_exists("Categories IDs", $attributes) && $attributes["Categories IDs"] == "") {
    unset($attributes["Categories IDs"]);
   }

    // if this node is a translation, just use parent's set attributes
    $sql = "SELECT __translationOfGuid FROM wtNode WHERE __guid = {$this->m_guid}";
    $query = mysql_query($sql);
    if($row = mysql_fetch_array($query)) {
      if($row[0] != 0) {
        return parent::setAttributes($attributes);
      }
    }

    if(array_key_exists("Price Rules", $attributes)) {
      $attributes["Price Rules"] = WTProduct::getPriceRulesFromForm($this->m_guid);
      $attributes["Price"] = $GLOBALS["WT"]->getRequestValue("g0r0");
      
    }


if(array_key_exists("Product Type ID", $attributes)) {
  if(is_numeric($attributes["Product Type ID"])) {
    $option = $GLOBALS["WT"]->getNode($attributes["Product Type ID"]);
    if($option->getName() == "Image" && array_key_exists("File", $attributes)) { 
      $prevFileID = $this->getAttribute("File");

      $name = $this->getAttribute("Name");
      $fileAttribute = $GLOBALS["WT"]->getNode("/Config/Node Types/Product/File");
      $fileAttributeID = $fileAttribute->m_guid;

      $images = $GLOBALS["WT"]->getNode("/Files/Product Files");
      $file = $images->createChild("wtFile", Array("Field Name" => "attr$fileAttributeID", "Protected" => "Yes" ));
      if($file) {
        $attributes["Image"] = $file->m_guid;
        $attributes["File"] = $file->m_guid;
        if($name == "" && (!array_key_exists("Name", $attributes) || $attributes["Name"] == "")) {
          $attributes["Name"] = $file->getAttribute("Title");
        }

        if($prevFileID) {
          $prevFile = $GLOBALS["WT"]->getNode($prevFileID);
          if($prevFile) {
            $prevFile->deleteNode(true);
          }
        }
      } 
    }
  }

/*    print_r($attributes);
    exit("");
*/

}

    if(array_key_exists("Options", $attributes) && $attributes != "") {
      $result = Array();
      $attributes["Options"] = $this->parseJSONProductOptions($attributes["Options"]);



/*
      $optionArray = array_map("trim", explode("|", $attributes["Options"]));

      foreach($optionArray as $option) {
        if($option != "") {
          $elements = explode("-", $option);
          $optionSet = $GLOBALS["WT"]->getNode($elements[0]);
          $option = $GLOBALS["WT"]->getNode($elements[1]);

          $optionSetGuid = $optionSet->m_guid;
          $optionGuid = $option->m_guid;

          if(!array_key_exists($optionSetGuid, $result)) {
            $result[$optionSetGuid] = Array();
          }
          $priceEffect = (int)$elements[2];
          if($priceEffect == 0) {
            $price = 0;
          } else if($priceEffect == 1) {
            $price = $elements[3];
          } else if($priceEffect == 2) {
            $price = "+" . $elements[3];
          }
          $available = $elements[4];
          $result[$optionSetGuid][$optionGuid] = Array("guid" => $option->m_guid, "price" => $price, "available" => $available);
        }
      }
      $attributes["Options"] = serialize($result);
*/

    }


    $productPages = false;
    if(WTConfig::get("Product Manager/Product Pages") != "No") { 
      $productPages = $GLOBALS["WT"]->getNode("/Pages/Products");
    }
    $oldName = $this->getName(); 


    parent::setAttributes($attributes);


    $newName = $this->getName();


    $categories = explode(",", $this->getAttribute("Categories IDs", true));



    $parentGuids = $this->getParents("Category");
    foreach($parentGuids as $parentGuid) {
      if(!in_array($parentGuid, $categories)) {

        $GLOBALS["WT"]->unlinkNodes($parentGuid, $this->m_guid);
      }
    }


    foreach($categories as $categoryGuid) {
      if(trim($categoryGuid)) {
        $GLOBALS["WT"]->linkNodes($categoryGuid, $this->m_guid);
      }
    }

    $enabled = true;
    if($this->getAttribute("Enabled", true) == "No") {
        $enabled = false;
    }




    if(!$enabled) {
      $this->deleteLinkedPages();
    }

    if($productPages && $enabled) { // && $oldName != $newName) {
      // need to update the names of the product pages
      $results = Array();
      $q = Array(); 
      $q["Node Type"] = "Page";
      $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid;
      if($GLOBALS["WTSITEID"] == 11467) {
        $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid . " AND `Template` = 'Product'";
      }
      $q["Select"] = "wtNode.__guid";
      $q["Results Array"] = &$results;
      $GLOBALS["WT"]->query($q);

 
      if(count($results) == 0) {
        // uh oh, no linked page foro the product
        foreach($categories as $categoryGuid) {
          if(trim($categoryGuid)) {
            $categoryNode = $GLOBALS["WT"]->getNode($categoryGuid);
            if($categoryNode) {
              $this->createLinkedPage($categoryNode);
            }
/*
            $GLOBALS["WT"]->unlinkNodes($categoryGuid, $this->m_guid);
            $GLOBALS["WT"]->linkNodes($categoryGuid, $this->m_guid);
*/
          }
        }

        $GLOBALS["WT"]->query($q);
      }

      $productUri = "";


      foreach($results as $result) {

        $productPage = $GLOBALS["WT"]->getNode($result["__guid"]);
        if($productPage) {
          $productPage->setAttributes(Array("Menu Text" => $newName));
          $productPage->setURI("products");//, "__name");
//          $productPage->setKeywords();

//          exec('php ' . $GLOBALS["WTDIRECTORY"] . 'util/indexPage.php ' . $GLOBALS["WTSITEID"] . ' ' . $productPage->m_guid . '  &>/dev/null & echo \$!');
          if($productUri == "") {
            $productUri = $productPage->getAttribute("URI", true);
            parent::setAttributes(Array("URI" => $productUri));
          }


        }
      }
    }


/*
    $categories = explode(",", $this->getAttribute("Categories IDs", true));

    $parentGuids = $this->getParents("Category");
    foreach($parentGuids as $parentGuid) {
      if(!in_array($parentGuid, $categories)) {
        $GLOBALS["WT"]->unlinkNodes($parentGuid, $this->m_guid);
      }
    }


    foreach($categories as $categoryGuid) {
      if(trim($categoryGuid)) {
        $GLOBALS["WT"]->linkNodes($categoryGuid, $this->m_guid);
      }
    }
*/


/*
    $parentGuids = $this->getParents("Category");
    foreach($parentGuids as $parentGuid) {
      if(!in_array($parentGuid, $categories)) {
        $GLOBALS["WT"]->unlinkNodes($parentGuid, $this->m_guid);
      }
    }
*/

  }

  /**
   *  Get the stock for the product (or one of the products options)
   *
   *  @method getStock
   *  @param {String} [options=""] A string representing the options
   *  @return {int} The stock for the product
   */
  function getStock($options = "") 
  {

    if($options != "") {
      $optionArray = explode("_", $options);
      if(count($optionArray) == 3) {
        $optionSetGuid = (int)$optionArray[1];
        $optionGuid = (int)$optionArray[2];
        $options = unserialize($this->getAttribute("Options"));
        if(array_key_exists($optionSetGuid, $options)) {
          $optionAttributes = $options[$optionSetGuid];
          if(array_key_exists($optionGuid, $optionAttributes)) {
            return $optionAttributes[$optionGuid]["stock"];
          }
        }
      }
    }

    return $this->getAttribute("Stock");
  }

  /**
   *  Alter the stock of the product (or one of its options)
   *
   *  @method alterStock
   *  @param {int} amount The amount to alter the stock by (positive or negative)
   *  @param {String} [options=""]
   */
  function alterStock($amount, $options = "") 
  {
   
    $currentStock = $this->getStock($options);
    $stockWarningLevel = (int)WTConfig::get("Orders/Stock/Stock Warning Level");
    //$currentStock = $this->getAttribute("Stock");
    $currentStock += $amount;
    if($currentStock <= $stockWarningLevel) {
      $address = WTConfig::get("Orders/Stock/Stock Warning To Address");
      $subject = WTConfig::get("Orders/Stock/Stock Warning Subject");
      $message = WTConfig::get("Orders/Stock/Stock Warning Message");
      $attributes = $this->getAttributes();
      $attributes["Stock"] = $currentStock;
      if($options != "") {
        $optionArray = explode("_", $options);
        if(count($optionArray) == 3) {
          $optionGuid = $optionArray[2];
          if($optionGuid) {
            $optionNode = $GLOBALS["WT"]->getNode($optionGuid);
            if($optionNode) {
              $attributes["Name"] = $attributes["Name"] . "(" . $optionNode->m_name . ")";
            }
          }
        }

      }

      foreach($attributes as $k => $v) {
        $subject = str_replace('[' . $k . ']', $v, $subject);
        $message = str_replace('[' . $k . ']', $v, $message);
      }
      $mail = new WTMail();
      $mail->setTo($address);
      $mail->setFrom("bouncer@webtemplate.com.au", "Stock Warning");
      $mail->setContent($subject, $message, true);
      $mail->send();
    }



    if($currentStock >= 0) {

      if($options != "") {

        $optionArray = explode("_", $options);
        if(count($optionArray) == 3) {
          $optionSetGuid = (int)$optionArray[1];
          $optionGuid = (int)$optionArray[2];

          $options = unserialize($this->getAttribute("Options"));
          if(array_key_exists($optionSetGuid, $options)) {
            $optionAttributes = $options[$optionSetGuid];
            if(array_key_exists($optionGuid, $optionAttributes)) {

              $options[$optionSetGuid][$optionGuid]["stock"] = $currentStock;
              $sql = "UPDATE 
                        Product
                      SET
                        Options = '" . mysql_escape_string(serialize($options)) . "'
                      WHERE
                        __guid = " . $this->m_guid;
              mysql_query($sql);
              return true;

            }
          }
        }
      }

      // need to use sql because of permissions
      $sql = "UPDATE
                Product
              SET
                Stock = $currentStock
              WHERE
                __guid = " . $this->m_guid;
      mysql_query($sql);

      return true;
    } else {

      return false;
    }
  }

  function getOptionPriceEffect($optionSetGuid, $optionGuid) {
    return false;
  }


  /**
   *  Get the price of a product
   *
   *  @method getPrice
   *  @param {int} [quantity=1] The quantity to get the price for
   *  @param {int} [quantityOrdered=1] The total quantity ordered
   *  @param {float} The price
   */
  function getPrice($quantity = 1, $quantityOrdered = 1) {
    $priceRules = $this->getAttribute("Price Rules");
    if($priceRules != "") {
      $price = 0;
      $groupGuid = "0";
      $ruleArray = unserialize($priceRules);

      if($priceRules["Rule Count"] == 0) {
        $priceModelID = $ruleArray["Price Model ID"];
        $priceModel = $GLOBALS["WT"]->getNode($priceModelID);
        $results = Array();
        $q["Node Type"] = "Price Rule";
        $q["Path"] = "$priceModelID/*";
        $q["Criteria"] = " Quantity = 'Divisible By' ";
        $q["Order By"] = " Value DESC ";
        $q["Results Array"] = &$results;
        $GLOBALS["WT"]->query($q);
        foreach($results as $result) {
          $value = $result["Value"];
          if($quantityOrdered > $value && $ruleArray["Values"]["g" . $groupGuid . "r" . $result["__guid"]] != "") {
            $thisQuantity = ((int)($quantityOrdered / $value)) * $value;
            $price += $thisQuantity * $ruleArray["Values"]["g" . $groupGuid . "r" . $result["__guid"]];
            $quantityOrdered -= $thisQuantity;
          }
        }
      } else {
        if($groupGuid == "0") {
          $price = $this->getAttribute("Price") * $quantity;
        } else {
          $name = "g" . $groupGuid . "r0";
          if(array_key_exists($name, $ruleArray["Values"])) {
            $price = $ruleArray["Values"][$name] * $quantity;
          } else {
            $price = $this->getAttribute("Price") * $quantity;
          }
        }
      }             
    } else {
      $price = $this->getAttribute("Price") * $quantity;    
    }
    return $price;
  }

  /**
   *  Get the options for the product as an array
   *
   *  @method getOptions
   *  @return {Array} The options for the product
   */
  function getOptions() {   
    $options = $this->getAttribute("Options");
    if($options) {
      return unserialize($options);
    } else {
      return Array();
    }

/*
    $result = Array();
    if($options != "") {
      $optionArray = array_map("trim", explode("|", $options));
      foreach($optionArray as $option) {
        if($option != "") {
          $elements = explode("-", $option);
          if($elements[4] == 1) {
            $optionSet = $GLOBALS["WT"]->getNode($elements[0]);
          
            $option = $GLOBALS["WT"]->getNode($elements[1]);
            if(!array_key_exists($optionSet->getName(), $result)) {
              $result[$optionSet->getName()] = Array("guid" => $optionSet->m_guid, "options" => Array());
            }
            $price = $elements[3];
            $result[$optionSet->getName()]["options"][$option->getName()] = Array("guid" => $option->m_guid, "price" => $price);
          }
        }
      }      
    }
    
    return $result;*/

  }


  function createLinkedPage($parentNode) {
    $categoryPage = $parentNode->getLinkedPage();
    if($categoryPage) {

      // make sure the page doesn't already exist
      $q = Array();
      $q["Node Type"] = "Page";
      $q["Path"] = $categoryPage->m_guid . "/*";
      $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid;
      $q["Select"] = "COUNT(*)";
      $count = $GLOBALS["WT"]->query($q, "singleValueCallback");
      if($count > 0) {
        return;
      }

      $productPage = $categoryPage->createChild("Page", Array("Menu Text" => $this->getName(), "Title" => $productName, "Template" => "Product", "Linked Content ID" => $this->m_nodeIsHolderForGuid));
      $productPage->setURI("products", "__name");
      $productHolder = $productPage->createChild("wtNode", Array("Node Name" => "Product"));
      $GLOBALS["WT"]->linkNodes($productHolder, $this);
      $this->setAttributes(Array("URI" => $productPage->getAttribute("URI", true)));
    }
  }


  function deleteLinkedPages() {
    $results = Array();
    $q = Array();
    $q["Node Type"] = "Page";
    $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid;
    $q["Select"] = "wtNode.__guid";
    $q["Results Array"] = &$results;
    $GLOBALS["WT"]->query($q);
    foreach($results as $result) {
      $productPage = $GLOBALS["WT"]->getNode($result["__guid"]);
      $productPage->deleteNode();
    }
  }

  function deleteNode($forceDelete = false) 
  {

    if($this->m_guid == $this->m_nodeIsHolderForGuid) {
      $results = Array();
      $q = Array();
      $q["Node Type"] = "Page";
      $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid;
      $q["Select"] = "wtNode.__guid";
      $q["Results Array"] = &$results;
      $GLOBALS["WT"]->query($q);
      foreach($results as $result) {
        $productPage = $GLOBALS["WT"]->getNode($result["__guid"]);
        $productPage->deleteNode();
      }
    }

    $fileID = $this->getAttribute("File");
    parent::deleteNode($forceDelete);

    if($fileID) {
      $file = $GLOBALS["WT"]->getNode($fileID);
      $file->deleteNode(true);
    }



  }

  function linkedToParent($parentNode) {
    $productPages = false;
    if(WTConfig::get("Product Manager/Product Pages") != "No") {
      $productPages = $GLOBALS["WT"]->getNode("/Pages/Products");
    }



    if($productPages) {
      if($parentNode->getType() == "Category") {

        $this->createLinkedPage($parentNode);


/*
        $categoryPage = $parentNode->getLinkedPage();
        if($categoryPage) {
          // make sure the page doesn't already exist
          $q = Array();
          $q["Node Type"] = "Page";
          $q["Path"] = $categoryPage->m_guid . "/*";
          $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid;
          $q["Select"] = "COUNT(*)";
          $count = $GLOBALS["WT"]->query($q, "singleValueCallback");
          if($count > 0) {
            return;
          }

          $productPage = $categoryPage->createChild("Page", Array("Menu Text" => $this->getName(), "Title" => $productName, "Template" => "Product", "Linked Content ID" => $this->m_nodeIsHolderForGuid));
          $productPage->setURI("products", "__name");
          $productHolder = $productPage->createChild("wtNode", Array("Node Name" => "Product"));
          $GLOBALS["WT"]->linkNodes($productHolder, $this);
          $this->setAttributes(Array("URI" => $productPage->getAttribute("URI", true)));
                                                   
        } else {

        }
*/

/*
        $productName = $this->getAttribute("Name");

        $categoryPage = $GLOBALS["WT"]->getNode("/Pages" . $parentNode->getPath());
        $productPage = $categoryPage->createChild("Page", Array("Menu Text" => $this->getName(), "Title" => $productName, "Template" => "Product"));
        $productPage->setURI("products", "__name");
        $productHolder = $productPage->createChild("wtNode", Array("Node Name" => "Product"));
        $GLOBALS["WT"]->linkNodes($productHolder, $this);
        $this->setAttributes(Array("URI" => $productPage->getAttribute("URI")));
*/

      }
    }


  }

  function unlinkedFromParent($parentNode) {

    $productPages = false;
    if(WTConfig::get("Product Manager/Product Pages") != "No") {
      $productPages = $GLOBALS["WT"]->getNode("/Pages/Products");
    }
    if($productPages) {
      if($parentNode->getType() == "Category") {
        $categoryPage = $parentNode->getLinkedPage();
        if($categoryPage) {
          $q = Array();
          $results = Array();
          $q["Node Type"] = "Page";
          $q["Criteria"] = "`Linked Content ID` = " . $this->m_nodeIsHolderForGuid;
          $q["Path"] = $categoryPage->m_guid . "/*";
          $q["Select"] = "wtNode.__guid";
          $q["Results Array"] = &$results;
          $GLOBALS["WT"]->query($q);
          foreach($results as $result) {
            $node = $GLOBALS["WT"]->getNode($result["__guid"]);
            if($node) {
              $node->deleteNode();
            }
          }
          
        }
 

/*
        $productName = $this->getName();
        $productPage = $GLOBALS["WT"]->getNode("/Pages" . $parentNode->getPath() . "/$productName");
        if($productPage) {
          $productPage->deleteNode();
        }
*/
      }
    }
  }
}



?>