Алексей Карташов

Алексей Карташов

С нами с 04 февраля 2013; Место в рейтинге пользователей: #58
Fi1osof
07 декабря 2015, 09:46
1
0
На счет того, насколько просто на лету в минишопе цену можно менять и как вообще обстоят дела с мультиценами, я пока не вкурсе, мало еще его ковырял. Но в рамках трех часов как раз можно было бы поковырять (но вы сначала отдельный топик напишите, может более знающие подскажут). А далее уже дело техники — определить какой город и подставить цены. Определить можно хотя бы с помощью того же GeoIP.
Fi1osof
25 ноября 2015, 16:03
1
+1
isMember — злое зло. Он использует modUser::getUserGroupNames(), который группы получает из сессии пользователя. В итоге, не редки ситуации, когда пользоветелю меняешь группы (чтобы права сменить), а у него ничего не меняется, потому что у него уже сессия была начата, и пока он не перелогинется (или ему не сбросят сессию), isMember не увидит изменения групп.
На практике это доставляет не мало хлопот. Потому лучше написать свой небольшой запрос на проверку присутствия в группе, кешируемую, и при изменении прав просто сброс кеша актуализирует информацию.
Василий Наумкин
19 ноября 2015, 10:23
10
+7
My quick example:
<?php
$tplWrapper = '@INLINE <ul>{{+output}}</ul>';
$tplYear = '@INLINE <li>{{+year}}<sup>({{+count}})</sup><ul>{{+resources}}</ul></li>';
$tplMonth = '@INLINE <li>{{+month}}<sup>({{+count}})</sup><ul>{{+resources}}</ul></li>';
$tpl = '@INLINE <li><a href="{{+uri}}">{{+pagetitle}}</a></li>';

$pdo = $modx->getService('pdoFetch');

$resources = $pdo->getCollection(
	'modResource',
	array('published' => true, 'deleted' => false),
	array('parents' => 0, 'sortby' => 'createdon', 'sortdir' => 'DESC')
);
$tree = array();
foreach ($resources as $resource) {
	$year = date('Y', $resource['createdon']);
	$month = date('m', $resource['createdon']);
	$tree[$year][$month][] = $resource;
}

$output = '';
foreach ($tree as $year => $months) {
	$tmp1 = '';
	$count = 0;
	foreach ($months as $month => $resources) {
		$tmp2 = '';
		foreach ($resources as $resource) {
			$tmp2 .= $pdo->getChunk($tpl, $resource);
			$count++;
		}
		$tmp1 .=  $pdo->getChunk($tplMonth, array(
			'month' => $month,
			'count' => count($resources),
			'resources' => $tmp2,
		));
	}
	$output .=  $pdo->getChunk($tplYear, array(
		'year' => $year,
		'count' => $count,
		'resources' => $tmp1,
	));
}

return $pdo->getChunk($tplWrapper, array('output' => $output));

Result:
Василий Столейков
01 ноября 2015, 18:11
1
0
Если у заказчика есть конкретные требования к похожести товаров, то тогда нужно думать в сторону комментария выше.
В моей практике же было просто требование «Сделать похожие товары не важно как». В таком случае я использовал сниппет getRelated, но с ним прийдётся поиграться пока его правильно настроишь.

Вызов msProducts:
[[!msProducts? 
	&tpl=`tpl.msProducts.row.new`
	&limit=`3` 
	&parents=`2` 
	&resources=`[[getRelated?&fields=`pagetitle:2,content:1`&parents=`2`&limit=`0`&noResults=``&rowSeparator=`,`&tplOuter=`relatedOuter`&tplRow=`relatedRow`]]`
	&depth=`5` 
	&includeThumbs=`200x150`
	&showHidden=`1`
	&sortby=`RAND()`
]]
Смысл: нужно заставить getRelated выводить список id похожих страниц через запятую. Этот вызов вызывает 3 похожих товара в случайном порядке.

