ruạṛ
<?php ################################################################# # DISPLAY FUNCTIONS ################################################################# # BUILD MENU TREE # called from: template.php # purpose: generate nested list of pages with info needed for nav menu # notes: note selection by 'menu' and 'active' fields function build_menu_tree($parent=0, $showHidden = false) { $connID = connect_to_db(); $tree = array(); $pages = mysql_query("select * from page_data where parent_id = '$parent'" . (!$showHidden ? " and menu='1'" : "") . " and active='1' order by position"); // echo mysql_error(); // debugging while($p = mysql_fetch_assoc($pages)) { $path = ($p['external']) ? $p['external_path'] : $p['path']; $tree[] = array('page_id'=>$p['page_id'] ,'name'=>$p['name'] ,'type'=>$p['page_type'] ,'parent_id'=>$p['parent_id'] ,'path'=>$path ,'position'=>$p['position'] ,'active'=>$p['active'] ,'menu'=>$p['menu'] ,'menu_id'=>$p['menu_id'] ,'text'=>$p['menu_text'] ,'home'=>$p['index_page'] ,'error'=>$p['error_page'] ,'external'=>$p['external'] ,'visited'=>$p['visited'] ,'description'=>$p['description'] ,'branches'=>build_menu_tree($p['page_id']) //recursive ); } return $tree; } # BUILD PARENT CHAIN # called from: template.php # purpose: generate list of parents of the current page for labelling as selected in navigation function build_parent_chain($page_id) { global $homepage; $chain = array($page_id); if($page_id!=0 && !$homepage) { while( ( $page_id = select_one('page_data','parent_id','page_id',$page_id) ) != 0) { array_unshift($chain,$page_id); } array_unshift($chain, 0); //for home } return $chain; } # BUILD NAV # called from: template.php # purpose: generate list element code for navigation # notes: does not include initial; <ul> and final </ul> elements function build_nav($pages=array(), $tier=1, $menu=1, $depth=0, $categories = true, $descriptions = false) { global $parent_chain, $categories; $rows = ""; $i = 1; $j = count($pages); if($tier <= 1 || !$descriptions) { foreach($pages as $p) { if($p['menu_id'] != $menu && $menu !== null) { // $rows .= $menu.' '.$p['menu_id'].' ! '; //debugging $j--; continue; } $rows .= '<li class="'; $rows .= 'tier'.$tier; $rows .= ($p['home']) ? ' home' : ''; $rows .= (isset($parent_chain) && in_array($p['page_id'],$parent_chain)) ? ' sel' : ''; $rows .= '"><a href="'.$p['path'].'" class="'; $rows .= ($tier>1 && count($p['branches'])>0) ? 'sub' : ''; $rows .= '">'; $rows .= ($p['text'] != '') ? $p['text'] : $p['name']; $rows .= '</a>'; if($categories && $p['type']=='products' && $depth > $tier) { $rows .= '<ul> '.build_cat_nav($categories,($depth > $tier+1) ).' </ul> '; } else { if(count($p['branches'])>0 && ($depth == 0 || $tier < $depth) ) { if(!$descriptions) { $tag = "ul"; } else { $tag = "div"; } $rows .= "\n".'<' . $tag . '>'."\n"; $rows .= build_nav($p['branches'], $tier+1, $p['menu_id'],$depth,$categories,$descriptions); //recursive $rows .= "\n".'</' . $tag . '>'."\n"; } } $rows .= '</li>'; $i++; } } else { $lists = array("", "", ""); foreach($pages as $index => $page) { if((int) $page["menu_id"] !== (int) $menu) { $j -= 1; } $listItem = ""; $listItem .= "<li class='" . $tier . (isset($parent_chain) && in_array($page["page_id"], $parent_chain) ? ' sel' : '') . "'>\n"; $listItem .= "<a href='" . $page["path"] . "' class='" . (($tier > 1 && count($page["branches"]) > 0) ? 'sub' : '') . "'>" . ($page["text"] !== "" ? $page["text"] : $page["name"]) . "</a>\n"; $listItem .= "<p>\n"; $listItem .= $page["description"] . "\n"; $listItem .= "</p>\n"; $listItem .= "</li>\n"; $lists[$index % 3] .= $listItem; $i += 1; } $rows .= "<ul>" . implode("</ul><ul>", $lists) . "</ul>\n"; } return $rows; } # TEXT NAV # called from: template.php # purpose: generate string of top level pages function text_nav($pages=array()) { $i = 0; $j = count($pages)-1; foreach($pages as $p) { $str .= '<a href="'.$p['path'].'">'.$p['name'].'</a>'; $str .= ($i<$j) ? ' | ':''; $i++; } return $str; } #BUILD CAT NAV # called from: template.php # purpose: generate string of category menu /** * @param array $categories category tree as nested arrays * @param bool $all toggle whether to display all subcategories or just active branch * @param array $cat_chain * @return string */ function build_cat_nav($categories,$all=false,$cat_chain=array()) { /** * import variables from global scope * @var int $cat_id * @var int $n tracks cumulative number of products from sub-categories for designs which show number of products on nav menu */ global $cat_id, $n; /** * get all the parents of the current (sub)category so we know to display them * first iteration (bottom subcategory) - build chain thereafter pass it down in recursive function call * might be a more efficient way to do this in one db query but if I had to optimise I'd probably just have a field to store -all- the parent_ids on category creation */ if(empty($cat_chain)){ $pid = $cat_id; while($pid){ //stop when $pid == 0 $cat_chain[] = $pid; $pid = select_one('categories','parent_id','cat_id',$pid); } } /** * @var string $rows list item html */ $rows = ''; foreach($categories as $c) //each (sub)category on this branch and tier { /** * reset at the beginnign of each loop * @var string $link contents of this menu item * @var string $lower subcategory html (from recursion) * @var string $product product list html (unused in this version) */ $link = ''; $lower = ''; $product = ''; if($c['parent_id']==0) // top level category { $n = 0; //reset $n } if($c['menu'] && $c['active']) //display { /** * @var int $cid short reference */ $cid = $c['cat_id']; $link = '<a href="'.$c['path'].'">'.$c['name'].'</a> '; //sometimes include $n in here if($all || in_array($cid,$cat_chain)) //are we displaying (further) subcategories of this branch? { $lower=build_cat_nav($c['branches'],$all,$cat_chain); //recursive, also updates $n } $n += $c['products']; //update $n if($lower != '') { // generate submenu html $rows .= '<li class="sub'; $rows .= ($cat_id==$cid) ? ' sel' : ''; $rows .= (in_array($cid,$cat_chain)) ? ' open' : ''; $rows .= '">'.$link.' <ul class="cat'; // $rows .= (in_array($cid,$cat_chain)) ? ' open' : ''; $rows .= '"> '.$lower.' </ul> </li> '; } else { //generate single link html // if we are also listing products in the menu this is also where we generate and append $products using similar html as wraps $lower (see build_nav()) $rows .= '<li'; $rows .= ($cat_id==$cid) ? ' class="sel"' : ''; $rows .= '>'.$link.'</li> '; } } } return $rows; } # GET BRANCH # called from: page_type_products.php # purpose: get a category function get_branch($tree,$field,$id=0) { foreach($tree as $t) { if($t[$field]==$id) { return $t; } elseif($r=get_branch($t['branches'],$field,$id)) { return $r; } } return false; } # SUM PRODUCTS # called from: page_type_products.php # purpose: add up all teh products in a sub_category # note could probably do this in build_category_tree(), but extra overhead function sum_products($c) { $n = $c['products']; if(!empty($c['branches'])) { foreach($c['branches'] as $b) { $n += sum_products($b); } } return $n; } # BUILD BREADCRUMBS # called from: template.php # purpose: generate list element code for navigation # notes: does not include initial; <ul> and final </ul> elements function build_breadcrumbs($pages=array()) { $str = ''; foreach($pages as $p) { if($p==0) { $str .= '<a href="/index.php">Home</a>'; } else { $str .= select_one('page_data',"CONCAT(' > <a href=\"',path,'\">',name,'</a>')",'page_id',$p); } } // $str .= print_r($pages,true); //debugging return $str; } /** * display a link to the cart if there are products present * @global bool MODULE_CART * @global object $cart * @global string $page_type * @todo break orders out into it's own page type like password resets */ function cart_nav() { global $cart, $page_type; $rows = ''; if(MODULE_CART && $cart->num_products > 0 && $page_type != 'orders') { $rows = '<li class="cart'; $rows .= ($page_type=='cart') ? ' sel' : ''; $rows .= '"><a href="'.select_one('page_data','path','page_type','cart').'" >('.$cart->num_items.') Item(s) - '.format_price($cart->order_total()).'</a></li>'; } return $rows; } /** * display customer account menu depending on logged in status * @global bool MODULE_CUSTOMERS * @global object $customer * @global string $page_type */ function account_nav() { global $customer, $page_type; $rows = ''; $path = select_one('page_data','path','page_type','customer'); if($customer->logged_in) { $rows .= '<li class="login'; $rows .= ($page_type=='customer') ? ' sel' : ''; $rows .= '"><a href="'.$path.'">Your Account</a></li> <li class="orders '; $rows .= ($page_type=='orders') ? ' sel' : ''; $rows .= '"><a href="'.select_one('page_data','path','page_type','orders').'">Order History</a></li> <li class="logout"><a href="/processes/process-customer-log-out.php">Log out</a></li>'; } elseif(MODULE_CUSTOMERS) { $rows .= '<li class="login'; $rows .= ($page_type=='customer') ? ' sel' : ''; $rows .= '"><a href="'.$path.'">Log In</a></li>'; } return $rows; } /** * process content from database field for output * @global string $content html content + special codes from database */ function db_content($content) { //global $content; /** * run search/replace on $content for galleries or other special CMS codes * @var array $matches data returned by preg_match_all (initialise empty) $matches[1] contains gallery_id(s) * @var array $exacts the full codes to be replaced by preg_match_replace (initialise empty) * @var array $replaces the full strings to be inserted by preg_match_replace (initialise empty) */ $content = html_entity_decode($content,ENT_QUOTES); $matches = array(); $exacts = array(); $replaces = array(); if(preg_match_all('/<p>(?:\s| )*%%GALLERY-([\d]+)%%(?:\s| )*<\/p>/',$content,$matches)) { foreach($matches[1] as $a => $v) { /** * @var int $gallery_id database id of the gallery to be inserted * @var resource $gallery result of the mysql query for the gallery * @var array $g one gallery record * @var resource $images result of the database query for images in the gallery * @var array $i one image record * @var string $r html gallery code (div containing unordered list or Not found message) */ $gallery_id = $v; $exacts[] = '/<p>(?:\s| )*%%GALLERY-'.$gallery_id.'%%(?:\s| )*<\/p>/'; if(!$gallery = mysql_query("select * from gallery_data where gallery_id = '$gallery_id'")) { $r = '<div class="gallery"><p>No images found<p></div>'; } else { $galleryMin = is_numeric($_GET['start']) ? $_GET['start'] : 0; $g = mysql_fetch_assoc($gallery); if(!$g['active']) { $r = '<div class="gallery"><p>No images found<p></div>'; } elseif(!$images = mysql_query("select * from image_data where image_type='gallery' and container_id = '$gallery_id' and active='1' order by order_id desc, image_id LIMIT " . $galleryMin . ", " . GALLERY_IMAGES_PER_PAGE)) { $r = '<div class="gallery"><p>No images found<p></div>'; } elseif(mysql_num_rows($images)<1) { $r = '<div class="gallery"><p>No images found<p></div>'; } else { $totalImagesResult = mysql_query("SELECT COUNT(*) as image_count FROM image_data WHERE image_type = 'gallery' AND container_id = " . $gallery_id . " AND active = 1 ORDER BY order_id DESC"); $totalImagesRow = mysql_fetch_assoc($totalImagesResult); $totalImages = $totalImagesRow["image_count"]; $r = '<div class="gallery"><ul>'; while($i = mysql_fetch_assoc($images)) { $title = str_replace('$','\$',$i['title']); //or else it gets interpreted as a backreference marker in preg_replace() $r .= '<li><a href="'.$g['gallery_path'].$i['image_filename'].'" rel="gallery'.$v.'" title="'.$title.'"><img src="'.$g['gallery_path'].THUMBNAIL_PREFIX.$i['image_filename'].'" alt="'.$title.'" /></a></li>'."\n"; } $r .= '</ul> <br class="clear" /> </div> <div class="pagination"> ' . paging($totalImages, GALLERY_IMAGES_PER_PAGE, $galleryMin) . ' </div> <script type="text/javascript"> $(document).ready(function(){ $("a[rel=gallery'.$v.']").colorbox(); }); </script> '; } } $replaces[] = $r; // print_r($v); //debugging } /* //debugging echo 'Exacts '; print_r($exacts); echo 'replaces '; print_r($replaces); */ /* * replace CMS codes with html gallery code */ $content = preg_replace($exacts,$replaces,$content); } if(preg_match('/<p>(?:\s| )*%%SLIDESHOW%%(?:\s| )*<\/p>/',$content)) { global $has_slideshow, $slideshow; if($has_slideshow && $slideshow && mysql_num_rows($slideshow)>0) { $captions = ''; $r = ' <div class="slideshow"> <div class="slider"> '; while($s = mysql_fetch_assoc($slideshow)) { $r .= '<img src="'.$s['image_path'].$s['image_filename'].'" alt="'.$s['title'].'" width="'.PAGE_SLIDESHOW_WIDTH.'" height="'.PAGE_SLIDESHOW_HEIGHT.'" data-caption ="#caption-'.$s['image_id'].'" /> '; $captions .= '<span class="orbit-caption" id="caption-'.$s['image_id'].'">'.$s['title'].'</span> '; } $r .= ' </div> </div> '; /* * replace CMS code with html slideshow code */ $content = preg_replace('/<p>(?:\s| )*%%SLIDESHOW%%(?:\s| )*<\/p>/',$r.$captions,$content); } } if(MODULE_BLOG && preg_match_all('/<p>(?:\s| )*%%BLOGPREVIEW-([\d]+)%%(?:\s| )*<\/p>/', $content, $matches)) { foreach($matches[1] as $a => $v) { $content = preg_replace('/<p>(?:\s| )*%%BLOGPREVIEW-' . $v . '%%(?:\s| )*<\/p>/', blogPreview($v, 2), $content); } } if(MODULE_CUSTOMER_INTERESTS && preg_match('/<p>(?:\s| )*%%NEWSLETTER%%(?:\s| )*<\/p>/',$content)) { global $customer; $replace .= '<form id="contact" action="/processes/process-newsletter.php" method="post" enctype="multipart/form-data" class="contact"> <script type="text/javascript">// <![CDATA[ if(m = readCookie("formMessage")){ document.write(URLDecode(m)); eraseCookie("formMessage"); } // ]]></script> '; if($customer->newsletter){ $replace .= '<p>You have signed up for our newsletter, thank you. <a href="/processes/process-newsletter-remove.php">Click here to unsubscribe</a></p>'; } $replace .= '<p><label for="Customer">Full Name:</label> <input id="Customer" name="Customer" type="text" value="'.$customer->name.'" /></p> <p><label for="Email">Email:</label> <input id="Email" name="Email" type="text" value="'.$customer->email.'" /></p> <p class="interests-head">Please indicate your interests so that we can send you newsletters relevant to you</p> <div class="interests"> '.build_interest_checkboxes($customer->interest_list,$customer->interests).' </div> <div class="clear"> </div> <p><label for="security_code">Security:</label> <img class="auth" src="/resources/captcha/CaptchaSecurityImages.php" alt="Security Code" /> <input id="security_code" name="auth" type="text" /></p> <p class="action"><input name="submit" type="submit" value="'; $replace .= ($customer->newsletter) ? 'Change interests' : 'Sign Up'; $replace .= '" class="button" /></p> </form> '; /* * replace CMS code with html form code */ $content = preg_replace('/<p>(?:\s| )*%%NEWSLETTER%%(?:\s| )*<\/p>/',$replace,$content); } return $content; } /** * Displays the first paragraph from recent blog articles * @param int $articles Number of articles to display * @author Callum Muir <cmuirnz@gmail.com> */ function blogPreview($page, $articles) { $query = "SELECT *, UNIX_TIMESTAMP(DATE) AS timestamp " . "FROM blog " . "WHERE active = 1 " . "AND page_id = " . $page . " " . "ORDER BY DATE desc " . "LIMIT " . $articles; $result = mysql_query($query); $html = ""; while($article = mysql_fetch_assoc($result)) { $content = db_content($article['content']); $start = strpos($content, '<p>'); $end = strpos($content, '</p>', $start); $paragraph = substr($content, $start + 3, $end - $start - 3); $html .= "<p>\n"; $html .= "<a href='" . $article['path'] . "'>" . date('d\-m', $article['timestamp']) . "</a> - " . $paragraph . "\n"; $html .= "</p>\n"; } return $html; } /** * send an email using default site settings * @var string $body * @var string $subject * @var string $to_address * @global string SITE_EMAIL */ function send_email($body='',$subject='', $to_address='', $from_address='') { /** * Validate/set addresses, construct headers * @var string $headers */ if (!is_email($from_address)) $from_address = SITE_FROM_ADDRESS; //$from_address = 'programmer@activatedesign.co.nz'; //development if (!is_email($to_address)) $to_address = $from_address; $headers = "From: $from_address" . "\n" . "Reply-To: $from_address" . "\n" . "Return-Path: $from_address" . "\n" . 'X-Mailer: PHP/' . phpversion(); return mail($to_address, $subject, $body, $headers); } /** * suhosin workaround set up user including stored cart details * @return object */ function user_load(){ /** * look for an existing record within a resonable timeframe (limits exposure to stolen session cookies fron logged in customers) * @var string $sess_id * @var int $timeframe timestamp lower limit * @var resource $stored_data */ $sess_id = session_id(); $timeframe = time()-10800; //60*60*3 mysql_query("delete from session_anon where timestamp < '$timeframe'"); //table maintenance, should really be in a cron run once a day or more/less frequently depending on site traffic $stored_data = mysql_query("select * from session_anon where session_id = '$sess_id' and timestamp > '$timeframe' limit 1"); if(!$stored_data) //error { die(mysql_error()); } elseif(mysql_num_rows($stored_data) < 1) //no match { /* * add new record */ mysql_query("delete from session_anon where session_id = '$sess_id'"); //so as not to clash with pssible not-yet-cleaned-up expired ($timeframe) stored session mysql_query("insert into session_anon (session_id, timestamp) values ('$sess_id', '".time()."') "); $user = new user; } else { /** * load cart data either from temporary record or from user record if logged in */ $data = mysql_fetch_assoc($stored_data); $user_id = $data['user_id']; if($user_id==0){ // not logged in $user = new user; $user->name = $data['full_name']; $user->address = $data['address']; $user->shipping_location = $data['shipping_location']; $user->phone = $data['phone']; $user->email = $data['email']; $user->newsletter = $data['newsletter']; $user->interests = json_decode($data['interests'],true); $user->cart = $data['cart']; $user->wishlist = $data['wishlist']; } else //logged in { $user = new user($user_id); $user->logged_in = true; } /** * update session timestamp */ mysql_query("update session_anon set timestamp = '".time()."' where session_id = '$sess_id'"); } return $user; } /** * suhosin workaround save user details * @param object $user object */ function user_save($user){ $sess_id = session_id(); $interests = json_encode($user->interests); //print_r($user);die(); //debugging if(select_one('session_anon','session_id','session_id',$sess_id)) { //update $query = "update session_anon set full_name = '$user->name' , shipping_location = '$user->shipping_location' , address = '$user->address' , phone = '$user->phone' , email = '$user->email' , newsletter = '$user->newsletter' , interests = '$interests' where session_id = '$sess_id' "; } else { //insert $query = "insert into session_anon set session_id = '$sess_id' , full_name = '$user->name' , shipping_location = '$user->shipping_location' , address = '$user->address' , phone = '$user->phone' , email = '$user->email' , newsletter = '$user->newsletter' , interests = '$interests' "; } return mysql_query($query) or die(mysql_error()); } /** * suhosin workaround save user cart details * @param object $cart object * @param string $target */ function user_save_cart($cart,$target='cart'){ /** * update record * @var string $sess_id * @var string $contents serialized data */ $sess_id = session_id(); if(in_array($target,array('cart','wishlist'))) { $contents = ($cart->num_products) ? serialize($cart) : ''; mysql_query("update session_anon set $target = '$contents' where session_id = '$sess_id'"); } } /** * suhosin workaround log in * @param int $user_id */ function user_register_login($user_id){ if(!$user_id) { return false; } /** * update record * @var string $sess_id */ $sess_id = session_id(); mysql_query("update session_anon set user_id = '$user_id', cart='', wishlist='' where session_id = '$sess_id'"); return; } /** * suhosin workaround logout */ function user_register_logout(){ /** * delete record (new empty record will be created on next page load) * @var string $sess_id */ $sess_id = session_id(); mysql_query("delete from session_anon where session_id = '$sess_id'"); return; } ?>
cải xoăn