Контент


Библиотека ORM_MPTT

Понадобилось реализовать некоторые ORM-модели с поддержкой алгоритма Nested Sets, поэтому решил посмотреть существующие разработки. Существует проект MPTT library на официальной странице проектов Kohana, но меня в данный момент эта библиотека не устраивает отсутствием поддержки нескольких деревьев (multiple scopes), а также реализацией запросов к БД напрямую, без использования Query Builder‘а. На code.google.com есть проект ORM_MPTT, но он давно не развивается (что не помешало именно этой библиотеке стать отправной точкой для всех последующих разработок алгоритма Nested Sets под Kohana).

В результате я решил пойти по стопам разработчика S7Ncms (Eduard Baun) — сделать собственную библиотеку с реализацией нужных мне методов. Первая версия библиотеки доступна здесь. [подумываю насчет установки redmine для собственных проектов на сайт, реально ли это?]

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в Kohana.

Теги: , , .


Комментарии (19)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. cr0t пишет:

    Redmine? Смотря на сколько сильное желание будет ;) Я неделю на своем мучался, пока настроил так, что меня стало устраивать и компьютер не умирал под нагрузками при коммитах. Можете написать мне в личку — дам ссылку на свой, посмотрите, как выглядит «домашний» Redmine.

  2. BIakaVeron пишет:

    Интересно, можете на почту скинуть? Вообще пользую хостинг проектов от Google, но как-то хочется свое поставить. Правда, смущают возможные неприятные нагрузки…
    PS. Блог сами разработали? На Yii, как я понимаю :)

  3. stalker пишет:

    Вы не могли бы выложить исходники своей библиотеки еще раз в доступное место? По указанной ссылке только: Unknown post id, it may have expired or been deleted …

  4. VKS пишет:

    Не хватает наверное еще в библиотеке методов перемещения нодов между собой, а так реализация достойная, только в 349 строке имя метода исправьте, видимо ошибка.

  5. BIakaVeron пишет:

    Переместить узел с дочерними элементами можно методом move_to(). Также можно сменить родителя у всех дочерних элементов текущего узла (move_chilren_to()). Или надо что-то другое?
    Какая ошибка в строке 349? neighbor = ‘сосед’, метод проверяет, общий ли у них родитель.

  6. VKS пишет:

    В 349 у вас метод обзывается is_heighbor :P

    А не хватает метода, который бы менял позиции нодов между собой

    http://php.russofile.ru/ru/authors/sql/nestedsets01
    Вот на мой взгляд один из самых развитых классов для работы с деревьями. (методы ChangePosition и ChangePositionAll)

  7. BIakaVeron пишет:

    Ну, по сути это последовательные два вызова move_to(). Можно их реализовать в одном (уменьшится количество запросов), но часто ли они применяются?

    PS. А по поводу метода is_neighbor() все равно не понял :) Как Вы предлагаете его обозвать?

  8. VKS пишет:

    is_heighbor != is_neighbor() , просто у вас опечатка

  9. BIakaVeron пишет:

    Тьфу! :) Спасибо, исправил.

  10. VKS пишет:

    методы ChangePosition и ChangePositionAll в принципе вещи достаточно часто применяемые — допустим для сортировки категорий в каталоге.

  11. BIakaVeron пишет:

    ИМХО, сортировка не имеет ничего общего с хранимыми в БД данными. Если сегодня одна категория выше, а завтра другая — постоянно менять их местами? Проще сделать дополнительное поле и сортировать (ORDER BY) по нему…

  12. Sanpedro пишет:

    сортировка и иерархия хранимых данных вещи разные! но существуют как правило слитно — использование нестет деерва оправдано :) , а ORDER BY может «максимум» выводить детей в меню, отсортированными по алфавиту, не нарушая структуры ИМХО :)
    Спасибо за ссылочку на DB Tree…
    и Вам BlackaVeron, спасибо …

  13. BIakaVeron пишет:

    Представим себе две соседние ветки по 100 дочерних узлов в каждой. Чтобы поменять их местами, придется выполнить специальные (довольно затратные) запросы. А вот добавить к узлам поле order_num, которое будет управлять очередностью вывода веток — намного ведь проще. Разве не так? ИМХО, в пределах одного уровня ветки в принципе равнозначны, и не имеет смысла их менять местами (по крайней мере на стадии эксплуатации).

    Хотя метод все равно надо будет добавить…

  14. Никита пишет:

    «Ну, по сути это последовательные два вызова move_to(). Можно их реализовать в одном (уменьшится количество запросов), но часто ли они применяются?»

    например, есть дерево:

    - level1
    — level 1.1
    — level 1.2
    — level 1.3
    — level 1.4

    Как тогда с помощью move_to() поменять level 1.2 и level 1.3 местами?

  15. BIakaVeron пишет:

    Повторюсь, тут не имеет смысла реализовывать сортировку таким вот жестким способом. Добавьте к записи в БД поле «порядковый номер» (или «вес», или еще как-нибудь). Вместо того, чтобы менять узлы местами «физически» (т.е. меняя их поля left и right), достаточно поменять значения данных полей. Не забывайте, что ветки 1.2 и 1.3 могут содержать достаточное количество дочерних узлов, а это увеличит количество обновляемых записей.
    А вот перенести ветку в совсем другое место дерева (не в пределах одного общего родительского узла) — это да, имеет смысл. Но обычно при этом обмена не происходит, переносится только одна ветвь.
    Все это, конечно, мое ИМХО.

  16. Никита пишет:

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

    В чём один из люсов left_key и right_key у Nested Sets? Да в том, что по left_key как раз и можно делать сортировку ORDER BY!

  17. BIakaVeron пишет:

    Да, плюс достаточно существенный, чтобы с ним считаться…
    Насчет перемещения узла относительно другого — как есть метод insert_near(). Ну, и все идет к тому, что скоро появится метод exchange($node1, $node2) ;)

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

  18. Никита пишет:

    А я вчера написал метод position уже для твоего класса. Поделюсь с миром в ближайшее время :)

  19. Никита пишет:

    Да, выглядит так:

    $item = $tree->find($id);
    $item->position($near_id, ‘auto|before|after’);

    Разумеетя, $id и $near_id потомки одного родителя одного и того же уровня.



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.