Я согласен поддержать рублем, но опять месяц близится к концу :)

Очень подробная инструкция о том, как с нуля создать новый LAMP-сервер под MODX и установить собственно сам MODX Revolution на digitalocean.com Там все на буржуйском, но в целом не сложнее любой другой технической документации. Зато очень подробно и пошагово.

Всем, кто ждет с нетерпением новой сборки ShopModxBox, на которую был анонсирован сбор средств: есть две новости (хорошая и плохая). Плохая: скорее всего выпуск сборки задержится на пару-тройку дней. Хорошая: основная причина — более обширный функционал, чем был анонсирован в топике. Я реанимировал свой давний самый крупный проект (что интересно, я уже там использовал Smarty, хотя это был конец 11-го года). В том проекте было много интересных плюшек, которые я и решил перенести в эту сборку. В частности, там была оплата не только через платежные системы (можно было даже использовать несколько штук одной и той же системы, к примеру несколько робокасс (зачем? Там у нас была мультидоменность и партнерская программа, и надо было чтобы на разных доменах оплата проходила через разные робокассы для разных владельцев)), но и оплата с баланса. А так же не только продажа, но и подписки (при чем на подписки можно было завести сколько угодно тарифных планов, с различными сроками действия, количеством включенной в пакет внутренней валютой и т.п.). В общем, там был полноценный биллинг. И вот этот биллинг я и решил перенести на ShopModxBox. Само собой там тоже не было все идеально, в связи с чем это не пятиминутный перенос, а по сути переписка всего с нуля, просто тот проект помогает вспомнить какие ошибки были допущены и что можно было улучшить. В итоге сразу хочу отметить, что новая сборка полностью переделана и обратной совместимости не имеет вообще. О таких вариантах говорилось изначально, но в данном случае хочу это отметить особенно, так как не только структура изменения претерпела, но и база данных. Еще об изменениях: изменения в сборке реально кардинальные, и коснулись вообще всего, и главным образом корзины. Раньше корзина хранилась только в сессии, и в базу попадал только оформленный заказ. Здесь сразу несколько минусов есть, и главный для маркетологов — они не знают какие товары вызывали интерес, сколько было оформлено заказов, сколько не оформлено, какова конверсия и т.п. Так же если по какой-то причине сессия слетела (даже у авторизованного пользователя), то и корзина слетала. Сейчас есть куча вариантов в этом направлении, в том числе даже найти корзину не авторизованного пользователя, и передать ее ему, если он авторизовался. А если это был авторизованный пользователь, то он найдет свою корзину в личном кабинете в любой момент. И вот как раз в этом и кроется причина многих изменений. Во-первых, чисто идеологически. Я долго думал над тем, чем же на самом деле является корзина, и пришел к выводу, что это по сути своей Заказ, только еще не оформленный (то есть статус у него Новый). И Корзину (с товарами) от полноценного Заказа отличает только статус Оформлен. При этом не следует плодить сущности и выполнять всякие метаморфозы (то есть, к примеру, в момент оформления заказа перекидывать товары из Корзины в Заказ и т.п.). И очистка Корзины — это смена статуса на Отменен. То есть сам заказ никуда не деется, он просто отменяется (меняется статус). Для маркетологов это опять-таки полезная информация, так как для оценки поведения клиентов важно понимать что они делают, чтобы потом понять почему они так делают. В связи с этим, хочу сразу отметить, что мы берем курс на очень серьезное решение, в котором очень много всего будет уделено именно маркетингу. Это все равно как некоторые ЦМСки выделяют именно как SEO-friendly, потому что они не только управляют контентом, но и имеют какие-то инструменты для только, чтобы делать сайт более индексируемым. А мы вот плюс к этому будем пытаться делать так, чтобы магазин не просто работал (показывал товары), а имел серьезную маркетинговую составляющую. А вот сейчас полезная информация в плане идеологической структуры сайта. Главное: появляется новый компонент Billing, в котором содержится все, что связано с оплатами, счетами, заказами, контрагентами и т.п. Итак, мы определили базовую сущность — Заказ (Order). У заказа есть Статусы (OrderStatus). Есть связка Заказ-Товар (OrderProduct). Вот с этим как раз и работает корзина. Сама корзина осталась отдельным компонентом Basket, но процессоры она вызывает из компонента Billing. Далее, на заказ уже может быть сформирован счет (Invoice). Счета так же имею статусы (InvoiceStatus). Оплата (Payment). Это один из самых сложных моментов, и не буду грузить сейчас всеми тонкостями проводок, оплатой сразу по нескольким счетам и т.п. В общем, пока делаем попроще (один платеж — один счет, без всяких там транзакций и т.д. и т.п.), но в дальнейшем будем биллинг постепенно развивать. Так же Payment содержит информацию о том, через какую платежную систему был совершен платеж, ID счета в платежной системе и т.п. В общем, все это — очень большой объем работ, и лучше подождать пару дней, и получить более комплексную сборку сразу, чем потом пытаться докинуть доработки (так как это будет сделать очень сложно, ибо все это — основа, и очень сложная. Там много изменений будет в самой базе данных и т.п.). А чтобы оценить примерно объем работы, покажу пару скринов. Это основная модель (скрин 1) и процессоры основного компонента (скрин 2.) с того моего проекта. ? ? А в ShopModxBox я постепенно хочу сделать еще больше функционала (само собой буду стараться, чтобы объем кода не был очень большой, и все было структурировано). Так что, кому все это интересно, не стесняйте поддерживать рублем. Работы будет много и постоянно, а кушать надо :-)

