Как формируется menuindex?

Приветствую

Не до конца понимаю алгоритм работы menuindex ресурса в MODX. Как я понял, menuindex отображает порядок следования материалов в меню или в его ветках, но есть одна вещь, в которой прошу вашего совета.

Итак, имеем, к примеру, вложенное меню. По логике, да и по факту тоже, первый пункт меню или подменю должен быть обозначен нулем — так оно и есть, но дальше начинаются непонятные мне вещи.

Второй пункт меню в админке может быть обозначен 1, 2 или 3 (на скриншоте),

а в базе данных может отличаться на одну цифру от той, что указана в админке. Ну ладно, значение в админку подставляется из БД, значит, дело в кеше. Предположим, что мы его почистили и в админке стали отображаться фактические данные из админки, но и тут есть странность. В БД могут быть два одинаковых menuindex или пропуски между ними (все на втором скриншоте).


Почему так происходит, поясните пожалуйста такое поседение?
weranda
20 марта 2019, 10:33
modx.pro
1
1 121
0

Комментарии: 3

Владимир
20 марта 2019, 11:11
0
Пункты меню перетаскивались из другого раздела например.
    Игорь
    20 марта 2019, 13:52
    +1
    Как понимаю есть два поля в БД — id и menuindex. Цифра в скобках это id, позиция в меню — menuindex.
      Николай
      20 марта 2019, 18:44
      0
      В деталях не знаю, но menuindex формируется исходя из значений menuindex соседних ресурсов, на одном уровне вложенности относительно их родителя. Другие уровни вложенности в расчёт не берутся. Если нужно выстроить menuindex по порядку с учётом вложенности ресурсов, то я такой скрипт использую:

      <?php
      
      global $menuindex, $modx;
      
      function updateMenuIndex($id) {
          
          global $menuindex, $modx;
          
          $childsIds = $modx->getChildIds($id,1,array('context' => 'web'));                   
          if(!count($childsIds)) return;
          
          $q = $modx->newQuery('modResource');
          $q->where( ['id:IN' => $childsIds] ); 
          $q->sortby('menuindex', 'ASC');
          
          $result = $modx->getCollection('modResource', $q);
          
          foreach($result as $key=>$res) {
              $menuindex++;
      
              $res->set('menuindex', $menuindex);
              $res->save();
              //echo "$menuindex - {$res->pagetitle} ({$res->id})
      ";
              
              updateMenuIndex($res->get('id'));
          }
      }
      
      updateMenuIndex(0);
      return "menuindex обновлены у $menuindex ресурсов";

      Можно в сниппете использовать, в консоли вызвать, а можно плагин создать, я вешаю на событие OnBeforeCacheUpdate. При чистке кеша идёт сортировка menuindex, и в итоге одинаковых не встречается. На 2045 ресурсах показатели такие:

      SQL time: 0.3292 s
      SQL queries: 3924
      PHP time: 4.0855 s
      Total time: 4.4147 s
      Memory: 50 MB

      То есть, если ресурсов реально много, то памяти может не хватить…
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        3