/** * Diaplay the product catalog items. * * @return string HTML for product catalog. */ function PAYPAL_ProductList($cat_id = 0, $search = '') { global $_TABLES, $_CONF, $_PP_CONF, $LANG_PP, $_USER, $_PLUGINS, $_IMAGE_TYPE, $_GROUPS, $LANG13; USES_paypal_class_product(); USES_paypal_class_category(); if (SEC_hasRights('paypal.admin')) { $isAdmin = true; } else { $isAdmin = false; } $my_groups = implode(',', $_GROUPS); $cat_name = ''; $breadcrumbs = ''; $cat_img_url = ''; $display = ''; if ($cat_id != 0) { $Cat = new Category($cat_id); if ($Cat->isNew || !$Cat->hasAccess()) { echo COM_refresh(PAYPAL_URL); exit; } $breadcrumbs = PAYPAL_Breadcrumbs($cat_id); $cat_name = $Cat->name; $cat_desc = $Cat->description; $cat_img_url = $Cat->ImageUrl(); } // Display categories if (isset($_PP_CONF['cat_columns']) && $_PP_CONF['cat_columns'] > 0) { $sql = "SELECT cat.cat_id, cat.cat_name, count(prod.id) AS cnt\n FROM {$_TABLES['paypal.categories']} cat\n LEFT JOIN {$_TABLES['paypal.products']} prod\n ON prod.cat_id = cat.cat_id\n WHERE cat.enabled = '1' AND cat.parent_id = '{$cat_id}'\n AND prod.enabled = '1' " . PAYPAL_buildAccessSql('AND', 'cat.grp_access') . " GROUP BY cat.cat_id\n ORDER BY cat.cat_name"; //HAVING cnt > 0 //echo $sql;die; $res = DB_query($sql); $A = array(); while ($C = DB_fetchArray($res, false)) { $A[$C['cat_id']] = array($C['cat_name'], $C['cnt']); } // Now get categories from plugins foreach ($_PLUGINS as $pi_name) { $function = 'USES_' . $pi_name . '_paypal'; if (function_exists($function)) { $function(); $function = 'plugin_paypal_getcategories_' . $pi_name; if (function_exists($function)) { $pi_cats = $function(); foreach ($pi_cats as $catid => $data) { $A[$catid] = $data; } } } } $i = 1; $catrows = count($A); if ($catrows > 0) { $CT = new Template(PAYPAL_PI_PATH . '/templates'); $CT->set_file(array('table' => 'category_table.thtml', 'row' => 'category_row.thtml', 'category' => 'category.thtml')); //$CT->set_var('breadcrumbs', $breadcrumbs); if ($cat_img_url != '') { $CT->set_var('catimg_url', $cat_img_url); } $CT->set_var('width', floor(100 / $_PP_CONF['cat_columns'])); foreach ($A as $category => $info) { $CT->set_var(array('category_name' => $info[0], 'category_link' => PAYPAL_URL . '/index.php?category=' . urlencode($category))); /*if ($category == $cat) { $CT->set_var('curr', 'current'); $cat_name = $info[0]; } else { $CT->set_var('curr', 'other'); }*/ $CT->parse('catrow', 'category', true); if ($i % $_PP_CONF['cat_columns'] == 0) { $CT->parse('categories', 'row', true); $CT->set_var('catrow', ''); } $i++; } if ($catrows % $_PP_CONF['cat_columns'] != 0) { $CT->parse('categories', 'row', true); } $display .= $CT->parse('', 'table'); } } //$sortdir = $_REQUEST['sortdir'] == 'DESC' ? 'DESC' : 'ASC'; //$sql_sortdir = $sortdir; $sortby = isset($_REQUEST['sortby']) ? $_REQUEST['sortby'] : $_PP_CONF['order']; switch ($sortby) { case 'price_l2h': // price, low to high $sql_sortby = 'price'; $sql_sortdir = 'ASC'; break; case 'price_h2l': $sql_sortby = 'price'; $sql_sortdir = 'DESC'; break; case 'top_rated': $sql_sortby = 'rating'; $sql_sortdir = 'DESC'; break; case 'newest': $sql_sortby = 'dt_add'; $sql_sortdir = 'DESC'; break; case 'name': $sql_sortby = 'short_description'; $sql_sortdir = 'ASC'; break; /*case 'price': case 'dt_add': $sql_sortby = $sortby; break; case 'rating': $sql_sortby = 'rating'; break;*/ /*case 'price': case 'dt_add': $sql_sortby = $sortby; break; case 'rating': $sql_sortby = 'rating'; break;*/ default: $sortby = $_PP_CONF['order']; $sql_sortby = $sortby; $sql_sortdir = 'ASC'; break; } $sortby_options = ''; foreach ($LANG_PP['list_sort_options'] as $value => $text) { $sel = $value == $sortby ? ' selected="selected"' : ''; $sortby_options .= "<option value=\"{$value}\" {$sel}>{$text}</option>\n"; } //$sortby = $_PP_CONF['order']; //$sortdir = 'ASC'; // Get products from database. "c.enabled is null" is to allow products // with no category defined $today = $_PP_CONF['now']->toMySQL(); $sql = " FROM {$_TABLES['paypal.products']} p\n LEFT JOIN {$_TABLES['paypal.categories']} c\n ON p.cat_id = c.cat_id\n WHERE p.enabled=1\n AND p.avail_beg <= '{$today}' AND p.avail_end >= '{$today}'\n AND (\n (c.enabled=1 " . PAYPAL_buildAccessSql('AND', 'c.grp_access') . ")\n OR c.enabled IS NULL\n )\n AND (\n p.track_onhand = 0 OR p.onhand > 0 OR p.oversell < 2\n )"; // Add search query, if any if (isset($_REQUEST['query']) && !empty($_REQUEST['query']) && !isset($_REQUEST['clearsearch'])) { $srchitem = DB_escapeString($_REQUEST['query']); $fields = array('p.name', 'c.cat_name', 'p.short_description', 'p.description', 'p.keywords'); $srches = array(); foreach ($fields as $fname) { $srches[] = "{$fname} like '%{$srchitem}%'"; } $srch = ' AND (' . implode(' OR ', $srches) . ')'; $sql .= $srch; } $pagenav_args = array(); // If applicable, limit by category if (!empty($_REQUEST['category'])) { $cat_list = $_REQUEST['category']; $cat_list .= PAYPAL_recurseCats('PAYPAL_callbackCatCommaList', 0, $_REQUEST['category']); if (!empty($cat_list)) { $sql .= " AND c.cat_id IN ({$cat_list})"; } $pagenav_args[] = 'category=' . urlencode($_REQUEST['category']); } else { $cat_list = ''; } /* // If applicable, limit by search string if (!empty($_REQUEST['search_name'])) { $srch = DB_escapeString($_REQUEST['search_name']); $sql .= " AND (p.name like '%$srch%' OR p.short_description like '%$srch%' OR p.description like '%$srch%' OR p.keywords like '%$srch%')"; //if (!$isAdmin) $sql .= " AND p.grp_access IN ($my_groups) "; $pagenav_args[] = 'search_name=' . urlencode($_REQUEST['search_name']); } */ // If applicable, order by $sql .= " ORDER BY {$sql_sortby} {$sql_sortdir}"; //echo $sql;die; // If applicable, handle pagination of query if (isset($_PP_CONF['prod_per_page']) && $_PP_CONF['prod_per_page'] > 0) { // Count products from database $res = DB_query('SELECT COUNT(*) as cnt ' . $sql); $x = DB_fetchArray($res, false); if (isset($x['cnt'])) { $count = (int) $x['cnt']; } else { $count = 0; } // Make sure page requested is reasonable, if not, fix it if (!isset($_REQUEST['page']) || $_REQUEST['page'] <= 0) { $_REQUEST['page'] = 1; } $page = (int) $_REQUEST['page']; $start_limit = ($page - 1) * $_PP_CONF['prod_per_page']; if ($start_limit > $count) { $page = ceil($count / $_PP_CONF['prod_per_page']); } // Add limit for pagination (if applicable) if ($count > $_PP_CONF['prod_per_page']) { $sql .= " LIMIT {$start_limit}, {$_PP_CONF['prod_per_page']}"; } } // Re-execute query with the limit clause in place $res = DB_query('SELECT DISTINCT p.id ' . $sql); // Create product template if (empty($_PP_CONF['list_tpl_ver'])) { $_PP_CONF['list_tpl_ver'] = 'v1'; } $product = new Template(PAYPAL_PI_PATH . '/templates'); $product->set_file(array('start' => 'product_list_start.thtml', 'end' => 'product_list_end.thtml', 'product' => 'list/' . $_PP_CONF['list_tpl_ver'] . '/product_list_item.thtml', 'download' => 'buttons/btn_download.thtml', 'login_req' => 'buttons/btn_login_req.thtml', 'btn_details' => 'buttons/btn_details.thtml')); $product->set_var(array('pi_url' => PAYPAL_URL, 'user_id' => $_USER['uid'], 'currency' => $_PP_CONF['currency'], 'breadcrumbs' => $breadcrumbs, 'search_text' => $srchitem, 'uikit' => $_PP_CONF['_is_uikit'] ? 'true' : '', 'tpl_ver' => $_PP_CONF['list_tpl_ver'])); if (!empty($cat_name)) { $product->set_var('title', $cat_name); $product->set_var('cat_desc', $cat_desc); $product->set_var('cat_img_url', $cat_img_url); } else { $product->set_var('title', $LANG_PP['blocktitle']); } $product->set_var('sortby_options', $sortby_options); /*if ($sortdir == 'DESC') { $product->set_var('sortdir_desc_sel', ' selected="selected"'); } else { $product->set_var('sortdir_asc_sel', ' selected="selected"'); }*/ $product->set_var('sortby', $sortby); //$product->set_var('sortdir', $sortdir); $display .= $product->parse('', 'start'); // Create an empty product object $P = new Product(); if ($_PP_CONF['ena_ratings'] == 1) { $PP_ratedIds = RATING_getRatedIds('paypal'); } // Display each product $prodrows = 0; while ($A = DB_fetchArray($res, false)) { $prodrows++; $P->Read($A['id']); if ($_PP_CONF['ena_ratings'] == 1 && $P->rating_enabled == 1) { // can't rate from list page, messes with product links $static = true; $rating_box = RATING_ratingBar('paypal', $A['id'], $P->votes, $P->rating, $voted, 5, $static, 'sm'); $product->set_var('rating_bar', $rating_box); } else { $product->set_var('rating_bar', ''); } $pic_filename = DB_getItem($_TABLES['paypal.images'], 'filename', "product_id = '{$A['id']}'"); $product->set_var(array('id' => $A['id'], 'name' => htmlspecialchars($P->name), 'short_description' => htmlspecialchars(PLG_replacetags($P->short_description)), 'img_cell_width' => $_PP_CONF['max_thumb_size'] + 20, 'encrypted' => '', 'item_url' => COM_buildURL(PAYPAL_URL . '/detail.php?id=' . $A['id']), 'img_cell_width' => $_PP_CONF['max_thumb_size'] + 20, 'track_onhand' => $P->track_onhand ? 'true' : '', 'qty_onhand' => $P->onhand, 'has_discounts' => $P->hasDiscounts() ? 'true' : '', 'price' => $P->getPrice() > 0 ? $P->currency->Format($P->price) : '', 'sale_price' => $P->currency->Format($P->sale_price), 'on_sale' => $P->isOnSale() ? 'true' : '', 'small_pic' => $pic_filename ? PAYPAL_ImageUrl($pic_filename) : '', 'tpl_ver' => $_PP_CONF['list_tpl_ver'])); if ($isAdmin) { $product->set_var(array('is_admin' => 'true', 'pi_admin_url' => PAYPAL_ADMIN_URL, 'edit_icon' => "{$_CONF['layout_url']}/images/edit.{$_IMAGE_TYPE}")); } // FIXME: If a user purchased once with no expiration, this query // will not operate correctly /*$time = DB_getItem($_TABLES['paypal.purchases'], 'MAX(UNIX_TIMESTAMP(expiration))', "user_id = {$_USER['uid']} AND product_id ='{$A['id']}'"); */ $product->set_block('product', 'BtnBlock', 'Btn'); if (!$P->hasAttributes()) { // Buttons only show in the list if there are no options to select $buttons = $P->PurchaseLinks(); foreach ($buttons as $name => $html) { $product->set_var('button', $html); $product->parse('Btn', 'BtnBlock', true); } } else { if ($_PP_CONF['ena_cart']) { // If the product has attributes, then the cart must be // enabled to allow purchasing $button = $product->parse('', 'btn_details') . ' '; $product->set_var('button', $button); $product->parse('Btn', 'BtnBlock', true); } } $display .= $product->parse('', 'product'); $product->clear_var('Btn'); } // Get products from plugins. // For now, this hack shows plugins only on the first page, since // they're not included in the page calculation. if ($page == 1 && empty($cat_list)) { // Get the currency class for formatting prices USES_paypal_class_currency(); $Cur = new ppCurrency($_PP_CONF['currency']); $product->clear_var('rating_bar'); // no ratings for plugins (yet) foreach ($_PLUGINS as $pi_name) { $status = LGLIB_invokeService($pi_name, 'getproducts', array(), $plugin_data, $svc_msg); if ($status != PLG_RET_OK || empty($plugin_data)) { continue; } foreach ($plugin_data as $A) { // Reset button values $buttons = ''; $product->set_var(array('id' => $A['id'], 'name' => $A['name'], 'short_description' => $A['short_description'], 'display' => '; display: none', 'small_pic' => '', 'encrypted' => '', 'item_url' => $A['url'], 'track_onhand' => '', 'small_pic' => !empty($A['image']) ? PAYPAL_ImageUrl($A['image']) : '')); if ($A['price'] > 0) { $product->set_var('price', $Cur->Format($A['price'])); } else { $product->clear_var('price'); } if ($A['price'] > 0 && $_USER['uid'] == 1 && !$_PP_CONF['anon_buy']) { $buttons .= $product->set_var('', 'login_req') . ' '; } elseif ($A['prod_type'] > PP_PROD_PHYSICAL && $A['price'] == 0) { // Free items or items purchases and not expired, download. $buttons .= $product->set_var('', 'download') . ' '; } elseif (is_array($A['buttons'])) { // Buttons for everyone else $product->set_block('product', 'BtnBlock', 'Btn'); foreach ($A['buttons'] as $type => $html) { $product->set_var('button', $html); $product->parse('Btn', 'BtnBlock', true); } } //$product->set_var('buttons', $buttons); $display .= $product->parse('', 'product'); $product->clear_var('Btn'); $prodrows++; } // foreach plugin_data } // foreach $_PLUGINS } // if page == 1 if ($catrows == 0 && COM_isAnonUser()) { $product->set_var('anon_and_empty', 'true'); } $pagenav_args = empty($pagenav_args) ? '' : '?' . implode('&', $pagenav_args); // Display pagination if (isset($_PP_CONF['prod_per_page']) && $_PP_CONF['prod_per_page'] > 0 && $count > $_PP_CONF['prod_per_page']) { $product->set_var('pagination', COM_printPageNavigation(PAYPAL_URL . '/index.php' . $pagenav_args, $page, ceil($count / $_PP_CONF['prod_per_page']))); } else { $product->set_var('pagination', ''); } $display .= $product->parse('', 'end'); return $display; }