Создать чанки:
relatedOuter
[[+wrapper]]
и relatedRow
[[+id]]
Павел Гвоздь
16 августа 2015, 20:43
6
+3
Вот какой-то плагин писал давненько. Как раз отсылает мыло. А если мыло не ввели, то создаёт юзера вот с таким мылом «телефон@сайт-на-котором-регается-юзер.ru». На том сайте мне надо было вводить либо мыло, либо телефон. Поэтому такое решение.

Обновлено: В конце там у нас есть код — если юзер авторизован, то записать данные введённые в заказе в Profile.

<?php
$mail_subj_text = 'Регистрация на ' . $modx->getOption('site_name');
$chunk_mail_reg = 'tpl.mail.userRegisterFromOrderSubmit';
$suffix_email = '@сайт-на-котором-регается-юзер.ru';

switch ($modx->event->name)
{
	
	// Обработка события, чтобы узнать, существовал ли юзер раньше..
	// А также подставляет левый email, если он не заполнен, а "телефон" заполнен
	case "msOnSubmitOrder":
		
		$order_data = $order->get();
		if( empty($order_user['email']) ) {
			$order_data = $data;
		}
		//$modx->log(modX::LOG_LEVEL_ERROR, print_r( $order->get() , true));
		//$modx->log(modX::LOG_LEVEL_ERROR, print_r( $data , true));
		
		// если email пуст или он с нашим суффиксом, то подставляем ему мыло вида - "телефон@suffix_email"
		if( empty($order_data['email']) || strstr($order_data['email'], $suffix_email) )
		{
			if( trim($order_data['phone']) != '' )
			{
				$phone = preg_replace( "/\D/", "", $order_data['phone'] );
				$data['email'] = $order_data['email'] = ( $phone ) . $suffix_email;
			}
			else
			{
				$data['email'] = $order_data['email'] = '';
			}
		}
		$modx->event->returnedValues['data'] = $data;
		
		// проверяем наличие мыла
		$email = $order_data['email'];
		if(empty($email)) { continue; }
		
		// проверяем на существование юзера по username=email, и если не существовал, то пишем соответствующее значение в сессию
		$_SESSION['minishop2']['new_user'] = false;
		if( !$modx->getCount('modUser', array('username' => $email)) )
		{
			$_SESSION['minishop2']['new_user'] = $email;
			//$modx->log(modX::LOG_LEVEL_ERROR, print_r( $_SESSION['minishop2']['new_user'] , true));
		}
		
		//$modx->log(modX::LOG_LEVEL_ERROR, print_r( $data , true));
		
	break;
	
	
	case "msOnCreateOrder":
		
		$order_user = $order->get();
		
		// если email с суфиксом нашего сайта - то не продолжаем
		if( strstr( $order_user['email'], $suffix_email ) ) { continue; }
		
		// если не авторизован
		if( !$modx->user->isAuthenticated($modx->context->key) )
		{
			$email = $order_user['email'];
			if(empty($email)) {return false;}
			
			$user = $modx->getObject("modUser", array('username' => $email) );
			
			// Если юзер не существовал раньше (при событии msOnSubmitOrder), то ставим ему новый пароль и шлём сообщение о регистрации на мыло
			if( $_SESSION['minishop2']['new_user'] == $email )
			{
				$new_password = substr( md5(rand()), 0, 9 );
				$user->set('password', $new_password );
				$user->save();
				$modx->log(modX::LOG_LEVEL_ERROR, print_r( $new_password , true));
				
				// формируем письмо (тему и текст)
				$mail_subj = $mail_subj_text;
				$mail_body = $modx->getChunk( $chunk_mail_reg,
					array_merge(
						$user->getOne('Profile')->toArray(),
						$user->toArray(),
						array(
							'password' => $new_password,
						)
					)
				);
				
				
				// шлём письмо
				$mail = $modx->getService('mail', 'mail.modPHPMailer');
				$mail->set(modMail::MAIL_BODY, $mail_body);
				$mail->set(modMail::MAIL_FROM, $modx->getOption('emailsender'));
				$mail->set(modMail::MAIL_FROM_NAME, $modx->getOption('site_name'));
				$mail->set(modMail::MAIL_SENDER, $modx->getOption('emailsender'));
				$mail->set(modMail::MAIL_SUBJECT, trim($mail_subj));
				$mail->address('to', $email);
				$mail->address('reply-to', $modx->getOption('emailsender'));
				$mail->setHTML(true);
				$mail_response = !$mail->send()
					? $mail->mailer->ErrorInfo
					: true;
				
				// пишем в лог, если письмо не ушло
				if ($mail_response != true) {
					$modx->log(modX::LOG_LEVEL_ERROR, 'Не получилось отправить email на ящик '.$email.'. Сообщение: '.$mail_response);
				}
				$mail->reset();
			}
			
			//$modx->log(modX::LOG_LEVEL_ERROR, print_r( $_SESSION[ 'user_' . $email ] , true));
		}
		else
		{
			$user = $modx->user;
			
			// записываем данные из формы в профиль
			$profile = $user->getOne('Profile');
			
			$profile->set('fullname', $order_user['receiver']);
			$profile->set('phone', $order_user['phone']);
			$profile->set('city', $order_user['city']);
			$profile->set('address', $order_user['street']);
			$profile->set('comment', $order_user['comment']);
			
			$profile->save();
		}
		
		//$modx->log(modX::LOG_LEVEL_ERROR, print_r( $order_user , true));
		
	break;
	
}
Максим Кузнецов
02 августа 2015, 18:42
7
+7
Необходимо создать кастомный класс доставки:

