Новости Joomla

Как тестировать Joomla PHP-разработчику? Компонент Patch tester.

👩‍💻 Как тестировать Joomla PHP-разработчику? Компонент Patch tester.Joomla - open source PHP-фреймворк с готовой админкой. Его основная разработка ведётся на GitHub. Для того, чтобы международному сообществу разработчиков было удобнее тестировать Pull Requests был создан компонент Patch Tester, который позволяет "накатить" на текущую установку Joomla именно те изменения, которые необходимо протестировать. На стороне инфраструктуры Joomla для каждого PR собираются готовые пакеты, в которых находится ядро + предложенные изменения. В каждом PR обычно находятся инструкции по тестированию: куда зайти, что нажать, ожидаемый результат. Тестировщики могут предположить дополнительные сценарии, исходя из своего опыта и найти баги, о которых сообщить разработчику. Или не найти, и тогда улучшение или исправление ошибки быстрее войдёт в ядро Joomla. Напомню, что для того, чтобы PR вошёл в ядро Joomla нужны минимум 2 положительных теста от 2 участников сообщества, кроме автора. Видео на YouTubeВидео на VK ВидеоВидео на RuTubeКомпонент на GitHub https://github.com/joomla-extensions/patchtester@joomlafeed#joomla #php #webdev #community

Вышел релиз Revo PageBuilder Toolkit for YOOtheme Pro 1.6

Вышел релиз Revo PageBuilder Toolkit for YOOtheme Pro 1.6.2PageBuilder Toolkit - это специализированный плагин для конструктора страниц Yootheme Pro, содержит набор различных утилит для ускорения процесса работы и отладки макета, множественные улучшения в интерфейсе, включая поддержку dark mode, подсказки, быстрая смена разрешения в окне просмотра и много чего еще.v.1.6.2 Что нового?- Индикатор статусов: теперь не просто показывает состояние запросов, но и делает автоматические попытки их отправки при кратковременных сбоях в сети, а если это не помогло, то переводит конструктор в ручной режим, что позволяет сохранит макет и настройки темы прежде чем вы потеряете все, что было сделано с момента последнего сохранения- Подсветка ошибок в макете: плагин анализирует код страницы и может автоматически подсвечивать data атрибуты с кучей мусора, которые попадают в код страницы при копипасте из Figma в TinyMCE (пригодится для старых макетов, в текущей работе плагин сам очищает код мусора). Также есть подсветка семантических ошибок сборки - дубли h1 тега на странице и вложенных друг в друга заголовков.- Улучшена поддержка будущего релиза Yootheme Pro 5 и редактора CodeMirror 6Плагин для русскоязычных пользователей доступен в каталоге расширений SovMart и распространяется за символическую плату (100р). Разработчики Joomla расширений и партнеры автора могут получить плагин бесплатно.Для работы плагина необходим конструктор страниц Yootheme Pro.Разработчик плагина - участник нашего сообщества Александр Судьбинов (@alexrevo), член официальной группы поддержки Yootheme Pro. Страница расширенияОписание на сайте автора@joomlafeed#joomla #yootheme

0 Пользователей и 1 Гость просматривают эту тему.
  • 2 Ответов
  • 3039 Просмотров
*

artMelnikov

  • Захожу иногда
  • 57
  • 3 / 0
Добрый день!

Есть интересная идея, готового решения которой я не нашел и решил сделать сам и рассказать другим. Так как знаний не хватает, прошу помощи у Вас, дорогие друзья:

Задача следующая:
1.   [РЕШЕНО] В Интернет-магазине всем зарегистрированным по умолчанию предоставляется скидка 5%.
2.   [РЕШЕНО] Но есть группа товаров, на которую скидки быть не может (так как накрутки на него нет).
3.   [РЕШЕНО] Есть пара десятков постоянных покупателей, у которых должна быть скидка 10%
4.   [РЕШЕНО] В списке товаров должна быть стандартная цена без скидки, а скидка должна быть видна только в корзине (для того чтоб человек видел нормальные цены как в физическом магазине, а при оформлении видел выгоду от использования Интернет-магазина).
5.   [НУЖНА ПОМОЩЬ] Во время оформления заказа должна быть возможность выбора: «Использовать скидку» и «Не использовать скидку» (это нужно для тех пользователей, которые хотят, чтоб фирма оплатила без скидки, а на сумму скидки получить откат )) )

Группами пользователей всё это не решить, поэтому решение одно – купоны.

