Илья Александрович

Илья Александрович

С нами с 13 ноября 2017; Место в рейтинге пользователей: #362
Иван Бочкарев
08 декабря 2020, 09:05
2
+1
Вариант, когда нужно предоставить возможность указать минимальную сумму для клиента в ClientConfig:

<?php
$cart_status = $order->ms2->cart->status();
$order_status = $order->get();
$min_price_order = $modx->getOption('min_price_order');

if ($modx->event->name == 'msOnSubmitOrder'){
    if ($cart_status['total_cost'] < $min_price_order && $order_status['delivery'] == 2) {
        $modx->event->output('Минимальная сумма заказа для выбранного способа доставки ' . $min_price_order . ' рублей!');
    } 
}
Konstantin
08 апреля 2019, 07:15
2
+2
Легко!
Заварить себе чашечку чего-нибудь, сесть на балконе/веранде, подумать о бренном и осознать, что сайт без цен в 2019 году это пи***ц и так делать нельзя.

Ну а если не осознаете никак важность цены на сайте, то напишите прехук для формит:
<?php
    //id получателей
    $recipients = array(
        '00000','00000'
    );
    
    $client_phone = $hook->getValue('phone');
    $client_email = $hook->getValue('email');
    
    // Текст сообщения
    $tm_msg = "Назови клиенту цену, изверг! : {$client_phone}, {$client_email} ";

    $tm_token = 'токен бота';
    $tm_msg = urlencode($tm_msg);

    foreach($recipients as $id){
        $url = "https://api.telegram.org/bot{$tm_token}/sendMessage?chat_id={$id}&text={$tm_msg}";
        $ch = curl_init();
        curl_setopt_array($ch, array(CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true));
        $result = curl_exec($ch);
        curl_close($ch);
    }

return true;
Андрей
05 января 2019, 16:27
3
0
ох, давно это было… я может что-то еще там менял.
вот рабочий итог
[[!FormIt?
            &pdfTpl=`tpl.PDF1`
            &hooks=`formit2file, SendFilePDF, redirect`
            &author=`www.ru`
            &title=`Заявка`
            &emailTpl=`sentEmailTpl`
            &validate=`contact_email:required`
            &store=`1`
            &redirectTo=`108`
            ]]
formit2file
<?php
// initialize output;
$output = true;
$counter = 1;
 
// valid extensions
$ext_array = array('jpg', 'png', 'gif', 'JPG', 'zip', 'rar', '7z', 'rar5');
 
// create unique path for this form submission
$uploadpath = 'assets/pdf/';
 
// get full path to unique folder
$target_path = $modx->config['base_path'] . $uploadpath;
 
// get uploaded file names:
$submittedfiles = array_keys($_FILES);
 
// loop through files
foreach ($submittedfiles as $sf) {
 
    // Get Filename and make sure its good.
    $filename = basename( $_FILES[$sf]['name'] );
 
    // Get file's extension
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
    $ext = mb_strtolower($ext); // case insensitive
 
    // is the file name empty (no file uploaded)
    if($filename != '') {
         
        // is this the right type of file?
        if(in_array($ext, $ext_array)) {
     
            // clean up file name and make unique
            $filename = $counter . '.' . $ext; 
            $filename = str_replace(' ', '_', $filename); // spaces to underscores
            $filename = date("G-i-s_") . $filename; // add date & time
             
            // full path to new file
            $myTarget = $target_path . $filename;
             
            // create directory to move file into if it doesn't exist
            mkdir($target_path, 0755, true);
             
            // is the file moved to the proper folder successfully?
            if(move_uploaded_file($_FILES[$sf]['tmp_name'], $myTarget)) {
                // set a new placeholder with the new full path (if you need it in subsequent hooks)
                $myFile = $uploadpath . $filename;
                $hook->setValue($sf,$myFile);
                // set the permissions on the file
                if (!chmod($myTarget, 0644)) { /*some debug function*/ }
                 
            } else {
                // File not uploaded
                $errorMsg = 'There was a problem uploading the file.';
                $hook->addError($sf, $errorMsg);
                $output = false; // generate submission error
            }
         
        } else {
            // File type not allowed
            $errorMsg = 'Type of file not allowed.';
            $hook->addError($sf, $errorMsg);
            $output = false; // generate submission error
        }
     
    // if no file, don't error, but return blank
    } else {
        $hook->setValue($sf, '');
    }
$counter = $counter + 1;
}
return $output;
SendFilePDF
<?php
$fields = $hook->getValues(); //поля из формы
$NF = $fields['filesToUpload'];//получаем имя и путь загруженного файла
$fields['filesToUpload'] = str_replace('assets/pdf/','',$fields['filesToUpload']);
$mail_z = $fields['contact_email'];
$message = $modx->getChunk('sentEmailTpl', $fields);