1) Идем в core/components/minishop2/custom/delivery/ и создаем здесь свой пхп файл (допустим, mscustomdeliveryhandler.class.php) со следующим содержимым:

<?php

//Важно: при изменении названия файла, вот в этом месте также нужно изменить класс
class mscustomdeliveryhandler extends msDeliveryHandler{

	public function getCost(msOrderInterface $order, msDelivery $delivery, $cost = 0) {
        $cart = $this->ms2->cart->status();
        
	//условие начисление доставки
        if ($cart['total_cost'] < 5000) {
            $add_price = $delivery->get('price');
            if (preg_match('/%$/', $add_price)) {
                $add_price = str_replace('%', '', $add_price);
                $add_price = $cost / 100 * $add_price;
            }
            $cost += $add_price;
        }
        
        return $cost;
    }

}

2) Идем в настройки магазина -> Варианты доставки.
Создаем новый вариант «Доставка» (или редактируем исходный), после чего заполняем в «дополнительную стоимость» требуемое значение (300 рублей), в Класс-обработчик пишем название созданного файла — mscustomdeliveryhandler, заполняем доступные способы оплаты и ставим галочку напротив «включен».
Сергей Шлоков
07 апреля 2015, 11:21
1
0
Вдруг все уже за меня придумано…
На хабре есть подробные статьи.
В MODX есть
— modx::escape(),
— modx::quote(),
— modx::stripTags,
— ну и напоследок убойный modx::sanitizeString.
А ежели сам пишешь PDO запрос, то используй bindParam.
Пашок
Пашок
25 марта 2015, 23:24
1
0
Надеюсь ты это не в серьёз. :)))
Виталий Серый
17 марта 2015, 11:03
1
+1
В принципе не проблема отключить — с прямыми руками нужный порядок сохраняется.
Но все равно притронулся к функции сортировки. Через итератор вроде неплохо работает.
public function rankProductImages() {
	$q = $this->xpdo->newQuery('msProductFile', array('product_id' => $this->get('id'), 'parent' => 0, 'type' => 'image'));
	$q->select('id');
	$q->sortby('rank ASC, createdon', 'ASC');
	if ($q->prepare() && $q->stmt->execute()) {
		$ids = $q->stmt->fetchAll(PDO::FETCH_COLUMN);
		foreach ($ids as $k => $id) {
			foreach ($this->xpdo->getIterator('msProductFile', array('parent' => $id, 'type' => 'image')) as $thumb) {$thumb->set('rank',$k); $thumb->save();}
		}
	}
}
Большое спасибо за помощь.