Но к слову, там не все классно в этом плане (сортировок). Сортировка по одному полю — это запросто. А вот сортировка по нескольким полям — это уже не просто так. Поэтому буду думать еще в этом направлении. Чисто из-за того, что там по сути два запроса выполняется и используется два объекта запросов, там сложности в плане вызова единого метода на формирования сортировок. Дело в том, что подсчет надо выполнять без сортировки, а конечный запрос с сортировкой, и на практике там много бывает вариантов, когда единый вариант сложно найти. Но это обязательно будет доработано.

Как раз это тебе и писал :-)

Здесь у тебя все ОК с SQLем, но ты не там это используешь. Подсчет должен выполняться без всяких order by rand(). А тебя метод prepareQueryBeforeCount. Правильней в initialize() указывать $this->setDefaultProperties(array( 'sort' => 'RAND()', )); Или просто в вызов передавать sort=RAND()

Разобрался. дастаточно было указать sort=RAND(), ничего не надо править в процессоре :)

В процессоре: //-------------------------------------------------------------- public function prepareQueryBeforeCount(xPDOQuery $c) { $c->where(array( 'parent' => $this->getProperty('parent'), ));

    if($this->getProperty('sort')=='rand')
        $c->sortBy('RAND()');

$s = $c->prepare(); print $c->toSQL();

$s->execute();

print '<pre>'; print_r($s->errorInfo()); return $c; } } выдает SELECT modResource.id AS modResource_id, modResource.type AS modResource_type, modResource.contentType AS modResource_contentType, modResource.pagetitle AS modResource_pagetitle, modResource.longtitle AS modResource_longtitle, modResource.description AS modResource_description, modResource.alias AS modResource_alias, modResource.link_attributes AS modResource_link_attributes, modResource.published AS modResource_published, modResource.pub_date AS modResource_pub_date, modResource.unpub_date AS modResource_unpub_date, modResource.parent AS modResource_parent, modResource.isfolder AS modResource_isfolder, modResource.introtext AS modResource_introtext, modResource.content AS modResource_content, modResource.richtext AS modResource_richtext, modResource.template AS modResource_template, modResource.menuindex AS modResource_menuindex, modResource.searchable AS modResource_searchable, modResource.cacheable AS modResource_cacheable, modResource.createdby AS modResource_createdby, modResource.createdon AS modResource_createdon, modResource.editedby AS modResource_editedby, modResource.editedon AS modResource_editedon, modResource.deleted AS modResource_deleted, modResource.deletedon AS modResource_deletedon, modResource.deletedby AS modResource_deletedby, modResource.publishedon AS modResource_publishedon, modResource.publishedby AS modResource_publishedby, modResource.menutitle AS modResource_menutitle, modResource.donthit AS modResource_donthit, modResource.privateweb AS modResource_privateweb, modResource.privatemgr AS modResource_privatemgr, modResource.content_dispo AS modResource_content_dispo, modResource.hidemenu AS modResource_hidemenu, modResource.class_key AS modResource_class_key, modResource.context_key AS modResource_context_key, modResource.content_type AS modResource_content_type, modResource.uri AS modResource_uri, modResource.uri_override AS modResource_uri_override, modResource.hide_children_in_tree AS modResource_hide_children_in_tree, modResource.show_in_tree AS modResource_show_in_tree, modResource.properties AS modResource_properties FROM modx_site_content AS modResource WHERE modResource.parent = 9 ORDER BY RAND() ASC

Array ( [0] => 00000 [1] => [2] => ) и на выходе процессора пусто.