Решение:
1.   Делаем, чтобы новому пользователю давалась скидка 5%
      1.1.   Создал 2 купона с кодами «5» и «10» и присвоил им постоянную скидку 5% и 10%.
      1.2.   Создал в разделе «Управление полями, заполняемыми пользователем» поле с названием: «vm_kupon», опубликовал его и показал только в разделе управления учетной записью (чтоб админ мог менять скидку с 5% на 10%). Это поле должно быть видно только из админки, но его видит и пользователь. С этим разберусь чуть позже. Решение есть.
      1.3.   Сделал чтобы при регистрации в это поле по умолчанию прописывалось значение 5 (что равно коду 5% купона.
2.   Это решается использованием компонента AwoCoupon Pro (этот компонент расширяет возможности использования купонов, в том числе и позволяет выбрать категорию товаров на которую не будет действовать купон).
3.   Золотым пользователям просто можно вручную поменять значение поля «vm_kupon» на 10).
4.   Так и будет, поскольку мы делаем скидку купонами, а не группами пользователей.
5.   Вот с этим пунктом у меня полная засада. Редактировать подозреваю нужно
components\com_virtuemart\themes\default\templates\common\couponField.tpl.php
и возможно
administrator\components\com_virtuemart\classes\ps_coupon.php
      5.1.   Во-первых, надо добиться того, чтоб после ввода купона поле ввода не исчезало.
      5.2.   Во-вторых, сделать, чтоб в поле ввода купона подставлялось значение из поля «vm_kupon» пользователя.
      5.3.   В-третьих, заменить поле ввода на radiobutton или checkbox (чтоб можно было включать и выключать купон)


Прошу Вас о помощи!

На всякий случай прикладываю коды файлов:
couponField.tpl.php
Код
<?php 
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/**
*
* @version $Id:couponField.tpl.php 431 2006-10-17 21:55:46 +0200 (Di, 17 Okt 2006) soeren_nb $
* @package VirtueMart
* @subpackage themes
* @copyright Copyright (C) 2008 soeren - All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
* @author Erich Vinson
* http://virtuemart.net
*/

mm_showMyFileName( __FILE__ );

?>

<table width="100%">
<tr class="sectiontableentry1">
<td width="100%">
<?php
if (@$_SESSION['invalid_coupon'] == true) {
echo "<strong>" . $VM_LANG->_('PHPSHOP_COUPON_CODE_INVALID'). "</strong><br />";
}
if( !empty($GLOBALS['coupon_error']) ) {
echo vmGet($GLOBALS, 'coupon_error', '')."<br />";
}
// If you have a coupon code, please enter it here:
echo $VM_LANG->_('PHPSHOP_COUPON_ENTER_HERE'). '<br />';
?>  
   <form action="<?php echo $mm_action_url . basename( $_SERVER['PHP_SELF'])?>" method="post" onsubmit="return checkCouponField(this);">
<input type="text" name="coupon_code" id="coupon_code" width="10" maxlength="30" class="inputbox" />
<input type="hidden" name="Itemid" value="<?php echo @intval($_REQUEST['Itemid'])?>" />
<input type="hidden" name="do_coupon" value="yes" />
<input type="hidden" name="option" value="<?php echo $option ?>" />
<input type="hidden" name="page" value="<?php echo $page ?>" />
<input type="submit" value="<?php echo $VM_LANG->_('PHPSHOP_COUPON_SUBMIT_BUTTON')?>" class="button" />
<?php
# awocoupon_code START ===============================================================
echo ' <input type="hidden" name="ship_to_info_id" value="'.vmGet( $_REQUEST, 'ship_to_info_id').'" />
<input type="hidden" name="shipping_rate_id" value="'.urldecode(vmGet( $_REQUEST, "shipping_rate_id", null )).'" />
<input type="hidden" name="payment_method_id" value="'.vmGet( $_REQUEST, 'payment_method_id').'" />';
$current_stage = ps_checkout::get_current_stage();
$checkout_steps = ps_checkout::get_checkout_steps();
if(!empty($checkout_steps[$current_stage-1])) {
foreach( $checkout_steps[$current_stage-1] as $this_step ) echo '<input type="hidden" name="checkout_this_step[]" value="'.$this_step.'" />';
}
# awocoupon_code END =================================================================
?>

</form>
</td>
</tr>
</table>
<script type="text/javascript">
function checkCouponField(form) {
if(form.coupon_code.value == '') {
new Effect.Highlight('coupon_code');
return false;
}
return true;
}
</script>