//формируем PDF
$pdo = $modx->getService('pdoFetch'); 
$pdfTpl = $modx->getOption('pdfTpl', $formit->config, '', true);
$content = $pdo->getChunk($pdfTpl, $fields);

$config = array();
$config = array_merge($config, $fields, array(
    'content' => $content,
    'author' => $author,
    'title' => $title,
));
// формируем ссылку на PDF
$result = $modx->runSnippet('PdfCreate', $config);
 
$modx->getService('mail', 'mail.modPHPMailer');
$modx->mail->set(modMail::MAIL_BODY, $message);
$modx->mail->set(modMail::MAIL_FROM, $modx->getOption('emailsender'));
$modx->mail->set(modMail::MAIL_FROM_NAME, $modx->getOption('site_name'));
$modx->mail->set(modMail::MAIL_SUBJECT, 'Поступила заявка');
$modx->mail->address('to', 'xxx@gmail.com');
$modx->mail->address('to', 'xxx@mail.ru');
$modx->mail->address('to', $mail_z);
$modx->mail->address('reply-to', $modx->getOption('emailsender'));
$modx->mail->attach($modx->getOption('base_path').'assets/pdf/'.$result.'.pdf');
$modx->mail->attach($modx->getOption('base_path').$NF);
$modx->mail->setHTML(true);

if (!$modx->mail->send()) {
  $modx->log(modX::LOG_LEVEL_ERROR,'An error occurred while trying to send the email: '.$modx->mail->mailer->ErrorInfo);
}

$modx->mail->reset();

return true;
PdfCreate
<?php
$date = date('Y-m-d_H-i-s', time()) . '_' .rand(1, 100);

$corePath = $modx->getOption('pdfresource.core_path', null, $modx->getOption('core_path') . 'components/pdfresource/');
$pdfresource = $modx->getService('pdfresource', 'PDFResource', $corePath . 'model/pdfresource/', array(
    'core_path' => $corePath
));

$content = $modx->getOption('content', $scriptProperties, '', true);
$title = $modx->getOption('title', $scriptProperties, '', true);
$author = $modx->getOption('author', $scriptProperties, '', true);

$aliasPath = MODX_ASSETS_PATH . 'pdf/';
$site_url = $modx->getOption('site_url');

// настройки PDFResource (подробнее почитать здесь: http://jako.github.io/PDFResource/usage/)
$pdfresource->initPDF(array(
    'mode' => 'utf-8',
    'format' => 'A4',
    'defaultFontSize' => intval(13),
    'defaultFont' => '',
    'mgl' => intval(30),    // margin left
    'mgr' => intval(10),    // margin right
    'mgt' => intval(30),     // margin top
    'mgb' => intval(10),     // margin bottom
    'mgh' => intval(10),    // margin header
    'mgf' => intval(10),    // margin footer
    'orientation' => 'P',   // ориентация PDF
    'customFonts' => '[]',
));

$pdfresource->pdf->SetTitle($title);
$pdfresource->pdf->SetAuthor($author);
$pdfresource->pdf->SetCreator($modx->getOption('site_url'));

$pdfresource->pdf->WriteHTML($content, 2);

$file_name = $date;
$pdfresource->pdf->Output($aliasPath . $file_name . '.pdf', 'F');

return $file_name;
Сергей Самусев
03 декабря 2018, 20:43
1
0
'tvFilters' => 'committees==%' ~ $_modx->resource.id~'%', Работает. Спасибо!
Konstantin
03 июня 2018, 10:07
1
0
Дополнительные опции выводятся просто, на странице с товаром
{$_modx->resource.device_type}

