• [Snippet] && [Module] Корзина заказов и админка#

  • Serg24 Reply #1, 4 years, 2 months ago

    Reply
    Уважаемые соплеменники
    Решил для личных нужд написать сниппет для создания корзины заказов. Обычную корзину, которая собирает данные о выбранных пользователем товарах, подсчете стоимости и отправке заказа на мыло ему и админу (без оплаты).

    Вышла новая версия модуля v4.1 beta. Обновлено 4.03.10
    Версия в стадии beta, поскольку внесено много новых возможностей и необходимо тестирование и доработки. Но вы можете смело использовать ее в ваших проектах, поскольку она наследовала уже проверенные временем наработки предыдущей версии.

    Полный список изменений читайте в документации. Но вот некоторые:

    1) Добавлена возможность манипулировать ценами товаров. Если вам нужно менять цену товара в зависимости от количества единиц заказанного товара, то у вас есть легкий способ это осуществить.

    Рассмотрим пример. Представьте, что у вас есть товар, у которого цена зависит от количества заказанных единиц. Например, если заказать от 1 до 5 штук, то цена товара 100 руб, если от 6 до 10 - то цена 90, а в остальных случаях 80 руб. Чтобы это реализовать, в поле ЦЕНА, в ТВ price вместо обычной цены достаточно указать простую формулу:

    1-5==100||6-10==90||80
    И цена товара динамически изменится.

    2) Добавлена возможность задавать дополнительные параметры товара: цвет, размер и т.д. При этом каждый параметр может определенным образом влиять на общую стоимость товара. Причем не только приплюсовываться к стоимости, а и отниматься и даже умножаться. Т.е. наподобие такого: Сумма = стоимость + param1 + param2 - param3.

    3) Сделана шаблонизация корзины и инфоблока.
    Более полный список изменений читайте в документации.

    Внимание. Я спешил выложить эту версию, поэтому в спешке мог что-то упустить в документации или в самих файлах. Буду очень благодарен за подсказки и найденные ошибки.

    Запущен в работу багтрекер. Он лежит по адресу http://tsv.org.ua/bugs/ Теперь все найденные ошибки, пожелания и предложения просьба направлять туда. Благодаря этому будет удобный учет ошибок и можно легко следить за ходом разработки.
    Последняя версия 4.1 beta, Скачать можно по ссылке http://letitbit.net/download/4883.443c38a5a29fc3be0b56d8a25/shop_4.1_beta.rar.html Ссылка на скачивание 4.0 beta: http://letitbit.net/download/7898.703f8761fd7c0b5e8335011cc/shop_4.0_beta.zip.html Предыдущая стабильная версия 3.2.2 http://letitbit.net/download/f19ce212e3/shop_v3.2.2.zip.html


  • AKots Reply #2, 4 years, 2 months ago

    Reply
    Мне кажется, лучше сначала выбрать какой-то имеющийся вариант за основу, а потом обсудить, что в нем надо исправить. Разрабатывать с нуля, я думаю, вряд ли нужно.


  • Serg24 Reply #3, 4 years, 2 months ago

    Reply
    В принципе, да. С нуля разрабатывать может и не нужно, хотя ковырять чужой код особо нету удовольствия. Хотя у меня есть 2 варианта неплохой корзины. Можно попробоватьее переделать под МОДх. Кому интересно, вылаживаю их здесь.

    Первый вариант, взять за основу сниппет из Этомите.

    ###########################################################################################################
    ##	SNIPPET: etoBasketV1.2											
    ##	DATE: 16/9/07												
    ## 	BY:  Cris D for Etomite CMS									
    ##	USE: Creates multiple item shopping page that allows users to purchase 				
    ##	items through paypal											
    ##														
    ##	LIMITATIONS: Due to the complex and changing field of on-line shopping, this snippet			
    ##	is designed as a base to start from and must be cusomised for individual use.	
    ##	Individual circumstances change dramatically, therefore only assistance with the snippet code logic	
    ##	will be offered in the etomite forums. For paypal assistance, please see paypal.com.			
    ##											
    ##	INSTALLATION INSTRUCTIONS: Copy and paste this code into your snippet library.				
    ##	Change the items requiring configuration.  Save it as etoBasket.	
    ##	Call the snippet in a page [!etoBasket!] and start entering your items for sale.			
    ##													
    ##	SECURITY and LOGGING IN: If you will need to have authenticate_visitor on your site to log in and
    ##	enter data or place a snippet call ?permission=1 to temporarily override the authentication.		
    ##														
    ##	MORE: More documentation can be found in the etomite forum, snippet library / etoBasket.		
    ##	CREDITS: robsta for the initial paypal snippet, Ralph and Dean for Etomite!	
    ##      UPDATES: 2007/11/17 Fixed some minor validation issues
    #############################################################################################################
    
    ########## CONFIGURE THIS SNIPPET ##################
    //Set the default folder for pictures (this can be overwritten on individual items if required)
    $default_pic_folder=isset($default_pic_folder) ? $default_pic_folder:"assets/images/";//set the the default image folder
    //set the table name (allows mutliple installations).
    $tableName="etobasket";
    //$paypalChunk=""; Optional, set the name of the chunk you would like to use to display the items.
    //Why not copy and paste the InternalTemplate as a new chunk and play with it.  
    //If it doesn't work, simply clear this field  to revert to the original one.
    $paypalChunk="";
    
    ######## PAYPAL VARIABLES #############
    //An explaination of these variables can be seen at
    //https://www.paypal.com/IntegrationCenter/ic_std-variable-reference.html#HTMLVariablesforShoppingCarts
    
    
    // Email account to pay the money to.
    $PAYPAL_BUSINESS= "yourname@domain.com";
    $PAYPAL_IMAGE = "https://www.paypal.com/en_GB/i/btn/x-click-but22.gif";
               //Default payment button image
    $PAYPAL_IMAGE_ALT = "Make payments with PayPal - its fast, free and secure!";     //Default payment button mouseover text
    $PAYPAL_ADD = "1";                      //default number of items
    $PAYPAL_CMD = "_cart";			//paypal requirement
    $PAYPAL_PAGE_STYLE = "Primary";		//set to the cart style in your account
    $PAYPAL_RETURN_PAGE_ID = "0";		//id of page returned to on completion of transaction                                 
    $ref="ID";				//this separates the item name and the id reference number.  Use...Ref, ID, RE, Code etc.
    $PAYPAL_NO_NOTE = "1";			//1=Request customers to leave a note on purchase 0= no notes
    $PAYPAL_CURRENCY_CODE = "AUD";       	// currency setting
    $PAYPAL_LC = "AUS";                  	// currency setting
    $currencyIcon="$";			// currency setting (optional- can confuse international customers and paypal)
    $ViewCart="View Cart";                  // Set for the text (or img src to the button to use)to show as the link
    
    //some inline styling for an item wrapping div to get immediate results.  
    //This is not used if an external chunk ($payPalChunk) is being used (external chunk and CSS preferred).
    $inlineStyling='float:left; 
    		display:block; 
    		padding:20px; 
    		margin:10px; 
    		width:100%; 
    		background:#ccffff url(templates/AlexisProRedux/images/section.jpg); 
    		margin:2px; 
    		padding:2px;';
    
    
    ########### END SNIPPET CONFIGURATION  ###################
    ##     The rest should take care of itself...		##
    ######### Automatic Snippet variables ####################
    $host = 	$GLOBALS['database_server']; 
    $user = 	$GLOBALS['database_user']; 
    $pass = 	$GLOBALS['database_password']; 
    $dbase=    trim($GLOBALS['dbase'],'`');//database
    $baseURL=	$GLOBALS['www_base_path'];
    $etoPrefix=$GLOBALS['table_prefix'];//automatically set to the prefix of the etomite installation.
    $userlog=$etomite->userLoggedIn();
    $page=$etomite->documentIdentifier;
    $permission=0;
    $permission=$etomite->checkPermissions();
    $tableCheck=$etomite->extTableExists($host, $user, $pass, $dbase, $table=$etoPrefix.$tableName);
    
    $extractedId=explode(':',$_GET['record']);
    
    ####### SNIPPET TEMPLATES #############
    //Copy and paste Internaltemplate to use as a start for an external chunk.
    //This is the main formatting of the items that the public see/
    
    //Create a "Proceed to checkout" button.
    $ViewCart=
    <<<END
    <a href="https://www.paypal.com/cart/display=1&business=$PAYPAL_BUSINESS&"
     target="paypal">$ViewCart</a>
    END;
    
    
    $InternalTemplate=
    <<<END
    <div class='ppal_item' style='$inlineStyling'>
    <img src='{baseURL}{pic_folder}{filename}' alt='{filename}'/><br />
    <div class='ppal_text' style='float:left;'>Item: {item} <br /> Description: {text}<br />Price:{currency_icon}{pp_currency_code}{price}</div>
    <div style='float:right;'><form action='https://www.paypal.com/cgi-bin/webscr'
     target="paypal" method='post'>
    <input type='image' src='{pp_image}' name='submit' alt='{pp_image_alt}' />
    <input type='hidden' name='add' value='{pp_add}' />
    <input type='hidden' name='cmd' value='{pp_cmd}' />
    <input type='hidden' name='business' value='{pp_business}' />
    <input type='hidden' name='item_name' value='{item}{ref}: {id}' />
    <input type='hidden' name='amount' value='{price}' />
    <input type='hidden' name='page_style' value='{pp_page_style}' />
    <input type='hidden' name='return' value='{baseURL}index.php?id={returnPage}' />
    <input type='hidden' name='no_note' value='{pp_no_note}' />
    <input type='hidden' name='currency_code' value='{pp_currency_code}' />
    <input type='hidden' name='lc' value='{pp_lc}' />
    </form></div>
    </div>
    END;
    
    //formNew creates a blank form for new records with some default values already added.
    $formNew.="<p> </p><h1>Add New Item</h1>";
    $formNew.=
    <<<END
    <form action="" name="etoBasket" method="POST" />
    <input type="hidden" name="prefix" value="bskt_" />
    <input type="hidden" name="into" value="$tableName" />
    <input type="hidden" name="bskt_id" value="" />
    <label for="item">Item: </label>
    	<input type="text" name="bskt_item" id="item" value="" /><br />
    <label for="description">Description:</label>
    	<textarea name="bskt_description" id="description" rows="3" cols="40"></textarea><br />
    <label for="price">Price:$PAYPAL_CURRENCY_CODE $currencyIcon</label>
    	<input type="text" name="bskt_price" id="price" value="" /><br />
    <label for="pic_folder">Pic URL:</label>
    	<input type="text" name="bskt_pic_folder" id="pic_folder" value="$default_pic_folder" />
    <label for="filename">Pic Filename:</label>
    	<input type="text" name="bskt_filename" id="filename" value="defaultimage.jpg"/><br />
    <label for="onPage">Show on page:</label>
    	<input type="text" name="bskt_onPage" id="onPage" value="$page"/>This page id is: $page<br />
    <label for="active">Active?</label>
    	<input type="text" name="bskt_active" id="active" value="$active"/>Set to "1" to show on page<br />
    <input type="submit" name="sub" value="Send it off" />
    </form><p> </p>
    END;
    
    ######## END SNIPPET TEMPLATES ########
    
    
    ########### Define Snippet Function #####################
    if (!function_exists('stripslashes_deep')){
    
    function stripslashes_deep($value){
        $value = is_array($value) ?
                    array_map('stripslashes_deep', $value) :
                    stripslashes($value);
    
        return $value;
    		}
    
    	}
    #########################################################
    //Try to get external chunk 
    $chunkName=$etomite->getChunk($paypalChunk);
    //or use internal chunk if none provided.
    if(empty($chunkName))$chunkName=$InternalTemplate;
    
    //If logged in, show managers forms...
    if($permission==1){
    		//check if table exists, if not make it
    		if($tableCheck!=1){
    			$sql = 'CREATE TABLE `'.$etoPrefix.$tableName.'` ('
            		. ' `id` INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, '
            		. ' `item` VARCHAR(100) NULL, '
            		. ' `description` VARCHAR(500) NULL, '
            		. ' `price` VARCHAR(10) NULL, '
            		. ' `pic_folder` VARCHAR(50) NULL, '
            		. ' `filename` VARCHAR(20) NULL, '
            		. ' `onPage` INT( 10 ) NULL, '
            		. ' `active` ENUM(\'1\',\'0\') NOT NULL DEFAULT \'1\''
            		. ' )'
            		. ' ENGINE = myisam;';
    			$etomite->dbQuery($sql);
    			}
    	//delete records if requested to
    	if(isset($_POST['delete']) ){
    	//unless you change your mind!
    	if(!isset($_POST['keep'])){
    		$id=isset($id)? $id:$_POST['bskt_id'];
    	$confirmDelete="<form action='' method='post'>\n
    			<input type='hidden' name='delete'>\n
    			<input type='hidden' name='bskt_id' value='$id'>\n
    			<input type='submit' name='confirm' value='DELETE'>\n
    			<input type='submit' name='keep' value='NO'>\n";
    	if(!$_POST['confirm']){return "Delete record...".$id.": ".$_POST['bskt_item']."?<br />".$confirmDelete;}
    		if(isset($_POST['confirm'])){
    			$sql.="DELETE FROM `".$etoPrefix."".$tableName."` WHERE `".$etoPrefix."".$tableName."`.`id` =".$id." LIMIT 1";
    			$con=$etomite->dbQuery($sql);
    			unset($id);
    			}
    		}
    	}
    	//has new or changed form data been sent off? If so save it.
    	if(isset($_POST['sub'])){
    
    		$table=$_POST['into'];
    
    		$fields=array();
    
    		$fields = $etomite->getFormVars($method="POST", $prefix="bskt_", $trim=1, $REQUEST_METHOD);
    
    		foreach($fields as $key=>$value) {
    			$fields[$key] = addslashes($value);
    			}
    
    		if($fields['id']=="" OR $fields['id']=="{id}") {
    
    		$rs = $etomite->putIntTableRow($fields, $table, $addPrefix=true);
    		} else {
    		$rs = $etomite->updIntTableRows($fields, $table, $where="id=".$fields['id'], $sort="", $dir="ASC",$limit="",
    		$addPrefix=true);
    		}
    	}//closing bracket for if save details have been sent
    
    //get all records to populate the select drop down box.
    	$rsARaw=$etomite->getIntTableRows($fields="*",$from=$tableName,$where='',$sort='',$dir='',$limit="9999",
    	$push=true,$addPrefix=true);
    	
    	$rsA=stripslashes_deep($rsARaw);
    	$counta=count($rsARaw);
    //Create drop down select box to get existing records to edit.
    	$select.="<br /><form action=\"".$etomite->makeURL($page,'','')."\" method=\"get\">\n";
    	$select.="<input type=\"hidden\" name=\"id\" value=\"$page\">\n";
    	$select.="<label for=\"select\">Choose record:</label><select name=\"record\" id=\"select\">\n";
    	if($counta>1){
    		foreach ($rsA as $i){
    			$select.="<option label='".$i['id']."'";
    			if($extractedId[0]==$i['id']){$select.=" selected";}
    				$select.=">".$i['id'].": ".$i['item']."</option>\n";
    			}
    	}else{
    	$select.="<option label='".$rsA[0]['id']."' selected>".$rsA[0]['id'].": ".$rsA['item']."</option>\n";
    	}
    	$select.="</select><input type=\"submit\" name=\"recsub\" value=\"Get record\" /></form>";
    
    //If select form is sent to collect a record get the record to show
    	if(!empty($extractedId[0])){$where="id=".$extractedId[0];}else{$where='';}
    
    	$rsBRaw=$etomite->getIntTableRows($fields="*",$from=$tableName,$where,$sort,$dir,$limit="9999",
    	$push=true,$addPrefix=true);
    	$rsB=stripslashes_deep($rsBRaw);
    //Pre-fill in the forms with existing item data...
    	$countb=count($rsBRaw);
    	for($i=0;$i<$countb;$i++){
    		$id		=$rsB[$i]['id'];
    		$item		=$rsB[$i]['item'];
    		$description	=$rsB[$i]['description'];
    		$price		=$rsB[$i]['price'];
    		$pic_folder	=$rsB[$i]['pic_folder'];
    		$filename	=$rsB[$i]['filename'];
    		$onPage		=$rsB[$i]['onPage'];
    		$active		=$rsB[$i]['active'];
    
    //this form is the one that contains the existing records and is repeated for each item
    
    $form.="<img src='$baseURL".$pic_folder.$filename."' />";
    $form.=
    <<<END
    <form action="" name="etoBasket" method="POST" />
    <input type="hidden" name="prefix" value="bskt_" />
    <input type="hidden" name="into" value="$tableName" />
    <input type="hidden" name="bskt_id" value="$id" />
    <label for="item">Item: </label>
    	<input type="text" name="bskt_item" id="item" value="$item"/><br />
    <label for="description">Description:</label>
    	<textarea name="bskt_description" id="description" rows="3" cols="40">$description</textarea><br />
    <label for="price">Price:$PAYPAL_CURRENCY_CODE $currencyIcon</label>
    	<input type="text" name="bskt_price" id="price" value="$price" /><br />
    <label for="pic_folder">Pic URL:</label>
    	<input type="text" name="bskt_pic_folder" id="pic_folder" value="$pic_folder" />
    <label for="filename">Pic Filename:</label>
    	<input type="text" name="bskt_filename" id="filename" value="$filename"/><br />
    <label for="onPage">Show on page:</label>
    	<input type="text" name="bskt_onPage" id="onPage" value="$onPage" />This page id is: $page<br />
    <label for="active">Active?</label>
    	<input type="text" name="bskt_active" id="active" value="$active" />Set to "1" to show on page <br />
    	<input type="submit" name="delete" value="Delete">
    	<input type="submit" name="sub" value="Save">
    </form>
    END;
    
    }//closing bracket for generating pre-filled forms
    	//if a record has not been requested, put a blank form at the top of the page.
    	if(!$_GET['recsub']){
    		return $select.$formNew.$form;
    	}else{
    	//else put the requested record at the top and a blank one at the bottom.
    		return $select.$form.$formNew;
    	}
    }//closing bracket for showing managers forms.
    
    ##########################################################################
    ##	      If not logged in, then show the public stuff...		##
    ##########################################################################
    //Display item selection based on page id  set or default: show all
    $showSelection="onPage=".$page." AND active=1";
    $where=$showSelection;
    
    $rsCRaw=$etomite->getIntTableRows(
    $fields="*",$from=$tableName,$where,$sort,$dir,$limit="9999",$push=true,$addPrefix=true);
    
    $rsC=stripslashes_deep($rsCRaw);
    
    $countC=count($rsCRaw);
    for($i=0; $i<$countC; $i++){
    	$PAYPAL_INFO[]=array(
    	'item'		=>	$rsC[$i]['item'],
    	'price'		=>	$rsC[$i]['price'],
    	'text'		=>	$rsC[$i]['description'],
    	'id'		=>	$rsC[$i]['id'],
    	'pic_folder'	=>	$rsC[$i]['pic_folder'],
    	'filename'	=>	$rsC[$i]['filename'],
    	'active'	=>	$rsC[$i]['active'],
    	'pp_business'	=>	$PAYPAL_BUSINESS,
    	'pp_image'	=>	$PAYPAL_IMAGE,
    	'pp_image_alt'	=>	$PAYPAL_IMAGE_ALT,
    	'pp_add'	=>	$PAYPAL_ADD,
    	'pp_cmd'	=>	$PAYPAL_CMD,
    	'pp_page_style'	=>	$PAYPAL_PAGE_STYLE,
    	'currency_icon'	=>	$currencyIcon,
    	'pp_currency_code'=>	$PAYPAL_CURRENCY_CODE,
    	'pp_no_note'	=>	$PAYPAL_NO_NOTE,
    	'pp_lc'		=>	$PAYPAL_LC,
    	'baseURL'	=>	$baseURL,
    	'ref'		=>	$ref,
    	'returnPage'	=>	$PAYPAL_RETURN_PAGE_ID,
    	);
    }
    //output the data with the template...
    
    $output.=$etomite->mergeCodeVariables(
    $content=$chunkName,
    $rs=$PAYPAL_INFO,
    $prefix="{",$suffix="}",
    $oddStyle="class=\"pp_odd\"",$evenStyle="class=\"pp_even\"",//set these in your css to control how it looks
    $tag="div"
    );
    
    return $ViewCart.$output.$ViewCart;


    пробовал его в работе, выдает белую страницу. Видимо, где-то ошибка или несовместимость с МОДх. Просто небыло возможности разбираться.

    Второй вариант в приложенном архиве. Там считываются поля методом ПОСТ, потом эти данные записываются в текстовый файл. после чего идет дальнейшая обработка. В принципе, скриптик неплохой, но надо бы перевести на БД и доработать.

    Третий вариант - просто сделать все с нуля. о чем предлагал выше.

    Теперь кому интересно, можете поковырять приложенные мной варианты и сказать ваши идеи. Есть ли смысл делать на их основе или же сделать все свое - не сильно навороченно но тем не менее вложить нужный функционал уже с самого начала.

    Жду идей


  • Serg24 Reply #4, 4 years, 1 month ago

    Reply
    Уважаемые господа!
    Спешу обрадовать вас. Я сделал на основе найденного мной скрипта прекрасную корзину с возможностью добавления товаров, подсчетом и выводом результатов. Прерасная интеграция в шаблоны с ДИТТО.

    На днях выложу готовые сниппеты + документацию. которые начну писать завтра.


  • webboy Reply #5, 4 years, 1 month ago

    Reply
    Неплохая идея заложена в ShopX, к нему бы еще добавить возможности из gCart,
    переработав их, можно сделать мне кажется достаточно гибкую и функциональную корзину.



  • Seruy Reply #6, 4 years, 1 month ago

    Reply
    Quote from: Serg24 at Mar 26, 2008, 04:42 PM
    На днях выложу готовые сниппеты + документацию. которые начну писать завтра.
    Это ооочень хорошо! Заранее огромное спасибо!
    Если, что, могу помочь с документацией. Так как в ПХП особо не силен, а с модиксом пару месяцев. Но есть огромное желани работать в этом направлении.


  • Serg24 Reply #7, 4 years, 1 month ago

    Reply
    Первые испытания прошли успешно установка на МОДх прошла буквально за 5 мин., работает как часы. Внешний вид корзины и всего остльного элементарно, настройка самой корзины - всего в 1 файле, больше 20 языковых локализаций, в т.ч. и русский. Только немного подождите, все выложу, т.к. у меня много работы и нужно сниппеты привести в порядок. Как только все сделаю, сразу выложу


  • catsmeetman Reply #8, 4 years, 1 month ago

    Reply
    Ну наконец-то дождались, поскорей бы уже произошло "явление корзины народу"


  • afizikov Reply #9, 4 years, 1 month ago

    Reply
    В предвкушении


  • Serg24 Reply #10, 4 years, 1 month ago

    Reply
    сообщаю о стадии работы. Доделываю документацию. Сегодня-завтра выложу.