ps_coupon.php
Код
<?php
if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
/**
*
* @version $Id: ps_coupon.php 2600 2010-10-22 20:41:15Z zanardi $
* @package VirtueMart
* @subpackage classes
* @copyright Copyright (C) 2004-2009 soeren - All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* VirtueMart is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.
*
* http://virtuemart.net
*/

/**
 * Class Code for coupon codes
 * The author would like to thank Digitally Imported (www.di.fm) for good music to code to
 *
 *
 * CHANGELOG:
 *
 * v 1.0: Initial Release (28-NOV-2004) - Erich
*/

class vm_ps_coupon {

    function validate_add( &$d ) {
        global $VM_LANG, $vmLogger;
        /* init the database */
        $coupon_db = new ps_DB;
        $valid = true;
        
        /* make sure the coupon_code does not exist */
        $q = "SELECT coupon_code FROM #__{vm}_coupons WHERE coupon_code = '".$coupon_db->getEscaped($d['coupon_code'])."' ";
        $coupon_db->query($q);
        if ($coupon_db->next_record()) {
            $vmLogger->err( $VM_LANG->_('PHPSHOP_COUPON_CODE_EXISTS',false) );
            $valid = false;
        }
        if( empty( $d['coupon_value'] ) || empty( $d['coupon_code'] )) {
            $vmLogger->warning( $VM_LANG->_('PHPSHOP_COUPON_COMPLETE_ALL_FIELDS',false) );
            $valid = false;
        }
        if( !is_numeric( $d['coupon_value'] )) {
            $vmLogger->err( $VM_LANG->_('PHPSHOP_COUPON_VALUE_NOT_NUMBER',false) );
            $valid = false;
        }
        return $valid;
        
    }
    function validate_update( &$d ) {
        global $VM_LANG, $vmLogger;
        /* init the database */
        $coupon_db = new ps_DB;
        $valid = true;
        
        /* make sure the coupon_code does not exist */
        $q = "SELECT coupon_code FROM #__{vm}_coupons WHERE coupon_code = '".$coupon_db->getEscaped($d['coupon_code'])."' AND coupon_id <> '".$d['coupon_id']."'";
        $coupon_db->query($q);
        if ($coupon_db->next_record()) {
            $vmLogger->err( $VM_LANG->_('PHPSHOP_COUPON_CODE_EXISTS',false) );
            $valid = false;
        }
        if( empty( $d['coupon_value'] ) || empty( $d['coupon_code'] )) {
            $vmLogger->err( $VM_LANG->_('PHPSHOP_COUPON_COMPLETE_ALL_FIELDS',false) );
            $valid = false;
        }
        if( !is_numeric( $d['coupon_value'] )) {
            $vmLogger->err( $VM_LANG->_('PHPSHOP_COUPON_VALUE_NOT_NUMBER',false) );
            $valid = false;
        }
        return $valid;
        
    }
    /* function to add a coupon coupon_code to the database */
    function add_coupon_code( &$d ) {
     global $vmLogger, $VM_LANG;
        $coupon_db = new ps_DB;

        if( !$this->validate_add( $d ) ) {
            return false;
        }
        $fields = array(
       'coupon_code' => vmGet($d,'coupon_code'),
       'percent_or_total' => strtolower($d['percent_or_total']) == 'percent' ? 'percent' : 'total',
       'coupon_type' => strtolower($d['coupon_type']) == 'gift' ? 'gift' : 'permanent',
       'coupon_value' => (float)$d['coupon_value']
       );
        $coupon_db->buildQuery( 'INSERT', '#__{vm}_coupons', $fields );
        if( $coupon_db->query() ) {
       $_REQUEST['coupon_id'] = $coupon_db->last_insert_id();
       $vmLogger->info($VM_LANG->_('VM_COUPON_ADDED'));
       return true;
        }
        return false;
    
    }
    
    
    /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
    