Если минишоп последний, то даж опции в виде текстового поля выводится как массив, я использую join
{$_modx->resource.device_type | join}
В списке товаров также только без «_modx->resource.»
{$device_type} {$device_type | join}
И также с сниппетом
В списке товаров:
{'!AddComparison' | snippet : [
'id' => $id,
'tpl' => 'Comparison.add',
'list' => $device_type,
'list_id' => 14
]}
На странице товара
{'!AddComparison' | snippet : [
'id' => $id,
'tpl' => 'Comparison.add',
'list' => $_modx->resource.device_type,
'list_id' => 14
]}
Если опция массив то добавляйте join
'list' => $device_type | join, 'list' => $_modx->resource.device_type | join,
Андрей
14 декабря 2017, 18:00
1
0
[[!FormIt?
&pdfTpl=`tpl.PDF`
&hooks=`pdf, SendFilePDF, redirect`
&author=`Автор PDF`
&title=`Заголовок PDF`
&emailTpl=`sentEmailTpl`
&emailSubject=`Заявка на подключение`
&validate=`contact_name:required:minLength=^2^,
contact_email:email:required,
contact_message:required`
&store=`1`
&redirectTo=`20`
]]
сниппет pdf
<?php
$pdo = $modx->getService('pdoFetch'); 
$pdfTpl = $modx->getOption('pdfTpl', $formit->config, '', true);
$author = $modx->getOption('author', $formit->config, 'Автор', true);
$title = $modx->getOption('title', $formit->config, 'Заголовок PDF', true);
$content = $pdo->getChunk($pdfTpl, $fields);
$config = array();
$config = array_merge($config, $fields, array(
    'content' => $content,
    'author' => $author,
    'title' => $title,
));
// формируем ссылку на PDF
$hook->setValue('pdf_link', $modx->runSnippet('PdfCreate', $config)); 
return true;
и сниппет PdfCreate
<?php
$date = date('Y-m-d_H-i-s', time()) . '_' .rand(1, 100);

$corePath = $modx->getOption('pdfresource.core_path', null, $modx->getOption('core_path') . 'components/pdfresource/');
$pdfresource = $modx->getService('pdfresource', 'PDFResource', $corePath . 'model/pdfresource/', array(
    'core_path' => $corePath
));

$content = $modx->getOption('content', $scriptProperties, '', true);
$title = $modx->getOption('title', $scriptProperties, '', true);
$author = $modx->getOption('author', $scriptProperties, '', true);

$aliasPath = MODX_ASSETS_PATH . 'pdf/';
$site_url = $modx->getOption('site_url');

// настройки PDFResource (подробнее почитать здесь: http://jako.github.io/PDFResource/usage/)
$pdfresource->initPDF(array(
    'mode' => 'utf-8',
    'format' => 'A4',
    'defaultFontSize' => intval(8),
    'defaultFont' => '',
    'mgl' => intval(10),    // margin left
    'mgr' => intval(10),    // margin right
    'mgt' => intval(7),     // margin top
    'mgb' => intval(7),     // margin bottom
    'mgh' => intval(10),    // margin header
    'mgf' => intval(10),    // margin footer
    'orientation' => 'P',   // ориентация PDF
    'customFonts' => '[]',
));

$pdfresource->pdf->SetTitle($title);
$pdfresource->pdf->SetAuthor($author);
$pdfresource->pdf->SetCreator($modx->getOption('site_url'));

$pdfresource->pdf->WriteHTML($content, 2);

$file_name = $date;
$pdfresource->pdf->Output($aliasPath . $file_name . '.pdf', 'F');
return $site_url . ltrim($modx->getOption('assets_url'), '/') . 'pdf/' .$file_name. '.pdf';
в который и генерит имя файла в переменной $file_name по сути равной дате, но вот как эту переменную передать в другой сниппет я не могу понять, просто указание имени не помогает
DOM
DOM
12 июля 2017, 15:11
3
0
Для вообще ленивых :), авторизация Login по ajax:
Вызов:
[[!Login? &loginTpl=`lgnLoginTpl` &logoutTpl=`lgnLogoutTpl` &errTpl=`lgnErrTpl` &loginResourceId=`52` &logoutResourceId=`[[*id]]`]]

Форма:
<div class="loginForm">
    <div class="loginLogin">
        <div class="loginMessage">[[!+errors]]</div>
        <form class="loginLoginForm auth" action="[[~[[*id]]]]" method="post">
            <fieldset class="loginLoginFieldset">
                <label class="loginUsernameLabel" for="login">[[%login.username]]</label>
                <input class="loginUsername put-focus" type="text" name="username" id="login">
                <span class="error error-login"></span>
                
                <label class="loginPasswordLabel" for="pass">[[%login.password]]</label>
                <input class="loginPassword" type="password" name="password" id="pass">
                <span class="error error-password"></span>
                    
                <input class="loginRememberme" type="checkbox" name="rememberme" id="checkbox-1" checked>
                <label class="loginRemembermeLabel new-check" for="checkbox-1">Запомнить меня</label>
                
                <input class="loginLoginValue" type="hidden" name="service" value="login">
                <input type="submit" name="Login" value="[[+actionMsg]]">
                 
                <input class="returnUrl" type="hidden" name="returnUrl" value="[[+request_uri]]">
            </fieldset>
            <div class="text-center">
                <a class="forgot-login" href="[[~45]]">Забыли логин или пароль?</a>
            </div>
        </form>
    </div>
