ruạṛ
<?PHP /** * category object * may contain more category objects and product objects */ class category { /** * define variables matched to to database fields * may not have identical names, see $this->load_from_data for conversions */ var $cat_id , $parent_id , $name , $path , $title , $keywords , $description , $content , $num_products , $active , $menu , $order_id , $position , $visited ; /** * subcategory/product containers * @var array $images * @var array $subcats child categories * @var array $products products in this category * @var array $all_products products in this category plus subcategories */ var $images = array(); var $subcats = array(); var $products = array(); var $all_products = array(); var $products_loaded = false; /** * object construction function * @param int $id unique database record id */ function __construct($id=0) { /* * set minimum visibility */ $this->cat_id = 0; $this->active = 0; /** * if no id supplied simply prepare category to be populated from dataset eg in creation script */ if(!$id) { return; } /** * else get category data * assumes database connection already established at global level * @var resource $category mysql dataset */ $category = mysql_query("select * from categories where cat_id = '$id' "); if($category && mysql_num_rows($category)>0) { $this->load_from_data(mysql_fetch_assoc($category)); mysql_free_result($category); // clean up } return; } /** * populate object - can be done on init or manually * @param array $d data; */ function load_from_data($d=array()) { if(!empty($d)) { $this->cat_id = $d['cat_id']; $this->parent_id = $d['parent_id']; $this->name = $d['cat_name']; $this->path = $d['cat_path']; $this->title = $d['title']; $this->keywords = $d['keywords']; $this->description = $d['description']; $this->content = $d['content']; $this->num_products = $d['num_products']; $this->active = $d['active']; $this->menu = $d['menu']; $this->order_id = $d['order_id']; $this->position = $d['position']; $this->visited = $d['visited']; } $images = mysql_query("select * from image_data where image_type = 'category' and container_id='".$this->cat_id ."' order by image_id"); $this->images = array(); //empty if($images && mysql_num_rows($images)>0){ while ($i = mysql_fetch_assoc($images)) { $i['image'] = $i['image_path'].$i['image_filename']; //$i['thumbnail'] = $i['image_path'].THUMBNAIL_PREFIX.$i['image_filename']; $this->images[] = $i; } } return; } /** * populate/return subcategories * @param bool $all flag to switch between all/active, by default only load active * @param bool $vis flag to switch between shown on menu, by default only load visible */ function load_subcats($all=false,$vis=true) { $this->subcats = array(); //empty; /** * @var int $id this category id * @var string $query constructed mysql query * @var resource $subs mysql_resource set */ $id = $this->cat_id; $query = "select cat_id from categories where parent_id = '$id'"; $query .= ($all) ? '' : " and active = '1'"; $query .= (!$vis) ? '' : " and menu = '1'"; $query .= ' order by position ASC'; $subs = mysql_query($query); while($s = mysql_fetch_assoc($subs)) { $this->subcats[] = new category($s['cat_id'],true); } unset($s); unset($subs); // clean up return; } /** * populate/return products * @param bool $all flag to switch between all/active, by default only load active */ function load_products($all=false) { $this->products = array(); //empty /** * @var int $id this category id * @var string $query constructed mysql query * @var resource $prods mysql_resource set * @var array $return collects products to pass up the chain if called by load_all_products */ $id = $this->cat_id; $query = "select p.*, x.product_path as path from product_category_xref as x left join products as p on p.prod_id = x.product_id where x.category_id = '$id'"; $query .= ($all) ? '' : " and p.active = '1'"; $query .= ' order by x.position'; $prods = mysql_query($query); while($p = mysql_fetch_assoc($prods)) { $o = new product(); $o->load_from_data($p); $o->set_category($id); $this->products[] = $o; } return; } /** * load one page of products * @param int $start * @param bool $all * @uses PRODUCTS_PER_PAGE * @todo roll this into the standard load_products() (will need to update all calls to load_products()) */ function load_products_page($start=0, $all=false) { $this->products = array(); //empty /** * @var int $id this category id * @var string $query constructed mysql query * @var resource $prods mysql_resource set * @var array $return collects products to pass up the chain if called by load_all_products */ $id = $this->cat_id; $query = "select p.*, x.product_path as path from product_category_xref as x left join products as p on p.prod_id = x.product_id where x.category_id = '$id'"; $query .= ($all) ? '' : " and p.active = '1'"; $query .= ' order by x.position '; $query .= (PRODUCTS_PER_PAGE) ? " limit $start, ".PRODUCTS_PER_PAGE : ''; $prods = mysql_query($query);// or die($query); while($p = mysql_fetch_assoc($prods)) { $o = new product(); $o->load_from_data($p); $o->set_category($id); $this->products[] = $o; } return; } /** * populate/return products including those in subcategories * @param bool $all flag to switch between all/active, by default only load active */ function load_all_products($all=false) { $this->load_products($all); $this->all_products = $this->products; foreach($this->subcats as $s) { $s->load_all_products($all); $this->all_products = array_merge($this->all_products,$s->all_products); } $this->num_products = $this->count_all_products(); return; } /** * @todo function to re-sort products after load_all_products */ /** * count the number of products in category + subcategories, load subcats and products if necessary * @param bool $all flag to switch between all/active, by default only load active * @param bool $vis flag to switch between categories shown on menu, by default only load visible * @return int */ function count_all_products($all=false,$vis=true) { if(!$this->loadedProducts) { if(empty($this->subcats)) { $this->load_subcats($all,$vis); } $this->load_all_products($all); $this->loadedProducts = true; } return $this->count_products() + count($this->all_products); } /** * count the number of products in this objectonly, load products if necessary * $this->number_products is the total number of products in the category - usually only the visible (active) products will be loaded * @param bool $all flag to switch between all/active, by default only load active * @return int */ function count_products($all=false) { if(empty($this->products)) { $this->load_products($all); } return count($this->products); } /** * add record to the database and create stub file * @return bool */ function create() { global $message; /** * get from POST */ $this->parent_id = $parent_id = clean_plain_data($_POST['parent']); $this->name = $name = clean_plain_data($_POST['cat_name']); $this->position = $position = is_numeric_id($_POST['position'],0); if(!$position) { $this->position = $position = select_one('categories','max(position)','parent_id',$parent_id)+10; } /** * validate required fields */ $m = ''; if($name==''){ $m .= 'Please enter a category name <br />'; } if($parent_id != 0 && (!is_numeric_id($parent_id, false) || !select_one('categories', 'cat_id', 'cat_id', $parent_id) ) ) { $m .= 'Invalid parent category'; } if($m != '') { $message .= $m; return false; } /** * assemble directory path * @var string $path * @var string $parent_path */ $path = dir_name($name); if($parent_id > 0) { $parent_path = select_one('categories', 'cat_path', 'cat_id', $parent_id); } else { if(!$parent_path = select_one('page_data', 'path', 'page_type', 'products')) { $message .= 'No products section defined <br />'; return false; } } $this->path = $path = $parent_path.$path; /** * add to database * @var string $fields * @var string $values */ $date_added = time(); $fields = 'parent_id , cat_name , cat_path , position '; $values = "'$parent_id' , '$name' , '$path/' , '$position' "; $query = "insert into categories ( $fields ) values ( $values )"; if(!mysql_query($query)) { $message .= mysql_error(); return false; } $message .= 'Category record created <br />'; $this->cat_id = $cat_id = mysql_insert_id(); /** * create stub file * there will be a page_id because we checked for the record getting $parent_path */ $contents = array( 'page_id' => select_one('page_data','page_id','page_type','products') , 'cat_id' => $cat_id ); if(!create_stub_file($path, $contents)) { //message should have been added by create_stub_file() $this->remove_from_database(); return false; } /** * directory for images * @var string $dir */ $dir = DOC_ROOT.'/resources/images/category/'.$cat_id; if(!mkdir($dir, 0755,true)) { $message .= 'There was an error creating the image path <br />'; $this->remove_from_database(); clean_dir(DOC_ROOT.$this->path, true); return false; } chmod($dir, DIR_PERMS); $message .= 'Category created successfully.<br />'; return true; } /** * update record in the database * update image * @return bool */ function update() { global $message; /** * san check */ if(!$this->cat_id) { $message .= 'Invalid category <br />'; return false; } /** * get from POST */ $this->name = $name = clean_plain_data($_POST['cat_name']); $this->title = $title = clean_plain_data($_POST['title']); $this->keywords = $keywords = clean_plain_data($_POST['keywords']); $this->description = $description = clean_plain_data($_POST['description']); $this->content = $content = clean_html_data($_POST['content']); /** * validate required fields */ $m = ''; if($name==''){ $m .= 'Please enter a category name <br />'; } if($m != '') { $message .= $m; return false; } /** * @var string $query update query */ $query = "update categories set cat_name = '$name' , title = '$title' , keywords = '$keywords' , description = '$description' , content = '$content' where cat_id = '$this->cat_id'"; $update = mysql_query($query); if(!$update) { $message .= mysql_error(); return false; } $message .= 'Category record updated <br />'; /** * replace thumbnail image? */ $this->add_thumbnail('thumbnail'); /** * if we need to add a full size image or images for some reason * then copy in code based on {product->add_image()} */ return true; } /** * remove record from database * @return bool */ function remove_from_database() { global $message; /** * san check */ if(!is_numeric_id($this->cat_id,0)) { $message .= 'Unable to remove category from database: invalid id <br />'; return false; } /** * delete category record * @var string $query delete query * @return bool */ $query = "delete from categories where cat_id = '$this->cat_id'"; $result = mysql_query($query); if(!$result || mysql_affected_rows() != 1) { $message .= 'There was an error '.mysql_error().'<br />Affected rows: '.mysql_affected_rows(); return false; } // $message .= $this->name.' database records deleted <br />'; return true; } /** * add an image * @var string $upload form field * @return bool * @todo we probably need to tidy up all the image functions into one or two - move databasing into upload_image() function */ function add_thumbnail($upload) { global $message; /** * san check */ if(!$upload || !is_numeric_id($this->cat_id)) { return false; } /** * make sure we have an image directory */ $path = '/resources/images/category/'.$this->cat_id; $dir = DOC_ROOT.$path; if(!is_dir($dir)) { mkdir($dir,0755,true); chmod($dir, DIR_PERMS); } $dir .= '/'; /** * @var array $dim config for image function * @var int $img_id */ $dim = array('w'=>CATEGORY_THUMBNAIL_WIDTH,'h'=>CATEGORY_THUMBNAIL_HEIGHT, 'tw'=>0, 'th'=>0, 'orient'=>''); if($_FILES[$upload]['name']) { if(!$img_id = select_one('image_data', 'image_id', 'concat(image_type,container_id)','category'.$this->cat_id)) { if(!$insert = mysql_query("insert into image_data (image_type, container_id, image_path, title, link, active) values ('category', '$this->cat_id', '$path/', '', '', '1')")) { $message .= 'Image upload database error. '.mysql_error().'<br />'; return false; } //else $img_id = mysql_insert_id(); } /** * @var string $suff * @var string $filename */ $suff = image_suffix($_FILES[$upload]['tmp_name']); $filename = 'thumbnail'.$suff; $message .= upload_image($upload,$dim,$dir,$filename,false); // resize directly to thumbnail if(!file_exists($dir.$filename)) { // appropriate message should have been generated by upload_image() mysql_query("delete from image_data where image_id = '$img_id'"); return false; } else { list($w, $h) = @getimagesize($dir.$filename); if(!$update = mysql_query("update image_data set image_filename = '$filename', width = '$w', height = '$h' where image_id = '$img_id'")) { $message .= 'There was a problem recording the image. Please try again.'.mysql_error().'<br />'; unlink(($dir.$filename)); mysql_query("delete from image_data where image_id = '$img_id'"); return false; } } //message generated by upload_image() //$message .= ucfirst(str_replace('_', ' ', $upload)).' uploaded <br />'; return true; } //else //$message .= print_r($_FILES,true); return false; } /** * remove all images * @param bool $rmDir remove image directory as well * @return bool */ function remove_images($rm_dir = false) { global $message; /** * san check */ if(!is_numeric_id($this->cat_id,0)) { $message .= 'Unable to remove category images: invalid id <br />'; return false; } /* * images */ // files $path = DOC_ROOT.'/resources/images/category/'.$this->cat_id; if(!clean_dir($path, $rm_dir)) { $message .= 'Unable to remove category images: dir failed <br />'; return false; } //delete image records mysql_query("delete from image_data where image_type like 'category%' and container_id = '$this->cat_id'"); $message .= $this->name.' images deleted <br />'; return true; } /** * remove all products * more efficient than repeatedly loading products and calling remove_from_category * @return bool */ function remove_products() { global $message; /** * san check */ if(!is_numeric_id($this->cat_id,0)) { $message .= 'Unable to remove products from category: invalid id <br />'; return false; } /** * remove all products from category * @var string $query * @var string $path directory we will be deleting */ $query = "select * from product_category_xref where category_id = '$this->cat_id'"; //$query .= ($cat_id) ? " and category_id = '$cat_id'" : ''; $paths = mysql_query($query); $n = 0; while($p = mysql_fetch_assoc($paths)) { if(clean_dir(DOC_ROOT.$p['product_path'],true)) { mysql_query("update categories set num_products = num_products-1 where cat_id = '$this->cat_id'"); $n++; } else { $message .= $n.' products removed from '.$this->name.' <br />'; $message .= 'Error: Unable to delete all products <br />'; return false; } } $query = "delete from product_category_xref where category_id = '$this->cat_id'"; //$query .= ($cat_id) ? " and category_id = '$cat_id'" : ''; mysql_query($query); $message .= ($n>0) ? $n.' products removed from '.$this->name.' <br />' : ''; $this->products = array(); return true; } /** * delete subcategories. Use with care. * load subcategories before calling this function (this allows the list to be customised) * @return bool */ function delete_subcategories() { global $message; foreach($this->subcats as $s) { if(!$s->delete(true)) { $message .= 'Error: unable to delete '.$this->name.' -> '.$s->name.'<br />'; return false; } //else $message .= 'Deleted '.$this->name.' => '.$s->name.'<br />'; } return true; } /** * remove everything * @param $subcat flag to say if this is being called from $this->delete_subcategories (toggles message) * @return bool */ function delete($subcat = false) { global $message; /** * san check */ if(!is_numeric_id($this->cat_id,0)) { $message .= 'Unable to delete category: invalid id <br />'; return false; } /** * delete subcategories (recursive) */ $this->load_subcats(true,false); if(!$this->delete_subcategories()) { return false; } /** * remove products */ if(!$this->remove_products()) { return false; } /** * remove (delete) images */ if(!$this->remove_images(true)) { $message .= 'Notice - did not remove images directory <br />'; //not a critical error - continue } /** * delete stub file and directory */ clean_dir(DOC_ROOT.$this->path,true); if(file_exists($this->path)) { $message .= 'Error: unable to remove file <br />'; return false; } /** * remove (delete) from database */ if(!$this->remove_from_database()) { return false; } //else if(!$subcat) { $message .= 'Deleted '.$this->name.' <br />'; } return true; } } ?>
cải xoăn