    /* function to update a coupon */
    function update_coupon( &$d ) {
       global $vmLogger, $VM_LANG;
        if( !$this->validate_update( $d ) ) {
            return false;
        }  
        /* init the database */
        $coupon_db = new ps_DB;
        
        $fields = array(
       'coupon_code' => vmGet($d,'coupon_code'),
       'percent_or_total' => strtolower($d['percent_or_total']) == 'percent' ? 'percent' : 'total',
       'coupon_type' => strtolower($d['coupon_type']) == 'gift' ? 'gift' : 'permanent',
       'coupon_value' => (float)$d['coupon_value']
       );
        $coupon_db->buildQuery( 'UPDATE', '#__{vm}_coupons', $fields, 'WHERE coupon_id = '.(int)$d['coupon_id'] );
        if( $coupon_db->query() ) {
       $_REQUEST['coupon_id'] = $coupon_db->last_insert_id();
       $vmLogger->info($VM_LANG->_('VM_COUPON_UPDATED'));
       return true;
        }
        return false;
    }
    
        
    /* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ */
    
    /* function to remove coupon coupon_code from the database */
    function remove_coupon_code( &$d ) {
        
        return require_once (JPATH_ADMINISTRATOR.DS."components".DS."com_awocoupon".DS."assets".DS."virtuemart".DS."ps_coupon_remove.php");
}
function remove_coupon_code_vm( &$d ) {
/* remove the coupon coupon_code */
        /* init the database */
        $coupon_db = new ps_DB;
if( is_array($d['coupon_id'] )) {
foreach( $d['coupon_id'] as $coupon ) {
$q = 'DELETE FROM #__{vm}_coupons WHERE coupon_id = '.(int)$coupon;
$coupon_db->query($q);
}
}
else {
$q = 'DELETE FROM #__{vm}_coupons WHERE coupon_id = '.(int)$d['coupon_id'];
$coupon_db->query($q);
}
        $_SESSION['coupon_discount'] =    0;
        $_SESSION['coupon_redeemed']   = false;
        
        return true;
    }
    
    
    /* function to process a coupon_code entered by a user */
    function process_coupon_code( $d ) {
        return require_once (JPATH_ADMINISTRATOR.DS."components".DS."com_awocoupon".DS."assets".DS."virtuemart".DS."ps_coupon_process.php");
}
function process_coupon_code_vm( $d ) {
global $VM_LANG, $vmLogger;
        /* init the database */
        $coupon_db = new ps_DB;
        
        /* we need some functions from the checkout module */
        require_once( CLASSPATH . "ps_checkout.php" );
        $checkout = new ps_checkout();
        if( empty( $d['total'])) {
         $totals = $checkout->calc_order_totals($d);
         $d['total'] = $totals['order_subtotal']
+ $totals['order_tax']
+ $totals['order_shipping']
+ $totals['order_shipping_tax']
- $totals['payment_discount'];
        }
        $d['coupon_code'] = trim(vmGet( $_REQUEST, 'coupon_code' ));
        $coupon_id = vmGet( $_SESSION, 'coupon_id', null );
        
        $q = 'SELECT coupon_id, coupon_code, percent_or_total, coupon_value, coupon_type FROM #__{vm}_coupons WHERE ';
        if( $coupon_id ) {
            /* the query to select the coupon coupon_code */
            $q .= 'coupon_id = '.intval($coupon_id);
        }
        else {
            /* the query to select the coupon coupon_code */
            $q .= 'coupon_code = \''.$coupon_db->getEscaped( $d['coupon_code'] ).'\'';
        }
        /* make the query */
        $coupon_db->query($q);
        
        /* see if we have any fields returned */
        if ($coupon_db->num_rows() > 0)
        {
            /* we have a record */
            
            /* see if we are calculating percent or dollar discount */
            if ($coupon_db->f("percent_or_total") == "percent")
            {
                /* percent */    
                //$subtotal = $checkout->calc_order_subtotal( $d );
                
                /* take the subtotal for calculation of the discount */
                //$_SESSION['coupon_discount'] = round( ($subtotal * $coupon_db->f("coupon_value") / 100), 2);
                 $coupon_value = round( ($d["total"] * $coupon_db->f("coupon_value") / 100), 2);
                
                 if( $d["total"] < $coupon_value ) {
                   $coupon_value = (float)$d['total'] +(float)$d['order_tax'] ;
                   $vmLogger->info( str_replace('{value}',$GLOBALS['CURRENCY_DISPLAY']->getFullValue( $coupon_value ),$VM_LANG->_('VM_COUPON_GREATER_TOTAL_SETTO')) );
                }
                 $_SESSION['coupon_discount'] = $coupon_value;
            }
            else
            {
            
             $coupon_value = $GLOBALS['CURRENCY']->convert( $coupon_db->f("coupon_value") );

                /* Total Amount */
                if( $d["total"] < $coupon_value ) {
                   $coupon_value = (float)$d['total'] +(float)$d['order_tax'] ;
                   $vmLogger->info( str_replace('{value}',$GLOBALS['CURRENCY_DISPLAY']->getFullValue( $coupon_value ),$VM_LANG->_('VM_COUPON_GREATER_TOTAL_SETTO')) );
                }
                $_SESSION['coupon_discount'] = $coupon_value;
                
            }
            
            /* mark this order as having used a coupon so people cant go and use coupons over and over */
            $_SESSION['coupon_redeemed'] = true;
            $_SESSION['coupon_id'] = $coupon_db->f("coupon_id");
            $_SESSION['coupon_code'] = $coupon_db->f("coupon_code");
            $_SESSION['coupon_type'] = $coupon_db->f("coupon_type");
                
            
        }
        else
        {
            /* no record, so coupon_code entered was not valid */
            $GLOBALS['coupon_error'] = $VM_LANG->_('PHPSHOP_COUPON_CODE_INVALID');
            return false;
            
        }
    
    }    
}
// Check if there is an extended class in the Themes and if it is allowed to use them
// If the class is called outside VirtueMart, we have to make sure to load the settings
// Thomas Kahl - Feb. 2009
if (!defined('VM_ALLOW_EXTENDED_CLASSES') && file_exists(dirname(__FILE__).'/../virtuemart.cfg.php')) {
include_once(dirname(__FILE__).'/../virtuemart.cfg.php');
}
// If settings are loaded, extended Classes are allowed and the class exisits...
if (defined('VM_ALLOW_EXTENDED_CLASSES') && defined('VM_THEMEPATH') && VM_ALLOW_EXTENDED_CLASSES && file_exists(VM_THEMEPATH.'user_class/'.basename(__FILE__))) {
// Load the theme-user_class as extended
include_once(VM_THEMEPATH.'user_class/'.basename(__FILE__));
} else {
// Otherwise we have to use the original classname to extend the core-class
class ps_coupon extends vm_ps_coupon {}
}  
?>
« Последнее редактирование: 15.09.2011, 20:43:56 от artMelnikov »
*

