Зажигаешь. Даже не успеваю всё поставить и проверить, но я попробую =)
Николай, здравствуйте! Как раз зарегистрировался на сайте чтобы узнать у Вас про форум для MODX, и тут такая интересная новость. Однозначно нужно вынести на главную. Установлю и попробую запустить. Есть ли какие-либо обязательные расширения для того, чтобы все заработало? (GetResources и.т.п?)
Для начала смотрим видео, а потом милости просим под кат. В общем, как я и обещал, я таки сел писать свою социалку… Но хотя я думал выпустить первый релиз уже через пару дней, первый релиз я все-таки публикую только сегодня, не смотря на то, что за дело я взялся в тот же самый день. А дело в том, что первые дни практически полностью ушли на обдумывание модели. Я все время был в поиске такой золотой середины, чтобы и просто все было (раз-два, все встало, и работает), и при этом не имело каких-то жестких ограничений. Этот момент я разъясню подробней: вот у нас есть отдельно MODX, и отдельно Livestreet. MODX мы все любим за то, что на нем можно сделать что угодно. Это отличная платформа для проектов любого уровня. А вот Livestreet хорош тем, что на нем можно за несколько минут развернуть собственный аналог Хабрахабра. У MODX минус — отсутствие готовых решений, которые можно было бы кучу накидать как в Livestreet, и все они дружно бы работали без лишних хаков (не будем о багах). А в LS минус — узкопрофильность. Много хороших готовых компонентов, дружных и не очень, но когда дело доходит до тюнинга, вот тут начинаются серьезные проблемы (попробуйте на LS магазин замутить). Так вот, вот эту золотую середину я и хотел найти, чтобы и логика готовая была, и гибкость. И здесь я пришел к выводу, что нельзя делать один компонент. Здесь должно быть минимум два. Этот момент тоже разъясню: MODX отлично подходит для создания сайтов-визиток, корпоративных сайтов, новостных лент и магазинов. Почему? Потому что элементарная информационная сущность этих ресурсов — документ (страница). Документ имеет поля (заголовок, контент, дату создания и т.п.). Просто документ позволяет реализовать бОльшую часть структуры и логики. А там, где не хватает какого-то поля, на помощь приходят TV-шки. Но давайте взглянем на тот же LS: у нас есть блоги, топики и пользователи. Блоги и топики имеют много статистической информации (просмотры, голоса, рейтинги и т.п.), и пользователи (кто за него голосовал, за кого голосовал и т.п.). В целом все это можно было бы и на TV-шках и прочих MODX-плюшках сделать, но сами знаете, что это и большая нагрузка, и много элементов, и целостность обеспечить надо… В общем тут много всего, и MODX-а как-то не хватает (именно каких-то базовых сущностей). Если еще и на форумы посмотреть, то там тоже много общего с сущностями ливстрита есть: разделы — это блоги, топики — они и в Африке топики, и в свойствах пользователей есть общие моменты. В общем, я думал-думал, и придумал: один пакет будет устанавливать именно недостающие MODX-у сущности: Блог, Топик, Юзер. Блог и Топик — это модифицированные объекты modResource (подробнее о CRC читаем здесь, если с буржуйским нормально). А Юзер — это модифицированный modUser (об этом даже почитать нечего, разве что только мои эксперименты Поправка. Оффмануала: rtfm.modx.com/display/revolution20/Extending+modUser В свое время неправильно перевел некоторые части статьи и думал, что там пример только с данными пользователей в отдельной таблице, а не в modx_users.). Эти объекты и их дополнительные таблицы легли в основу базового пакета modSociety. Устанавливая этот пакет, вы получаете эти сущности в своей системе, но их наличия практически вообще не ощутите. Разве что появятся новые типы документов. ? По задумке объекты этого пакета должны обеспечить основу для любых типов социалок, форумов и т.п. А вот второй пакет (modBlog) — вот это уже модель готового сайта со своей уникальной логикой. Хотя пакет еще очень сырой, и это пока только заготовка, наверняка у многих, кто посмотрел видео, ассоциации возникли с Хабром или Ливстритом. Да, я хочу сделать свой вариант хабра-движка. И это будет готовое решение, которое будет устанавливаться в пару кликов, со всей структурой, готовым шаблоном и т.п. Но так же планируется, что будут появляться и другие пакеты, устанавливающие свои специализированные сайты. При этом для всех этих сайтов основа будет — modSociety. То есть если появляется какая-то сущность, которая может понадобиться большинству таких типовых движков, эта сущность переходит в modSociety. Если сущность специфическая для конкретного пакета, то там она и развивается, и устанавливается с конкретным пакетом. Таким образом будем держать такой баланс, чтобы и основа была богатая, и при этом ядро не сильно разрасталось. А теперь перечислю некоторые фишки своих пакетов. Сразу скажу, что эти пакеты — сосредоточение всех моих знаний о MODX Revolution, и пока я их писал, в поисках оптимальных решений я такие фишки Ревы ковырял, что просто прозревал. Уверен, что освоив хотя бы малую часть этого, многие, кто до сих пор еще не решился перейти на Реву, всерьез об этом задумаются… 1. Пользовательские типы ресурсов (производные от modResource). Я об этом уже говорил выше, но хочу отдельно об этом рассказать. Пользовательские ресурсы не только позволяют просто добавить какие-то свойства базовым объектам, а позволяют в принципе создавать совершенно другие объекты, и полностью менять логику. К примеру в моем пакете modBlog переопределяется папка контроллеров документов SocietyBlog и SocietyTopic, и при создании или обновлении этих ресурсов через админку как обычных документов, запросы отправляются не на системный коннектор самого MODX-а, а на коннекторы моего пакета, и там я уже дополнительно творю, что хочу. (Конечно и без этого можно обойтись, но очень яркий пример). 2. Переопределяемые контроллеры базовых классов SocietyBlog и SocietyTopic. Это вообще ураган! Хотя, как я и говорил выше, SocietyBlog и SocietyTopic — это базовые объекты, которые будут фигурировать в разных специализированных сайтах, логика этих объектов может отличаться. К примеру в своем Хабра-движке у меня будет какое-то ограничение на количество символов в топике (к примеру), а в другом типовом сайте у меня этого ограничения не будет, или оно просто будет отличаться. Так вот, используя то, что нам дает MODX, мы можем переопределять контроллеры этих объектов. К примеру в одном контексте одна папка контроллеров будет, а в другом другая. И на уровне контроллеров и процессоров я уже могу рулить логику при сохранении объектов, обновлении и т.п. При этом логика может быть или общая и для бэкэнда и для фронтэнда, или отличаться. К примеру, я хочу, чтобы ограничения на количество символов учитывались и в паблике, и в админке. Я могу это сделать, и даже в админке через редактор документов пользователь не сможет сохранить документ с нарушением правил, и получит соответствующие сообщения об ошибках. При этом мы не плодим объекты или таблицы, у нас все единое, просто логика различается в разных пакетах. 3. Шаблонизация. Я много раз говорил, что MODX-шаблоны — это не шаблоны, а чанки-контроллеры. Реальной же шаблонизации нет в MODX. Я сразу заложил основу под шаблонизации в пакете modBlog, потому можно будет легко менять скины сайта. 4. Инсталяха с менюшкой. Вот эта часть наверно самая сильная здесь. Я наверно выжал возможности менеджера пакетов MODX-а на 120%. У меня не только пакет устанавливает все политики безопасности, группы пользователей, контексты, структуру, элементы и т.п., но еще и позволяет на этапе установки выбрать какие-то особые действия, к примеру создать новый контекст, или обновить существующий. То есть даже имея несколько разных сайтов на разных контекстах с разной логикой, можно накатить новый пакет с обновлением уже существующих отдельных контекстов. В общем слов нет, одни слюни. А 120% — это потому что сам по себе менеджер пакетов не предусматривает исполнение javascript-а на этапе установки пакетов, но я использовал одну хитрость, которая позволила это. 5. 100% MODX-технологии. Да, все это — 100% функционал Рево из коробки. Да, свои объекты я дописал, но они используют таблицы, контроллеры, процессоры и т.п. самой Ревы. То есть ядро я не зацепил ни на байт, и ничего со стороны не взял. А теперь самое главное: Исходники обоих пакетов я выложил на гитхабе: github.com/Fi1osof/modSociety github.com/Fi1osof/modBlog Я рассчитываю на то, что заинтересованные члены сообщества так же подключатся к доработке этих пакетов. Самое главное — основу — я уже заложил и ее и буду развивать. Но есть полно задач, которые можно разбить. К приму скины для него нужны и т.п. То есть все мы сможем создать отличный движок, который наверняка сможет стать ключом для MODX в мир блого-социальных движков. Гарантирую каждому участнику огромный опыт на выходе.
Просто в этом процессоре мне количество и не нужно — пользователь один Так а что же ты тогда используешь modObjectGetListProcessor? Используй modObjectGetProcessor он делает выборку только одного процессора. Еще надо будет посмотреть, можно ли после Join'ов ограничивать количество и сортировать присоединенные записи… Все эти вещи выполняются в list-процессорах пакета shopModx. Посмотри как это там выполняется. Лично я исползую их практически везде, и еще не было задачи, на которую мне не хватало бы getdata-процессора. P.S. если у тебя суперузкопрофильная задача, тогда вообще используй просто modPropcessor, и основную логику пиши в методе process.
Я туда и смотрю) Просто в этом процессоре мне количество и не нужно — пользователь один, а уже присоединенных объектов много. Еще надо будет посмотреть, можно ли после Join'ов ограничивать количество и сортировать присоединенные записи…
Пожалуйста. Можешь скачать магазин и посмотреть как там сделано.
Илья, привет!
Ты используешь базовый процессор modObjectGetListProcessor. Переопределять в нем метод getData надо очень осторожно. Вот ты не очень удачно это сделал, так как ты из метода вынес очень полезные методы, такие как prepareQueryBeforeCount и prepareQueryAfterCount. Вот сравни: public function getData() { $data = array(); $limit = intval($this->getProperty('limit')); $start = intval($this->getProperty('start'));
/* query for chunks */ $c = $this->modx->newQuery($this->classKey); $c = $this->prepareQueryBeforeCount($c); $data['total'] = $this->modx->getCount($this->classKey,$c); $c = $this->prepareQueryAfterCount($c);
$sortClassKey = $this->getSortClassKey(); $sortKey = $this->modx->getSelectColumns($sortClassKey, $this->getProperty('sortAlias',$sortClassKey),'',array($this->getProperty('sort'))); if (empty($sortKey)) $sortKey = $this->getProperty('sort'); $c->sortby($sortKey,$this->getProperty('dir')); if ($limit > 0) { $c->limit($limit,$start); }
$data['results'] = $this->modx->getCollection($this->classKey,$c); return $data; } Так вот как раз на уровне этих методов и происходит вклинивание в формирование запроса. То есть в расширяющем процессоре ты пишешь примерно следующее: public function prepareQueryBeforeCount(xPDOQuery $c) { $c = parent::prepareQueryBeforeCount($c); // Добавляешь условия к запросу return $c; } Это тебе позволит не лезть в общую логику. 2. По поводу самой логики: я сам чаще всего использую только два метода: а) Расширение классов (переопределяя методы типа prepareQueryBeforeCount) б) Передачей параметров. К примеру вот часть кода процессора: class ....{ public function initialize(){ $this->setDefaultProperties(array( 'hot' => false, // Флаг, что делать только выборку новинок )); return parent::initialize(); }
public function prepareQueryBeforeCount(xPDOQuery $c) { $c = parent::prepareQueryBeforeCount($c);
// Если указано, что нужны только новинки
if($this->getProperty('hot')){
// Добавляем условие только новинок
}
return $c;
}
} И вот уже при вызове этого процессора ты просто передаешь параметр 'hot' => true и все. По умолчаниюу тебя стоит 'hot' => false.
На сайте есть страница пользователя. На ней выводится его профиль, созданные им объявления, его последние заявки и пр. Это все отдельные объекты. Кроме того есть страницы со списками этих объектов «Мои объявления», «Мои заявки». Хотелось бы на любой из страниц делать поменьше запросов. Соответственно, нужны JOIN. Как я представляю реализацию таких выборок. Для страницы пользователя есть процессор xpectaProfileGetProcessor, в который передается id пользователя и он выбирает все его данные: <?php
class xpectaProfileGetProcessor extends modObjectGetListProcessor{ public $classKey = 'modUser';
public function getData() {
$c = $this->modx->newQuery($this->classKey);
$c->where(array('id' => $this->getProperty('id')));
$c->select(array(
"{$this->classKey}.*",
));
$data = array();
if($c->prepare() && $c->stmt->execute()){
$data = $c->stmt->fetchAll(PDO::FETCH_ASSOC);
}
return $data;
}
}
return 'xpectaProfileGetProcessor'; В него я хочу передавать список «модулей», которые нужно запустить. Каждый из них будет выглядеть как-то так: $c->leftJoin('xpectaAd', 'xpectaAd');
$c->select(array( "xpectaAd.id as ad_id", 'xpectaAd.title as ad_title', //... ));
return $c; И отсюда вопрос, где эти методы лучше хранить? Создать отдельный класс с ними? Или в код класса того или иного объекта вставлять как метод — но тогда их из процессора просто так не вызовешь… А можно прямо в этом процессоре и хранить. Какой вариант предпочтительнее? Или, может это все совсем не так делается?
Печально новый год начинать с такого нехорошего топика, но ничего не поделаешь… Конечно много уже кто бросал камни в MODX из-за проблем с кешированием, но сегодня сделаю это и я. Я конечно же очень люблю MODX, но некоторые вещи меня прямо-таки вымораживают! Сразу оговорюсь, что описываемые здесь проблемы касаются только тех случаев, когда предполагается большое количество документов в одном контексте (более 10 000). Сегодня мы рассмотрим процесс генерации кеша контекстов и на что и как мы можем влиять. Для начала немного теории: каждый раз, когда мы обновляем кеш сайта, MODX полностью перегенерирует и сохраняет настройки всех контекстов. То же самое он делает и с каждым контекстом в отдельности, когда, к примеру, сохраняется какой-либо документ контекста. А в чем проблема? А проблема в том, что это как минимум накладывает очень серьезные ограничения на максимальное кол-во документов в контексте. Почти два года назад я уже писал о своих исследованиях по этому поводу еще на версии Revo 2.0.8, так вот — с тех пор практически ничего не поменялось… Сразу определим основную проблему: при обновлении кеша контекста, MODX перебирает все документы этого контекста (читай: делает много-много запросов к базе данных и получает и обрабатывает очень большой объем информации) и формирует карты ресурсов и алиасов. При этом он хранит эти карты не в отдельном кеш-файле, а именно в кеше настроек контекста. Есть проблема — сразу же можно предположить парочку вариантов ее решения: