Skip to content

Instantly share code, notes, and snippets.

@Dmi3yy
Last active February 4, 2024 10:50
  • Star 4 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Dmi3yy/48b153d5ab60e2524e81170d38bf4bcd to your computer and use it in GitHub Desktop.
Evo 3 SiteContent Model - RU

Работа с Деревом документов через SiteContent

Вступление

Для начала рекомендую ознакомиться с документацией по Eloquent на сайте Laravel https://laravel.com/docs/6.x/queries так как в Evo логика работы с базой такая же, это не только удобно но еще и дает возможность находить информацию что и как сделать не только в рамках Evolution CMS.

Работа с дополнительными полями (TV)

Спасибо Webber за DLSiteContent, https://github.com/webber12/DLSiteContent основные методы работы с TV так же интегрированны в ядро.

Сортировка и фильтр по ТВ

$docs = SiteContent::withTVs(['price', 'titl'])
            ->active()
            ->where('parent', 0)
            ->where('tv_price.value', '>', '150')
            ->orderBy('tv_price.value', 'desc')
            ->orderBy('pagetitle', 'asc')
            ->get();

Сортировка и фильтрация по ТВ с приведением типа (и без него)

$docs = SiteContent::withTVs(['price', 'brand'])
            ->active()
            ->where('parent', 0)
            ->tvFilter("tv:price:>:150:UNSIGNED;tv:price:<:600:UNSIGNED;tv:brand:in:а,б,в;tv:brand:!null;")
            ->tvOrderBy("price asc UNSIGNED, brand asc")
            ->orderBy('pagetitle', 'asc')
            ->get();

Фильтрация и сортировка по ТВ с приведением типа (и без него) с учетом значений по-умолчанию

$docs = SiteContent::withTVs(['price:d', 'brand'])
            ->active()
            ->where('parent', 0)
            ->tvFilter("tvd:price:>:150:UNSIGNED;tv:brand:in:а,б,в")
            ->tvOrderBy("price:d asc UNSIGNED, brand asc")
            ->orderBy('pagetitle', 'asc')
            ->get();   

Работаем с getTvList (Актуально при большом количестве ТВ)

$result = SiteContent::where('parent', 0)
            ->active()
            ->get();
$docs = SiteContent::tvList($result, ['price', 'brand']);

tagsData (контроллер site_content_tags) с сортировкой pub_date/createdon

$docs = SiteContent::where('parent', 1)
            ->active()
            ->tagsData('17:5,7,8')
            ->orderByDate()
            ->get();

Closure Table - работа с деревом документов

За основу реализации был взят данный компонент для Laravel https://github.com/franzose/ClosureTable, но интегрирован в ядро.

Получение документов из корня, 2 уровня вложенности

$docs = SiteContent::GetRootTree(2)
            ->withTVs(['test'], ':', true)
            ->get()
            ->toTree()
            ->toArray();

обратите внимание на withTVs в методе GetRootTree необходимо передавать с доп параметрами

Получение всех дочерних документов из документа с ID 2 c TV параметрами

$docs = SiteContent::descendantsOf(2)
            ->withTVs(['tv1','tv2'])
            ->get()
            ->toTree()
            ->toArray();

Получение дочерних документов из документа с ID 2 c уровнем вложенности 3

$docs = SiteContent::descendantsOf(2)
            ->where('depth', '<', 4)
            ->get()
            ->toTree()
            ->toArray();

Получение id дочерних документов из ID 2 без учета вложенных документов

$docs = SiteContent::find(2)
            ->getChildren()
            ->pluck('id')
            ->toArray();

Получение родительских документов документа с ID 7

$docs = SiteContent::find(7)
            ->ancestors()
            ->orderBy('depth', 'desc')
            ->get();

Cписок доступных методов из Closure Table

            ancestors()
            ancestorsOf($id)
            ancestorsWithSelf()
            ancestorsWithSelfOf($id)
            descendants()
            descendantsOf($id)
            descendantsWithSelf()
            descendantsWithSelfOf($id)
            childNode()
            childNodeOf($id)
            childAt(int $position)
            childOf($id, int $position)
            firstChild()
            firstChildOf($id)
            lastChild()
            lastChildOf($id)
            childrenRange(int $from, int $to = null)
            childrenRangeOf($id, int $from, int $to = null)
            sibling()
            siblingOf($id)
            siblings()
            siblingsOf($id)
            neighbors()
            neighborsOf($id)
            siblingAt(int $position)
            siblingOfAt($id, int $position)
            firstSibling()
            firstSiblingOf($id)
            lastSibling()
            lastSiblingOf($id)
            prevSibling()
            prevSiblingOf($id)
            prevSiblings()
            prevSiblingsOf($id)
            nextSibling()
            nextSiblingOf($id)
            nextSiblings()
            nextSiblingsOf($id)
            siblingsRange(int $from, int $to = null)
            siblingsRangeOf($id, int $from, int $to = null)                                         

Более детально так же можно ознакомиться тут : https://github.com/franzose/ClosureTable/blob/master/README.md

Итог

В целом работая с компонентами Laravel мы получаем больше свободы и более понятный код. К примеру если использовать все описанное выше то нет необходимости в Сниппете DocLister, собстввнно пооэтому он и был удален из набора по умолчанию в Evo 3.

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

@iv-litovchenko
Copy link

iv-litovchenko commented Mar 19, 2021

Вопрос небольшой появился про TV-поля.
А как выбрать TV-поля типа связи?
В примере показано как выбирать и фильтровать обычные поля типа text, varchar, int....

$docs = SiteContent::withTVs(['price', 'titl']);
->where('tv_price.value', '>', '150')
            ->orderBy('tv_price.value', 'desc')

@argirov83
Copy link

Интересно посмотреть на реализацию function scopeTvFilter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment