Переход от 2.0.6 REVO с частью функций EVO к 2.2.6 REVO.

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

  1. Отсутствие функций getDocumentChildren, getDocuments и documentIdentifier
  2. В ходе неправильного обновления слетает полностью древо ресурсов, из-за чего не работает функция getChildIds и все зависящее от этого дела.
  3. Ваш сайт делался в те времена, когда 1251 было реально крутой вещью и вам нужен utf-8
  4. Все остальные ошибки, которые вылезают в ходе перехода от 1251 к utf-8.

Все эти ошибки, я буду разбирать вот в каком порядке 3, 2, 4, 1.

И так ошибка №3
У нас есть наша волшебная база данных, в которых у нас всё храниться в 1251, а наш великолепный modx всё писал туда в UTF-8, в ходе чего мы имеем гигантский набор крякрозябл от которых нам естественно надо избавиться. Первый раз с подобной проблемой я столкнулся где-то месяца 4 назад, и тогда гуглил, и искал, и спрашивал в компьюнити, но тщетно. В итоге решение было написано мною самостоятельно. Но писано оно с использованием mysql обычного, поэтому возможны баги во время выполнения, или оно не зависит от этого, я так и не определил. Ниже привожу свой код на случай, если он кому-нибудь он понадобится.

$dbname = 'db_name';
        if (!mysql_connect('db_host', 'db_login', 'db_pass')) {
        print 'Could not connect to mysql';
        exit;
    }

    $result = mysql_list_tables($dbname);
    
    if (!$result) {
        print "DB Error, could not list tables\n";
        print 'MySQL Error: ' . mysql_error();
        exit;
    }
   
    while ($row = mysql_fetch_row($result)) {
                $sql_s = "ALTER TABLE ".$row[0]." CONVERT TO CHARACTER SET utf8";
                mysql_query($sql_s);
         $sql = "SELECT * FROM ".$row[0];
                 mysql_query('SET NAMES cp1251');
                 $res = mysql_query($sql);
                 while($rows = mysql_fetch_assoc($res))
                 {
                 $array_table[$row[0]][] = $rows;
                
                 $zapros = '';
                         foreach($rows as $key=>$value)
                         {
                                 $zapros .= ' , `'.$key.'` = "'.mysql_real_escape_string($value).'" ';
                         }
                         $zapros = substr($zapros, 2);
                          $sql_a = "UPDATE ".$row[0]." SET  ".$zapros." WHERE id = ".$rows['id'];
                        mysql_query('SET NAMES utf8');
                        mysql_query($sql_a);
                 }
    }


После выполнения кода, возникает ещё череда возможных ошибок, которые я опишу позже.
И так ошибка №2
Как выяснилось, стандартный вариант — на старую версию залить новое ядро и обновить — он вас на уровне соединения с базой пошлёт погулять, хотя допускаю, что это только мне так повезло, поэтому заливаем голый 2.2.6, потом ставим туда наш файл конфига и обновляем на основе нашей уже исправленной базы. В итоге получаем уже рабочую админку, но без всех наших компонентов. Чтобы они стали работоспособными, просто обновляем компоненты, и они работают, и никакие данные зависящее от этих компонентов у нас не пострадали.
Так же все эти действия приводят к тому, что у нас корректно работающее древо и отлично работают все необходимые нам новые функции.
Ошибка №4
И так, одна из ошибок обнаруженных мною изначально, это была ошибка
Resource URI already exists for resource id = 1; skipping duplicate resource URI for resource id = 507
Эта ошибка была в том, что у нас в ходе выполнения скрипта из ошибки 3, каким-то образом слетело поле uri, или же возможно это поле просто отсутствовало в предыдущей версии. Т.к. у меня они были абсолютно все пустые. И эту проблему опять же исправляет мой небольшой скрипт.

$dbname = 'db_name';
        if (!mysql_connect('db_host', 'db_name', 'db_pass')) {
        print 'Could not connect to mysql';
        exit;
    }