AnatolyW

  • Осваиваюсь на форуме
  • 12
  • 0 / 0
« Последнее редактирование: 25.05.2014, 21:01:58 от AnatolyW »
*

AnatolyW

  • Осваиваюсь на форуме
  • 12
  • 0 / 0
Насчет постоянной скидки при оформлении:

1) Создается купон с постоянной скидкой, с кодом например "3".

2) правится языковой файл чтобы кнопка "применить купон" изменилась на "применить скидку"
'PHPSHOP_COUPON_SUBMIT_BUTTON' => 'Учесть СКИДКУ 3% !',

3) правится couponField.tpl.php
Код
	    <form action="<?php echo $mm_action_url . basename( $_SERVER['PHP_SELF'])?>" method="post" onsubmit="return checkCouponField(this);">
<!--input type="text" name="coupon_code" id="coupon_code" width="10" maxlength="30" class="inputbox" /-->
<input type="hidden" name="coupon_code" value="3" />
<input type="hidden" name="Itemid" value="<?php echo @intval($_REQUEST['Itemid'])?>" />
<input type="hidden" name="do_coupon" value="yes" />
<input type="hidden" name="option" value="<?php echo $option ?>" />
<input type="hidden" name="page" value="<?php echo $page ?>" />
<input type="submit" value="<?php echo $VM_LANG->_('PHPSHOP_COUPON_SUBMIT_BUTTON')?>" class="button" />
« Последнее редактирование: 25.05.2014, 21:14:54 от AnatolyW »
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

[Решено] Товарная накладная и товарный чек

Автор mikeles

Ответов: 6
Просмотров: 6082
Последний ответ 21.09.2019, 19:48:12
от kungurskiy
[Решено] Чебокс "Показывать только товары, которые есть в наличии"

Автор artMelnikov

Ответов: 20
Просмотров: 7879
Последний ответ 28.06.2017, 11:19:51
от OutLaw1
Скидка на категорию [почти решено]

Автор baloon

Ответов: 4
Просмотров: 2591
Последний ответ 06.04.2016, 20:00:27
от Ejov
[Решено] Скидки на зависимые товары

Автор Serpent19

Ответов: 4
Просмотров: 1933
Последний ответ 04.06.2014, 15:47:15
от One
Свойства товара без подтягивания скидки

Автор One

Ответов: 0
Просмотров: 1514
Последний ответ 13.05.2014, 16:53:53
от One