err( "You must enter a name for the category."); $valid = False; } /** Image Upload Validation **/ // do we have an image URL or an image File Upload? if (!empty( $d['category_thumb_image_url'] )) { // Image URL if (substr( $d['category_thumb_image_url'], 0, 4) != "http") { $vmLogger->err( "Image URL must begin with http." ); $valid = false; } $d["category_thumb_image"] = $d['category_thumb_image_url']; } else { // File Upload if (!validate_image( $d, "category_thumb_image", "category")) { $valid = false; } } if (!empty( $d['category_full_image_url'] )) { // Image URL if (substr( $d['category_full_image_url'], 0, 4) != "http") { $vmLogger->err( "Image URL must begin with http." ); return false; } $d["category_full_image"] = $d['category_full_image_url']; } else { // File Upload if (!validate_image( $d, "category_full_image", "category")) { $valid = false; } } return $valid; } /** * Validates all product category fields and uploaded image files * on category update. * * @param array $d The input vars * @return boolean True when validation successful, false when not */ function validate_update(&$d) { global $vmLogger; $valid = true; if (!$d["category_name"]) { $vmLogger->err( "You must enter a name for the category." ); $valid = False; } elseif ($d["category_id"] == $d["category_parent_id"]) { $vmLogger->err( "Category parent cannot be same category." ); $valid = False; } $db =& new ps_DB; $q = "SELECT category_thumb_image,category_full_image FROM #__{vm}_category WHERE category_id='". $d["category_id"] . "'"; $db->query( $q ); $db->next_record(); /** Image Upload Validation **/ // do we have an image URL or an image File Upload? if (!empty( $d['category_thumb_image_url'] )) { // Image URL if (substr( $d['category_thumb_image_url'], 0, 4) != "http") { $vmLogger->err( "An Image URL must begin with 'http'." ); $valid = false; } // if we have an uploaded image file, prepare this one for deleting. if( $db->f("category_thumb_image") && substr( $db->f("category_thumb_image"), 0, 4) != "http") { $_REQUEST["category_thumb_image_curr"] = $db->f("product_thumb_image"); $d["category_thumb_image_action"] = "delete"; if (!validate_image( $d, "product_thumb_image", "category")) { return false; } } $d["category_thumb_image"] = $d['category_thumb_image_url']; } else { // File Upload if (!validate_image( $d, "category_thumb_image", "category")) { $valid = false; } } if (!empty( $d['category_full_image_url'] )) { // Image URL if (substr( $d['category_full_image_url'], 0, 4) != "http") { $vmLogger->err( "Image URL must begin with 'http'." ); return false; } // if we have an uploaded image file, prepare this one for deleting. if( $db->f("category_full_image") && substr( $db->f("category_thumb_image"), 0, 4) != "http") { $_REQUEST["category_full_image_curr"] = $db->f("category_full_image"); $d["category_full_image_action"] = "delete"; if (!validate_image( $d, "category_full_image", "category")) { return false; } } $d["category_full_image"] = $d['category_full_image_url']; } else { // File Upload if (!validate_image( $d, "category_full_image", "category")) { $valid = false; } } return $valid; } /** * Validates all product category fields and uploaded image files * on category deletion. * * @param mixed $category_id The category_id (or IDs when it's an array) * @param array $d The input vars * @return boolean True when validation successful, false when not */ function validate_delete( $category_id, &$d) { global $vmLogger; $db = new ps_DB; if (empty( $category_id )) { $vmLogger->err( "Please select a category to delete." ); return False; } // Check for children $q = "SELECT * FROM #__{vm}_category_xref where category_parent_id='$category_id'"; $db->setQuery($q); $db->query(); if ($db->next_record()) { $vmLogger->err( "This category has children - please delete those children first."); return False; } $q = "SELECT category_thumb_image,category_full_image FROM #__{vm}_category WHERE category_id='$category_id'"; $db->query( $q ); $db->next_record(); /* Prepare category_thumb_image for Deleting */ if( !stristr( $db->f("category_thumb_image"), "http") ) { $_REQUEST["category_thumb_image_curr"] = $db->f("category_thumb_image"); $d["category_thumb_image_action"] = "delete"; if (!validate_image($d,"category_thumb_image","category")) { $vmLogger->err( "Failed deleting Category Images!" ); return false; } } /* Prepare product_full_image for Deleting */ if( !stristr( $db->f("category_full_image"), "http") ) { $_REQUEST["category_full_image_curr"] = $db->f("category_full_image"); $d["category_full_image_action"] = "delete"; if (!validate_image($d,"category_full_image","category")) { return false; } } return True; } /** * Creates a new category record and a category_xref record * with the appropriate parent and child ids * @author pablo * @author soeren * * @param array $d * @return mixed - int category_id on success, false on error */ function add( &$d ) { global $vmLogger; $ps_vendor_id = $_SESSION["ps_vendor_id"]; $db = new ps_DB; $timestamp = time(); if ($this->validate_add($d)) { if (!process_images($d)) { return false; } while(list($key,$value)= each($d)) { if (!is_array($value)) $d[$key] = addslashes($value); } // Let's find out the last category in // the level of the new category $q = "SELECT MAX(list_order) AS list_order FROM #__{vm}_category_xref,#__{vm}_category "; $q .= "WHERE category_parent_id='".$d["parent_category_id"]."' "; $q .= "AND category_child_id=category_id "; $db->query( $q ); $db->next_record(); $list_order = intval($db->f("list_order"))+1; if (empty($d["category_publish"])) { $d["category_publish"] = "N"; } $q = "INSERT into #__{vm}_category (vendor_id, category_name, "; $q .= "category_publish, category_description, category_browsepage, products_per_row, "; $q .= "category_flypage, category_thumb_image, category_full_image, cdate, mdate, list_order) "; $q .= "VALUES ('$ps_vendor_id','"; $q .= $d["category_name"] . "','"; if ($d["category_publish"] != "Y") { $d["category_publish"] = "N"; } $q .= $d["category_publish"] . "','"; $q .= $d["category_description"] . "','"; $q .= $d["category_browsepage"] . "','"; $q .= $d["products_per_row"] . "','"; $q .= $d["category_flypage"] . "','"; $q .= $d["category_thumb_image"] . "','"; $q .= $d["category_full_image"] . "','"; $q .= $timestamp . "','"; $q .= $timestamp . "', '"; $q .= $list_order . "')"; $db->setQuery($q); $db->query(); $category_id = $db->last_insert_id(); $q = "INSERT into #__{vm}_category_xref "; $q .= "(category_parent_id, category_child_id) "; $q .= "VALUES ('"; $q .= $d["parent_category_id"] . "','"; $q .= $category_id . "')"; $db->setQuery($q); $db->query(); $vmLogger->info( "Successfully added new category: ".$d['category_name'].'.'); return $category_id; } else { return False; } } /** * Updates a category record and its category_xref record * * @author pablo * @author soeren * * @param array $d * @return boolean true on success, false on error */ function update(&$d) { global $vmLogger; $ps_vendor_id = $_SESSION["ps_vendor_id"]; $db = new ps_DB; $timestamp = time(); foreach ($d as $key => $value) { if (!is_array($value)) $d[$key] = addslashes($value); } if ($this->validate_update($d)) { if (!process_images($d)) { return false; } $q = "UPDATE #__{vm}_category SET "; $q .= "category_name='" . $d["category_name"]; if (!isset($d["category_publish"])) { $d["category_publish"] = "N"; } $q .= "',category_publish='" . $d["category_publish"]; $q .= "',category_description='" . $d["category_description"]; $q .= "',category_browsepage='" . $d["category_browsepage"]; $q .= "',products_per_row='" . $d["products_per_row"]; $q .= "',category_flypage='" . $d["category_flypage"]; $q .= "',category_thumb_image='" . $d["category_thumb_image"]; $q .= "',category_full_image='" . $d["category_full_image"]; $q .= "', mdate='$timestamp"; $q .= "', list_order='" . $d["list_order"]."'"; $q .= " WHERE category_id='" . $d["category_id"] . "' "; $q .= "AND vendor_id='$ps_vendor_id' "; $db->setQuery($q); $db->query(); /* ** update #__{vm}_category x-reference table with parent-child relationship */ $q = "UPDATE #__{vm}_category_xref SET "; $q .= "category_parent_id='" . $d["category_parent_id"]; $q .= "' WHERE category_child_id='" . $d["category_id"] . "'"; $db->setQuery($q); $db->query(); /* Re-Order the category table IF the list_order has been changed */ if( intval($d['list_order']) != intval($d['currentpos'])) { $dbu = new ps_DB; /* Moved UP in the list order */ if( intval($d['list_order']) < intval($d['currentpos']) ) { $q = "SELECT category_id FROM #__{vm}_category_xref,#__{vm}_category "; $q .= "WHERE category_parent_id='".$d["category_parent_id"]."' "; $q .= "AND category_child_id=category_id "; $q .= "AND category_id <> '" . $d["category_id"] . "' "; $q .= "AND list_order >= '" . intval($d["list_order"]) . "'"; $db->query( $q ); while( $db->next_record() ) { $dbu->query("UPDATE #__{vm}_category SET list_order=list_order+1 WHERE category_id='".$db->f("category_id")."'"); } } /* Moved DOWN in the list order */ else { $q = "SELECT category_id FROM #__{vm}_category_xref,#__{vm}_category "; $q .= "WHERE category_parent_id='".$d["category_parent_id"]."' "; $q .= "AND category_child_id=category_id "; $q .= "AND category_id <> '" . $d["category_id"] . "' "; $q .= "AND list_order > '" . intval($d["currentpos"]) . "'"; $q .= "AND list_order <= '" . intval($d["list_order"]) . "'"; $db->query( $q ); while( $db->next_record() ) { $dbu->query("UPDATE #__{vm}_category SET list_order=list_order-1 WHERE category_id='".$db->f("category_id")."'"); } } } /* END Re-Ordering */ // Problem: When the parent id has changed, the category is // in a new level. We now need to change the list order value // of the category to the value: recent MAXIMUM + 1 if( $d["category_parent_id"] != $d["current_parent_id"] ) { // Let's find out the last category in // the new level of the category $q = "SELECT MAX(list_order) AS list_order FROM #__{vm}_category_xref,#__{vm}_category "; $q .= "WHERE category_parent_id='".$d["category_parent_id"]."' "; $q .= "AND category_child_id=category_id "; $q .= "AND category_id <> '".$d["category_id"]."'"; $db->query( $q ); $db->next_record(); $q = "UPDATE #__{vm}_category SET list_order=".$db->f("list_order")."+1 WHERE category_id='".$d["category_id"]."'"; $db->query( $q ); } $vmLogger->info( "Successfully updated category: ".$d['category_name'].'.' ); return True; } else { return False; } } /** * Controller for Deleting Records. * @param $d Holds the category_id(s) of the category(/ies) to be deleted */ function delete( &$d ) { $record_id = $d["category_id"]; if( is_array( $record_id)) { foreach( $record_id as $record) { if( !$this->delete_record( $record, $d )) return false; } return true; } else { return $this->delete_record( $record_id, $d ); } } /** * Deletes one Record. */ function delete_record( $record_id, &$d ) { global $ps_product, $db, $vmLogger; if (!$this->validate_delete($record_id, $d)) { return False; } // Delete all products from that category // We must filter out those products that are in more than one category! // Case 1: Products are assigned to more than on category // so let's only delete the __{vm}_product_category_xref entry $q = "CREATE TEMPORARY TABLE IF NOT EXISTS `#__tmp_prod` AS (SELECT * FROM `#__{vm}_product_category_xref` WHERE `category_id`='$record_id');"; $db->query( $q ); $q = "SELECT #__{vm}_product_category_xref.product_id FROM `#__{vm}_product_category_xref`, `#__tmp_prod` WHERE #__{vm}_product_category_xref.product_id=#__tmp_prod.product_id AND #__{vm}_product_category_xref.category_id!='$record_id';"; $db->query( $q ); if( $db->num_rows() > 0 ) { $i = 0; $q = "DELETE FROM #__{vm}_product_category_xref WHERE product_id IN ("; while( $db->next_record() ) { $q .= "'".$db->f("product_id")."'"; if( $i++ < $db->num_rows()-1 ) $q .= ","; } $q .= ") AND category_id='$record_id'"; $db->query( $q ); } else { // Case 2: Products are assigned to this category only $q = "SELECT product_id FROM `#__{vm}_product_category_xref` WHERE `category_id`='$record_id';"; $db->query ( $q ); $d['product_id'] = Array(); while( $db->next_record() ) { $d['product_id'][] = $db->f("product_id"); } $ps_product->delete( $d ); } $q = "DELETE FROM #__{vm}_category WHERE category_id='$record_id'"; $db->setQuery($q); $db->query(); $q = "DELETE FROM #__{vm}_category_xref WHERE category_child_id='$record_id'"; $db->setQuery($q); $db->query(); /* Delete Image files */ if (!process_images($d)) { return false; } $vmLogger->info( "Successfully deleted category ID: $record_id." ); return True; } /** * This function is repsonsible for returning an array containing category information * @param boolean Show only published products? * @param string the keyword to filter categories */ function getCategoryTreeArray( $only_published=true, $keyword = "" ) { $db = new ps_DB; if( empty( $GLOBALS['category_info']['category_tree'])) { // Get only published categories $query = "SELECT category_id, category_description, category_name,category_child_id as cid, category_parent_id as pid,list_order, category_publish FROM #__{vm}_category, #__{vm}_category_xref WHERE "; if( $only_published ) { $query .= "#__{vm}_category.category_publish='Y' AND "; } $query .= "#__{vm}_category.category_id=#__{vm}_category_xref.category_child_id "; if( !empty( $keyword )) { $query .= "AND ( category_name LIKE '%$keyword%' "; $query .= "OR category_description LIKE '%$keyword%' "; $query .= ") "; } $query .= "ORDER BY #__{vm}_category.list_order ASC, #__{vm}_category.category_name ASC"; // initialise the query in the $database connector // this translates the '#__' prefix into the real database prefix $db->query( $query ); $categories = Array(); // Transfer the Result into a searchable Array while( $db->next_record() ) { $categories[$db->f("cid")]["category_child_id"] = $db->f("cid"); $categories[$db->f("cid")]["category_parent_id"] = $db->f("pid"); $categories[$db->f("cid")]["category_name"] = $db->f("category_name"); $categories[$db->f("cid")]["category_description"] = $db->f("category_description"); $categories[$db->f("cid")]["list_order"] = $db->f("list_order"); $categories[$db->f("cid")]["category_publish"] = $db->f("category_publish"); } $GLOBALS['category_info']['category_tree'] = $categories; return $GLOBALS['category_info']['category_tree']; } else { return $GLOBALS['category_info']['category_tree']; } } /** * This function is used for the frontend to display a * complete link list of top-level categories * * @param int $category_id The category to be highlighted * @param string $links_css_class The css class that marks mainlevel links * @param string $list_css_class (deprecated) * @param string $highlighted_style The css styles that format the hightlighted category * @return string HTML code with the link list */ function get_category_tree( $category_id=0, $links_css_class="mainlevel", $list_css_class="mm123", $highlighted_style="font-style:italic;" ) { global $sess; $categories = ps_product_category::getCategoryTreeArray(); // Copy the Array into an Array with auto_incrementing Indexes $key = array_keys($categories); $size = sizeOf($key); $category_tmp = Array(); for ($i=0; $i<$size; $i++) $category_tmp[$i] = &$categories[$key[$i]]; $html = ""; /** FIRST STEP * Order the Category Array and build a Tree of it **/ $nrows = count( $category_tmp ); $id_list = array(); $row_list = array(); $depth_list = array(); for($n = 0 ; $n < $nrows ; $n++) if($category_tmp[$n]["category_parent_id"] == 0) { array_push($id_list,$category_tmp[$n]["category_child_id"]); array_push($row_list,$n); array_push($depth_list,0); } $loop_count = 0; while(count($id_list) < $nrows) { if( $loop_count > $nrows ) break; $id_temp = array(); $row_temp = array(); $depth_temp = array(); for($i = 0 ; $i < count($id_list) ; $i++) { $id = $id_list[$i]; $row = $row_list[$i]; $depth = $depth_list[$i]; array_push($id_temp,$id); array_push($row_temp,$row); array_push($depth_temp,$depth); for($j = 0 ; $j < $nrows ; $j++) if(($category_tmp[$j]["category_parent_id"] == $id) && (array_search($category_tmp[$j]["category_child_id"],$id_list) == NULL)) { array_push($id_temp,$category_tmp[$j]["category_child_id"]); array_push($row_temp,$j); array_push($depth_temp,$depth + 1); } if (array_key_exists($j, $category_tmp)) { if( empty( $categories[@$category_tmp[$j]["category_parent_id"]] )) { array_push($id_temp,""); array_push($row_temp,""); array_push($depth_temp,""); } } } $id_list = $id_temp; $row_list = $row_temp; $depth_list = $depth_temp; $loop_count++; } /** SECOND STEP * Find out if we have subcategories to display **/ $allowed_subcategories = Array(); if( !empty( $categories[$category_id]["category_parent_id"] ) ) { // Find the Root Category of this category $root = $categories[$category_id]; $allowed_subcategories[] = $categories[$category_id]["category_parent_id"]; // Loop through the Tree up to the root while( !empty( $root["category_parent_id"] )) { $allowed_subcategories[] = $categories[$root["category_child_id"]]["category_child_id"]; $root = $categories[$root["category_parent_id"]]; } } // Fix the empty Array Fields if( $nrows < count( $row_list ) ) { $nrows = count( $row_list ); } // Now show the categories for($n = 0 ; $n < $nrows ; $n++) { if( !isset( $row_list[$n] ) || !isset( $category_tmp[$row_list[$n]]["category_child_id"] ) ) continue; if( $category_id == $category_tmp[$row_list[$n]]["category_child_id"] ) $style = $highlighted_style; else $style = ""; $allowed = false; if( $depth_list[$n] > 0 ) { // Subcategory! if( isset( $root ) && in_array( $category_tmp[$row_list[$n]]["category_child_id"], $allowed_subcategories ) || $category_tmp[$row_list[$n]]["category_parent_id"] == $category_id || $category_tmp[$row_list[$n]]["category_parent_id"] == @$categories[$category_id]["category_parent_id"]) { $allowed = true; } } else $allowed = true; $append = ""; if( $allowed ) { if( $style == $highlighted_style ) { $append = 'id="active_menu"'; } if( $depth_list[$n] > 0 ) $css_class = "sublevel"; else $css_class = $links_css_class; $catname = shopMakeHtmlSafe( $category_tmp[$row_list[$n]]["category_name"] ); $html .= ' ' . str_repeat(" ",$depth_list[$n]) . $catname . ps_product_category::products_in_category( $category_tmp[$row_list[$n]]["category_child_id"] ) .''; } } return $html; } /** * Function to print a table containing all categories sorted and structured * It goes through the category table and establishes * the category tree based on the parent-child relationships * defnied in the category_xref table. * This is VERY recursive... * @deprecated * * @param unknown_type $class * @param unknown_type $category_id * @param unknown_type $level */ function traverse_tree_down($class="",$category_id="0", $level="0") { static $ibg = 0; global $sess, $mosConfig_live_site, $VM_LANG; $ps_vendor_id = $_SESSION["ps_vendor_id"]; $db = new ps_DB; $class = "maintext"; $level++; $q = "SELECT * FROM #__{vm}_category,#__{vm}_category_xref "; $q .= "WHERE #__{vm}_category_xref.category_parent_id='"; $q .= $category_id . "' AND "; $q .= "#__{vm}_category.category_id=#__{vm}_category_xref.category_child_id "; $q .= "AND #__{vm}_category.vendor_id='$ps_vendor_id' "; $q .= "ORDER BY list_order asc "; $db->setQuery($q); $db->query(); while ($db->next_record()) { $product_count = $this->product_count($db->f("category_child_id")); if ($level % 2) $bgcolor=SEARCH_COLOR_1; else $bgcolor=SEARCH_COLOR_2; $ibg++; echo "
f("category_id")) .'">'; if ( $db->f("category_thumb_image") ) { $html.= $ps_product->image_tag( $db->f("category_thumb_image"), "alt=\"".$db->f("category_name")."\"", 0, "category"); $html.= " "; } $html.= $db->f("category_name"); $html.= ps_product_category::products_in_category( $db->f("category_id") ); $html.= " \n"; $html .= " | \n";
if ($iCol == $categories_per_row) {
$html.= "