К содержанию

Как сгенерировать алиас с помощью Translit?

Как использовать возможности пакета translit для генерации транслитерированных алиасов?
Дело в том, что мне пришлось перегенерировать все uri ресуросв (с разным class_key). Использовал советы отсюда и отсюда.
В итоге у меня получился такой скомбинированный вариант, который я запускаю в консоли:

<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
header("Content-Type: text/html; charset=utf-8");

// Подключаем
define('MODX_API_MODE', true);
require 'index.php';

// Включаем обработку ошибок
$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');

$modx->exec("UPDATE modx_site_content SET uri='' WHERE alias=''");
$modx->exec("UPDATE modx_site_content SET uri = '' WHERE uri=alias");//удаляет uri равное alias
$modx->exec("UPDATE modx_site_content SET uri = '' WHERE alias = CONCAT(uri, '/')");//удаляет uri со слешем на конце равное alias
$modx->exec("UPDATE modx_site_content t1, (SELECT uri FROM modx_site_content GROUP BY uri HAVING COUNT(*) > 1)
t2 SET t1.uri = '' WHERE t2.uri = t1.uri AND uri_override = 0");//удаляет дубликаты uri на всякий пожарный

$modx->setLogLevel(1);
ini_set('max_execution_time', 7200);
ignore_user_abort(true);

$q = $modx->newQuery('modResource');
$q->andCondition(array(    
    'uri' => null,    
    'OR:uri:=' => '',   
    'OR:alias:=' => ''
));
$q->sortby('id');
$q->limit(3000);

$rows = $updated = 0;

$s = $q->prepare();
$s->execute();
foreach($modx->getCollection('modResource', $q) as $data){
    $rows++;
    $modx->error->reset();
    $modx->runProcessor('resource/update', $data->toArray());
    if($modx->error->hasError()){
        print_r($modx->error->getErrors());
        echo "\nНе обработана строка\n";
    }
    else {
        $updated++; 
        echo "\nОБРАБОТАНО\n";
    }
}

echo "\n==========================================\n";
echo "Всего найдено документов по условию: ". $modx->getCount('modResource', $q)."\n";
echo "\nОбработано строк: $rows\n";
echo "\nОбновлено: $updated\n\n\n";
С помощью такого подхода получилось обновить у половины ресурсов, остальная половина упрямо даёт результат Обновлено: 0. Комбинировал результаты этого скрипта как только мог.

Задача: хочу сам, ручками, используя возможности translit сгенерировать alias и записать ресурсам с пустыми алиасами. А после этого уже разбираться с uri.
Василий Столейков
Василий Столейков
23 июня 2015, 19:59
modx.pro
9 608
Реклама

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

Василий Столейков
Василий Столейков Проверенный
23 июня 2015, 23:12
Уже 2 дня занимаюсь обновлением alias-ов и uri…
Ресурсов довольно много, около 10 тысяч.
    Илья Уткин
    Илья Уткин Администратор
    24 июня 2015, 09:32
    У ресурса есть метод cleanAlias, который генерирует псевдоним:

    $title = $data->get('pagetitle') . '-' . $data->get('id');
    $alias = $data->cleanAlias($title);
    $data->set('alias', $alias);
    $modx->runProcessor('resource/update', $resource->toArray());
      Алексей
      Алексей Проверенный
      24 июня 2015, 11:22
      Давно задавался вопросом — возможно ли вызвать метод
      ->cleanAlias($title);
      не создавая ресурс? Недавно что-то читал по статическим методам в классах — это такой особый метод, который доступен без создания экземпляра объекта. Так вот, является ли метод ->cleanAlias(); статическием? и если да, как его вызвать не создавая объект resource?
        Илья Уткин
        Илья Уткин Администратор
        24 июня 2015, 11:30
        Можно же создать экземпляр класса, использовать его методы, а в базу его не записывать (не вызывать ->save())

        $generator = $modx->newObject('modResource');
        foreach ($files as $file) {
        	$file['name'] = $generator->cleanAlias($file['name']);
        }
          Алексей
          Алексей Проверенный
          24 июня 2015, 11:35
          это да. интересовало мнение специалиста ООП -) так собственно и делается, просто не вызывается метод
          ->save();
          . Но тогда где прелести статических методов? ))
            Іван Клімчук
            Іван Клімчук Администратор
            08 января 2016, 16:57
            В реализации это не статический метод, на то есть причины. Достаточно посмотреть в исходники.

            public function cleanAlias($alias, array $options = array()) {
                return $this->xpdo->call($this->_class, 'filterPathSegment', array(&$this->xpdo, $alias, $options));
            }
            Как видно, вызывается функция filterPathSegment в то же классе, которая уже отвечает за обработку непосредственно. Вот она уже статическая и при желании ее можно использовать напрямую.

            modResource::filterPathSegment($modx, $alias);
              Алексей
              Алексей Проверенный
              25 февраля 2016, 09:00
              почему-то в консоли не работает ни так
              $modx->filterPathSegment($alias)
              ни так
              modResource::filterPathSegment($modx, $alias);
              а вот так работает -)
              $res = $modx->newObject('modResource');
              $res->cleanAlias($alias);
                Сергей Шлоков
                Сергей Шлоков Эксперт
                25 февраля 2016, 09:23
                У меня работает.
                  Алексей
                  Алексей Проверенный
                  26 февраля 2016, 12:22
                  блин, у меня же там старючая версия modx -))) наверное поэтому
          Алексей
          Алексей Проверенный
          08 января 2016, 11:20
          да похоже что можно, только это приведет к «разрастанию» кода, что авторы модкс не допускают. Пару лет назад Марк сделал пулл-реквест, но он не прошел: github.com/modxcms/revolution/pull/620
            Іван Клімчук
            Іван Клімчук Администратор
            08 января 2016, 17:00
            Я выше написал как можно сделать, Джейсон другое решение предложил.
          Василий Столейков
          Василий Столейков Проверенный
          24 июня 2015, 11:47
          Классно, спасибо за этот метод! Но он почему-то не срабатывает.
          Я выбрал только один ресурс по id чтобы понаблюдать как заполнится поле alias у него, наблюдаю в phpMyAdmin. Но после срабатывания кода и попытки запуска процессора обновления поле остаётся пустым, то есть обновление не произошло!
          Вот изменённый код:
          <?php
          ini_set("display_errors",1);
          error_reporting(E_ALL);
          header("Content-Type: text/html; charset=utf-8");
          
          // Подключаем
          define('MODX_API_MODE', true);
          require 'index.php';
          
          // Включаем обработку ошибок
          $modx->getService('error','error.modError');
          $modx->setLogLevel(modX::LOG_LEVEL_INFO);
          $modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');
          
          
          
          // $modx->exec("UPDATE modx_site_content WHERE uri='prezentaczii/' SET uri=''");
          // $modx->exec("UPDATE modx_site_content WHERE uri='informacziya/' SET uri=''");
          // // $modx->exec("UPDATE modx_site_content SET uri = '' WHERE uri=alias");//удаляет uri равное alias
          $modx->exec("UPDATE modx_site_content SET uri='' WHERE alias=''");
          $modx->exec("UPDATE modx_site_content SET uri = '' WHERE alias = CONCAT(uri, '/')");//удаляет uri со слешем на конце равное alias
          $modx->exec("UPDATE modx_site_content t1, (SELECT uri FROM modx_site_content GROUP BY uri HAVING COUNT(*) > 1)
          t2 SET t1.uri = '' WHERE t2.uri = t1.uri AND uri_override = 0");//удаляет дубликаты uri на всякий пожарный
          
          $modx->setLogLevel(1);
          ini_set('max_execution_time', 7200);
          ignore_user_abort(true);
          
          $q = $modx->newQuery('modResource', array('id'=>'85'));
          $q->andCondition(array(    
              'uri' => null,    
              'OR:uri:=' => '',   
              'OR:alias:=' => ''
          ));
          $q->sortby('id');
          $q->limit(1);
          
          $rows = $updated = 0;
          
          $s = $q->prepare();
          $s->execute();
          foreach($modx->getCollection('modResource', $q) as $data){
          
              $rows++;
              $modx->error->reset();
          
              $title = $data->get('pagetitle') . '-' . $data->get('id');
              $alias = $data->cleanAlias($title);
              $data->set('alias', $alias);
          
              $modx->runProcessor('resource/update', $data->toArray());
              if($modx->error->hasError()){
                  print_r($modx->error->getErrors());
                  echo "\nНе обработана строка\n".$data->get('pagetitle');
              }
              else {
                  $updated++; 
                  echo "\nОБРАБОТАНО\n".$data->get('pagetitle');
              }
          }
          
          print "\n==========================================\nВсего найдено документов по условию: ". $modx->getCount('modResource', $q)."\n";
          echo "\nОбработано строк: $rows\n";
          echo "\nОбновлено: $updated\n\n\n";
          Результат выполнения кода:
          Не обработана строка Тут название ресурса с id = 85
          ==========================================
          Всего найдено документов по условию: 1
          Обработано строк: 1
          Обновлено: 0
          Или записать alias напрямую, без процессоров?
            Илья Уткин
            Илья Уткин Администратор
            24 июня 2015, 11:50
            Можно и напрямую, тогда надо будет самостоятельно сгенерировать еще и поле URI
              Василий Столейков
              Василий Столейков Проверенный
              24 июня 2015, 12:10
              Спасибо тебе!
              Этот кусок кода успешно записал мне alias-ы:
              foreach($modx->getCollection('modResource', $q) as $data){
              
                  $title = $data->get('pagetitle');
                  $id = $data->get('id');
                  $alias = $data->cleanAlias($title);
                  $data->set('alias', $alias);
              
                  if($modx->exec("UPDATE modx_site_content SET alias='$alias' WHERE id ='$id'")) {
                      echo "\nНе обработана строка: ".$data->get('pagetitle')." == ".$alias;
                  }
                  else {
                      $updated++; 
                      echo "\nОБРАБОТАНО: ".$data->get('pagetitle')." == ".$alias;
                  }
              }
              но с URI пока не могу разобраться, что именно из тех строк что ты мне показал использовать…
                Василий Столейков
                Василий Столейков Проверенный
                24 июня 2015, 12:29
                Если я не ошибаюсь, то вот этот метод формирует URI:
                $aliasPath = $data->getAliasPath($alias);
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        17