mysql_select_db($dbname);
  
				 $sql = "SELECT * FROM  `modx_site_content`";
                 
                 $res = mysql_query($sql);
			
                 while($rows = mysql_fetch_assoc($res))
                 {
                
                       echo  $sql_a = "UPDATE `modx_site_content` SET  uri ='".$rows['alias'].".html' WHERE id = ".$rows['id'];
                       echo '
';
                       mysql_query($sql_a);
                 }
    


Или как вариант, каждый документ ручками пересохранить, что иногда затруднительно.
Ещё одна проблема, которую мы можем встретить – это то, что режутся тайтлы, но это уже исправляется только вручную. И ещё одна крупная проблема, с которой я долг возился, из-за своей неопытности, но спасибо Agel_Nash — указал на эту простую ошибку, а именно невидимые символы, из-за них постоянно php кидал ошибку в синтаксисе. Чаще всего они вылазят в конце сниппетов, в вещах типа return $str; это хорошо заметно на скриншоте.


Ошибка №1

И так проблема заключается в том, что в сниппетах используются устаревшие функции, и вместо того, чтобы переписывать весь функционал сайта в новых канонах, проще использовать современные аналоги, которые как выяснилось не так просто нагуглить. И так, самая популярная функция, это
$modx->documentIdentifier

её аналог в современном виде
$modx->resource->get('id')


Замену этих двух функций я произвёл очень просто. Ещё на уровне бэкапа сайта, я открыл notepad и заменил везде старую строчку, на новую.
Следующая устаревшая функция, это
$results = $modx->getDocumentChildren(
    $id = 146,
    $active = 1,
    $deleted = 0,
    'id, pagetitle, longtitle, introtext',
    $where = '',
    $sort='menuindex',
    $dir='ASC',
    $limit = ''
);

Здесь нам на выручку приходит xpdo, спасибо vanchelo за помощь со скриптом, именно его вариант я представлю ниже.
$child = $modx->getChildIds(146, 10, array('context' => 'web'));
$collection = $modx->getCollection('modResource', array(
    'id:IN' => $child,
    'published' => true,
    'deleted' => false,
));

$output = array();
if ($collection) {
    foreach ($collection as $resource) {
        $output[] = $resource->toArray();
    }
}
return $output;


Следующая устаревшая функция — это getDocuments, пример использования:
$bread = $modx->getDocuments($ids,1,0,'id, pagetitle');

Ниже представлен вариант решения этой проблемы таким же образом, как и проблемы описанной выше.
$collection = $modx->getCollection('modResource', array(
    'id:IN' => $ids,
    'published' => true,
    'deleted' => false,
));

$output = array();
if ($collection) {
    foreach ($collection as $resource) {
        $output[] = $resource->toArray();
    }
}
return $output;


И ещё одна небольшая ошибка, которая в хоть редко, но вылезает.
Это проверка является ли ресурс директорией, раньше это возвращалось вот так
$modx->documentObject['isfolder']

Теперь же современный аналог вот эта функция:
$modx->resource->get('isfolder')


Вот в принципе и все основные проблемы, которые могут возникнуть в ходе переноса сайта со старой версии на новую. Спасибо за внимание, если вы дочитали досюда.

P.S. Жду любых комментариев, в том числе и по любому коду, жду всё — даже критику.

upd. Для ошибки №1 Отличной ссылкой поделился artdevue Ссылка с таблицей старых функций и новых аналогов.

14 комментариев

avatar
Собственно, тут и комментировать то нечего. Грамотно и по делу. По крайней мере алгоритм действий был наверное таким же, может детали какие-то отличались бы (но это уже от сайта зависит).
avatar
Зачетно. Что-тут еще скажешь… Теги правда подкачали, но от этого пост хуже не стал;-)

P.S. Перенес пост в блог «документация и уроки», т.к. вышла отличная памятка для начинающих.
Комментарий отредактирован 2013-03-16 21:16:23 пользователем Agel_Nash
avatar
А какие именно теги?
avatar
$modx->documentIdentifier

её аналог в современном виде
$modx->resource->get('id')
можно и так
$modx->resourceIdentifier

а вообще. все эти замены устаревших функций описанны здесь
rtfm.modx.com/display/revolution20/Summary+of+Legacy+Code+Removed+in+2.1