</div>

Скрипт:
<script>
        $(document).ready(function(){
            $(".auth").bind("submit", function() {
                $("span.error, .loginMessage").text("");
                $("input.error, textarea.error").removeClass('error');
                
                if ($(".loginUsername").val().length < 1 && $(".loginPassword").val().length < 1) {
                    $(".error-login").text("Для входа введите Ваш логин");
                    $(".error-password").text("Для входа введите Ваш пароль");
                    $('.loginUsername, .loginPassword').addClass('error');
                    return false;
                }
                
                if ($(".loginUsername").val().length < 1) {
                    $(".error-login").text("Для входа введите Ваш логин");
                    $('.loginUsername').addClass('error');
                    return false;
                }
                
                if ($(".loginPassword").val().length < 1) {
                    $(".error-password").text("Для входа введите Ваш пароль");
                    $('.loginPassword').addClass('error');
                    return false;
                }
                
                $.ajax({
                        type    : "POST",
                        cache   : false,
                        url     : "[[~[[*id]]]]",
                        data    : $(this).serializeArray(),
                        success: function(data) {
                            var errMessage = $(data).find(".loginMessage").text();
                            if(errMessage == ""){
                                window.location = "[[~[[*id]]]]";
                            }else{
                                $(".error-login").text('Неправильный логин или пароль');
                                $('.loginUsername, .loginPassword').addClass('error');
                            }
                        }
                });
        
                return false;
        	});
        });
    </script>
Гриборий
22 февраля 2017, 15:41
1
+1
Плагином на событие OnDocFormSave.
if ( $resource->class_key == 'msProduct' ) {
    $uri = 'product/' . $resource->pagetitle . '.html';
    $resource->set('uri', $uri);
    $resource->save();
}
Дмитрий Мансуров
12 января 2017, 00:53
4
0
Спустя несколько лет вопрос все еще актуален поэтому напишу краткую инструкцию
Редактируем файлы
core/components/minishop2/model/minishop2/mscarthandler.class.php
Ищем
$count = inval($count);

(у меня это строка 153)
Меняем на
$count = floatval($count);
Файл:
core/components/minishop2/model/minishop2/mysql/msorderproduct.map.inc.php
Ищем
'count' => 
    array (
      'dbtype' => 'int',
      'precision' => '10',
      'phptype' => 'integer',
      'attributes' => 'unsigned',
      'null' => true,
      'default' => 1,
    ),
меняем на
'count' => 
    array (
      'dbtype' => 'decimal',
      'precision' => '10,2',
      'phptype' => 'float',
      'null' => true,
      'default' => 1,
    ),
Файл:
core/components/minishop2/model/schema/minishop2.mysql.schema.xml
Ищем
<field key="count" dbtype="int" precision="10" phptype="integer" attributes="unsigned" null="true" default="1"/>
меняем на
<field key="count" dbtype="decimal" precision="10,2" phptype="float"  null="true" default="1"/>
Виктор Долгий
01 сентября 2016, 13:03
2
0
Судя по всему, сохранением опций заведует класс msProductData, вот его и заставим работать. Мой пример с рабочего сайта, где нужно было к значению опции товара нужно было приписать текст. Также можно заменить значение, или обрабатывать поля с несколькими значениями, главное понимать, что нужно делать с массивами (опций):

<?php
$parentCategory = 220;
$optionKey = 'base_nicotine';
$addText = 'мг/мл';

$parents = $modx->runSnippet('pdoResources', array('returnIds' => 1, 'parents' => $parentCategory, 'where' => array('class_key' => 'msCategory'), 'limit' => 0));
$parents = explode(",", $parents);

foreach ($parents as $parent) {
	$products = $modx->getCollection('msProduct', array('parent' => $parent));
	foreach ($products as $product) {
		if (!($product instanceof msProduct)) {
			return "The resource with id = {$product->id} is not instance of msProduct.";
		}
		
		if ($data = $product->getOne('Data')) {
			$options = $data->get('options');
		}
		
		foreach ($options as $dataKey => $dataValue) {
			if ($dataKey == $optionKey && !strpos($dataValue[0], $addText)) {
				$options[$dataKey][0] = $dataValue[0].' '.$addText;
				$data->set('options', $options);
				$data->save();
			}
		}
	}
}

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