Ну а в ообщем за тему зачёт, думаю многим, кто ещё сидит на старых версиях модекса пригодиться :)
avatar
Спасибо за ссылку, я когда-то искал и уже потерял надежду на наличие этой статьи или подобной, не плохо было бы в русскую документацию, чтобы кто-нибудь перевёл эту статью. Ибо я искал по фраза типа, «Аналог getDocumentChildren в REVO» и «Аналоги старых функций в REVO» и «Аналоги функций EVO в REVO».
И всё было безуспешно.
avatar
Спасибо автору! У меня кстати вопрос похожий но проще — с 2.0.7 обновить до текущей надо. Это по каждой версии обновлять или первые 3-4 подряд после 2.0.7 так как там вроде бы было очень много изменений и уже потом только сразу бабахнуть на последнюю? ))
avatar
Я сразу бабахал на последнюю, а потом правки как в статье.
Только БЭКАП не забудьте сделать.
Комментарий отредактирован 2014-06-18 10:20:50 пользователем Ser1ous
avatar
Последнюю сразу бабахай, там все изменения уже присутствуют:)
avatar
как в пьессе — горе от ума)) я чтото помню было написано что при апгрейде на 2.0.9 сразу с 2.0.1 например — не пошло, вот и заморачиваюсь)) Уххх ладно, если ничего больше никто не напишет то как бабахну и уш потом сюда чиркану лог
avatar
Обновился ноне сразу и не до конца как я считаю

не сразу потомучто файлы не залил поверх тех что были от старой версии, но потом все гуд прошло. Все работает как бы, но…

SELECT *
FROM `workspaces`
LIMIT 0, 30

/var/www/modx/core/

так и содержит какой ту путь хотя я ожидал будет хотябы {core} Что и почему??
avatar
На локальном компе вс еработало а на хостинге началось такое что только админка работала))

Вот лог ошибок при попытке просмотра любого ресурса или очистки кеша:
/*
* MODX Console Output
*
* @date 2014-06-18 20:28:04
*/
Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 3

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 11

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 13

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 19

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 21

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 42

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 43

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 44

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 76

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 68

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 64

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 83

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 5

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 6

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 7

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 8

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 9

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 10

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 14

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 81

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 16

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 80

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 79

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 15

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 18

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 77

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 78

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 17

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 20

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 82

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 22

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 23

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 24

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 25

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 26

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 27

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 28

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 29

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 30

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 31

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 32

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 33

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 34

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 35

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 36

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 37

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 38

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 39

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 40

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 41

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 45

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 46

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 47

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 48

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 49

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 50

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 51

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 52

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 53

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 54

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 55

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 56

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 57

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 58

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 59

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 60

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 61

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 62

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 63

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 65

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 66

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 69

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 70

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 71

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 72

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 73

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 74

Resource URI  already exists for resource id = 2; skipping duplicate resource URI for resource id = 75

Processing automatic publishing dates

-> 0 documents were published.

-> 0 documents were unpublished.

Regenerating system settings cache: Refresh successful!

Regenerating the context caches

-> mgr: Refresh successful!

-> web: Refresh successful!

Clearing the lexicon topics cache: Refresh successful!


/* EOF */
avatar
пройдясь по индекс пшп вижу что все линни работают кроме последней:
$modx->handleRequest();
если ее отрубить то доходит парсер до конца файла пхп а если врубить то просто пустая страница и все

не работает ни с чпу ни без них тоесть просто по урлу
avatar
обратите внимание сайт на цмс модх не работает 2й день — поддержите проект и самую хорошую цмску чтоб не было потом печальных постов про точ то эта цмс якобы не очень и коммьюнити тоже не очень активное
avatar
Bob Ray, посоветовал сделать
<?php
$docs = $modx->getCollection('modResource');
foreach ($docs as $doc) {
    $doc->save();
}
return 'Finished!';


что добавило алиас ко всем ресурсам и все страницы начали грузиться теперь. В тоже время была часть проблемы в том что вэйфайндер не грузился и валил страницу — выяснилось что он был очень старой версии 11 года и после обновления — все заработало — зашуршало как веник
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.