Version: current

       1 <?php
       2 /*
       3  * Задача конвертации (2.6 -> 3.1)
       4  *
       5  * @author menedem, dvp
       6  */
       7 class ConvertFrom26Task extends BuildTask {
       8
       9     static $dbSuffix = '-c';
      10     static $fileSuffix = '/../convert';
      11     static $debug = false;
      12
      13     private $siteName;
      14     private $oldDB;
      15     private $oldPath;
      16     private $imageMapping = array(); //массив соответствий страрых и новых ID изображений
      17     private $fileMapping = array(); //массив соответствий страрых и новых ID файлов
      18
      19     private $fileFolderChanging = array(); //массив файлов, у которых можно менять папку - импортированные из корня или из виз.реда (не из структуры папок)
      20
      21     private $productsMapping = array(); //массив соответствий страрых и новых ID товаров в каталоге (для импорта истории заказов)
      22
      23     // !!! TODO хеш oldID => oldUrl
      24     // !!! TODO хеш oldUrl => newUrl
      25
      26     private $specCatalogMapping = array();
      27
      28     // хеш родитель-ребенок
      29     private $parentRelationsMapping = array();
      30
      31     // хеш ID-URL
      32     private $urlMapping = array();
      33
      34     // хеш старыйURL->новыйURL
      35     private $OldNewUrlMapping = array();
      36
      37
      38     /**
      39      * Типы изображений webylon 2.6
      40      */
      41     static $imageExtensions = array(
      42         0 => 'gif',
      43         1 => 'jpg',
      44         2 => 'png',
      45         20 => 'swf',
      46     );
      47
      48     /**
      49      * Типы файлов webylon 2.6
      50      */
      51     static $fileExtensions = array(
      52         '1'   => 'doc',
      53         '2'   => 'xls',
      54         '3'   => 'zip',
      55         '4'   => 'rtf',
      56         '5'   => 'xls',
      57         '6'   => 'ppt',
      58         '7'   => 'pdf',
      59         '11'  => 'docx',
      60         '12'  => 'pptx',
      61         '20'  => 'swf',
      62         '22'  => 'xlsx',
      63         '91'  => 'dbf',
      64         '92'  => 'mp3',
      65         '100' => 'gif',
      66         '101' => 'jpg',
      67         '201' => 'avi',
      68         '300' => 'xml',
      69         '500' => 'csv',
      70         '600' => 'txt',
      71         '700' => 'flv',
      72         '800' => 'mp3',
      73         '900' => 'rar',
      74         '901' => '7z',
      75         '902' => 'arj'
      76     );
      77
      78     static $attachedGalleryParams = array(
      79         'MATERIAL_TREE' => array('SMODE' => 0, 'PART' => 0),
      80         'MATERIALS' => array('SMODE' => 0, 'PART' => 1),
      81         'NEWS' => array('SMODE' => 0, 'PART' => 2),
      82         'CATALOG_TREE' => array('SMODE' => 0, 'PART' => 3),
      83         'ARTICLE_TREE' => array('SMODE' => 0, 'PART' => 5),
      84         'FAQ_TREE' => array('SMODE' => 0, 'PART' => 8),
      85         'LINK_TREE' => array('SMODE' => 0, 'PART' => 9),
      86         'EVENTS' => array('SMODE' => 0, 'PART' => 16),
      87         'ANONS' => array('SMODE' => 0, 'PART' => 17),
      88         'MGAL_STRUCTURE' => array('SMODE' => 0, 'PART' => 21),
      89
      90         'CATALOG' => array('SMODE' => 1, 'PART' => 3),
      91         'FAQ' => array('SMODE' => 1, 'PART' => 8),
      92         'LINKS' => array('SMODE' => 1, 'PART' => 9),
      93         'ARTICLES' => array('SMODE' => 1, 'PART' => 5)
      94     );
      95
      96     //Статусы заказов
      97     static $orderStatuses = array(
      98         'new' => 'Unpaid',
      99         'payment' => 'Unpaid',
     100         'process' => 'Processing',
     101         'done' => 'Complete',
     102     );
     103
     104     //Способы оплаты (добавляется в комментарий)
     105     static $paymentMethod = array(
     106         'cash' => 'Оплата наличными',
     107         'cheque' => 'Безналичный расчёт',
     108         'online' => 'По банковской карте'
     109     );
     110
     111     static function base_dir() {
     112         $path = TEMP_FOLDER . '/convert26';
     113         if (!is_dir($path)) {
     114             mkdir($path, 0775);
     115         }
     116         return $path;
     117     }
     118
     119     static function correct_url_segment($url) {
     120         $url = preg_replace('(^_+)', '', $url);
     121         return $url;
     122     }
     123
     124     function run($request) {
     125         if (!Director::is_cli() && !Permission::check("ADMIN") ) {
     126             print "Permission denied";
     127             return;
     128         }
     129
     130         // отключаем протоколирование
     131         if (class_exists('LogItem')) {
     132             LogItem::enable(false);
     133         }
     134         Versioned::$versions_ttl = 1;
     135
     136         // отправляем всеEmail на test, иначе письма могут уходить клиентам.
     137         Email::send_all_emails_to('test@mediaweb.ru');
     138
     139         $this->siteName = split(',', $request->getVar('site'));
     140         $this->siteName[] = '.*\.dev.?\.mediaweb\.ru';
     141         $this->oldPath = realpath(BASE_PATH . self::$fileSuffix);
     142
     143         global $databaseConfig;
     144         $this->oldDB = $databaseConfig['database'] . self::$dbSuffix;
     145
     146         print "oldSite:'{$this->siteName[0]}' oldPath:'{$this->oldPath}' oldDB:'{$this->oldDB}'\n\n";
     147
     148         if ($page = DataObject::get_one('SiteTree', "UrlSegment='about'")) {
     149             $page->doUnpublish();
     150             $page->delete();
     151         }
     152         if ($page = DataObject::get_one('SiteTree', "UrlSegment='contacts'")) {
     153             $page->doUnpublish();
     154             $page->delete();
     155         }
     156
     157
     158         //Импорт пользователей
     159         $this->importSiteUsers(1);//admins
     160         $this->importSiteUsers();//users
     161
     162         $this->importImageLibrary();
     163         $this->importFileLibrary();
     164
     165         // Подумать, возможно вычищать все страницы сайта 3.1 перед импортом, т.к. по умолчанию там уже создано 4(вроде) страницы
     166         // dvp: Скорее всего нет т.к. многие модули создают обязательнные страницы, если и удалять то оставлять ErrorPage и после конвертации вызывать dev/build
     167
     168         // SiteConfig
     169         $siteConfig = SiteConfig::current_site_config();
     170
     171         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".SITE_SETTINGS WHERE PART=0");
     172         if ($records->numRecords() > 0) {
     173             foreach($records as $record) {
     174                 if ($record['ATTRIBUTE'] == 'DESCRIPTION')
     175                     $siteConfig->MetaDescription = trim($record['VALUE']);
     176                 if ($record['ATTRIBUTE'] == 'KEYWORDS')
     177                     $siteConfig->MetaKeywords = trim($record['VALUE']);
     178                 if ($record['ATTRIBUTE'] == 'COUNTERS')
     179                     $siteConfig->HtmlFooterBlock = trim($record['VALUE']);
     180                 if ($record['ATTRIBUTE'] == 'BANNERS')
     181                     $siteConfig->HtmlRightBlock = trim($record['VALUE']);
     182                 if ($record['ATTRIBUTE'] == 'CINFO') //В Webylon 3.1.1 разбита на несколько полей, но складываем все в поле Address
     183                     $siteConfig->Address = trim($record['VALUE']);
     184                 if ($record['ATTRIBUTE'] == 'ADMIN_MAIL')
     185                     $siteConfig->AdminEmail = trim($record['VALUE']);
     186                 if ($record['ATTRIBUTE'] == 'SITE_NAME')
     187                     $siteConfig->Title = trim($record['VALUE']);
     188             }
     189         }
     190
     191         $siteConfig->write();
     192
     193         // Создание главной
     194         $homePage = DataObject::get_one('HomePage');
     195         if (!$homePage) $homePage = new HomePage;
     196
     197         $homePage->Title = 'Главная';
     198         $homePage->URLSegment = 'home';
     199         $homePage->Sort = 1;
     200
     201         $homePage->Content = $this->correctPathInContent(DB::query("SELECT value FROM \"{$this->oldDB}\".SITE_ATTRIBUTES WHERE ATTRIBUTE='MAINPAGE'")->value());
     202         $homePage->doPublish();
     203         $this->OldNewUrlMapping[$this->siteName[0]] = $homePage->AbsoluteLink();
     204
     205         $records = DB::query("SELECT * FROM  \"{$this->oldDB}\".MATERIAL_TREE WHERE DELETED=0 AND PARENT=-1 ORDER BY MORDER");
     206         if ($records->numRecords() > 0) {
     207             foreach($records as $record) {
     208                 $this->parentRelationsMapping["MATERIAL_TREE_" . $record['ID']] = "MATERIAL_TREE_0";
     209                 $this->importPageWithChildren($record);
     210             }
     211         }
     212
     213         //Анонсы в 2.6 не привязаны к коренвым страницам, а находятся только в таблице ANONS
     214         $this->importAnnouncement();
     215
     216         //Отзывы в 2.6 не привязаны к коренвым страницам, а находятся только в таблице GUEST
     217         $this->importGuestbook();
     218
     219         $this->importForms(); //Импортируем формы
     220
     221         $this->importOrders(); //Импортируем историю заказов
     222
     223         // перемещаем файлы из общих папок ("assets/images", "assets/images/root", "assets/images/Из документов", "assets/files", "assets/files/root", "assets/files/Из документов")
     224         // сначала обновляем инофрмацию о ссылках на файлы и картинки в виз.реде
     225         $pages = DataObject::get('SiteTree');
     226         foreach($pages as $page) {
     227             $page->syncLinkTracking();
     228         }
     229         //а затем перемещаем файлы из общих папок ("assets/images", "assets/images/root", "assets/images/Из документов", "assets/files", "assets/files/root", "assets/files/Из документов" )
     230         // в папки вида: "assets/images/Imported_$N"
     231         $this->correctImageFolders();
     232
     233         $this->correctFileFolders();
     234
     235         if (is_file(self::base_dir() . '/url_map.txt')) {
     236             unlink(self::base_dir() . '/url_map.txt');
     237         }
     238         if (count($this->OldNewUrlMapping)) {
     239             $lines = '';
     240             foreach($this->OldNewUrlMapping as $oldURL=>$newURL) {
     241                 $lines .= "{$oldURL} {$newURL}\n";
     242             }
     243             file_put_contents(self::base_dir() . '/url_map.txt', $lines);
     244         }
     245     }
     246
     247     //Импорт истории заказов
     248     function importOrders() {
     249         if (!class_exists('Cart')) {
     250             return false;
     251         }
     252         if (!$this->checkMySQLTableExists("CATALOG_HISTORY")) {
     253             echo "Таблицы CATALOG_HISTORY нет в БД\n";
     254             return false;
     255         }
     256
     257         if (!$this->checkMySQLTableExists("CATALOG_HISTORY_PROD")) {
     258             echo "Таблицы CATALOG_HISTORY_PROD нет в БД\n";
     259             return false;
     260         }
     261
     262         $orders = @DB::query("SELECT * FROM \"{$this->oldDB}\".CATALOG_HISTORY WHERE DELETED = 0");
     263         if ($orders->numRecords() > 0) {
     264             foreach($orders as $order) {
     265                 $this->importOrder($order);
     266             }
     267         }
     268     }
     269
     270     function importOrder($order) {
     271         $orderItems = DB::query("SELECT * FROM \"{$this->oldDB}\".CATALOG_HISTORY_PROD WHERE DELETED = 0 AND CLIENT = {$order['ID']}");
     272         if ($orderItems->numRecords() > 0) {
     273             foreach($orderItems as $orderItem) {
     274                 $this->importOrderItem($orderItem);
     275             }
     276         }
     277         $newOrder = new Order();
     278         $newOrder->ID = $order['ID'];
     279         $newOrder->ClientName = ($order['FIO']) ? $order['FIO'] : '-';
     280         $newOrder->Email = $order['EMAIL'];
     281         $newOrder->Phone = ($order['PHONE']) ? $order['PHONE'] : '-';
     282         $newOrder->ClientNotes = $order['COMMENTS'];
     283         $newOrder->AdminNotes = self::$paymentMethod[$order['PAYTYPE']];
     284         $newOrder->ItemsTotal = $order['TOTAL'];
     285         $newOrder->GrandTotal = $order['TOTAL'];
     286         $newOrder->Created = $order['CREATE_TIME'];
     287         $newOrder->LastEdited = $order['MODIFY_TIME'];
     288         $newOrder->Status = self::$orderStatuses[$order['STATUS']];
     289         if ($newOrder->Items() && $newOrder->Items()->Count() > 0) { //Заказ дает сохраниться, только если у него есть Items
     290             $newOrder->write();
     291         }
     292     }
     293
     294     function importOrderItem($orderItem) {
     295         if (!isset($this->productsMapping[$orderItem['PRODUCT']]))
     296             return false;
     297         $newOrderItem = new OrderItem();
     298         $newOrderItem->Title = $orderItem['PRODUCT_LABEL'];
     299         $newOrderItem->Quantity = $orderItem['NUMS'];
     300         $newOrderItem->ItemPrice = $orderItem['SUM'];
     301         $newOrderItem->LinkedID = $this->productsMapping[$orderItem['PRODUCT']];
     302         $newOrderItem->OrderID = $orderItem['CLIENT'];
     303         $newOrderItem->write();
     304         return $newOrderItem;
     305
     306     }
     307
     308     //Импорт поддерева
     309     function importPageWithChildren($page, $parentID = 0) {
     310         $newPageID = 0;
     311         if (isset($page['SYSPART'])) {
     312             if ($page['SYSPART'] ==  21) {
     313                 $newPageID = $this->importPhotoGallery($page, $parentID);
     314             }
     315             elseif ($page['SYSPART'] ==  16) {
     316                 $newPageID = $this->importEvents($page, $parentID);
     317             }
     318             elseif ($page['SYSPART'] ==  8) {
     319                 $newPageID = $this->importFAQ($page, $parentID);
     320             }
     321             elseif ($page['SYSPART'] == 5 ) {
     322                 $newPageID = $this->importPublications($page, $parentID);
     323             }
     324             elseif ($page['SYSPART'] == 3 ) {
     325                 $newPageID = $this->importCatalog($page, $parentID);
     326             }
     327             elseif ($page['SYSPART'] == 2 ) {
     328                 $newPageID = $this->importNews($page, $parentID);
     329             }
     330             elseif ($page['SYSPART'] < 2) {
     331                 $newPageID = $this->importDocPage($page, $parentID);
     332             }
     333         } else {
     334             $newPageID = $this->importDocPage($page, $parentID);
     335         }
     336
     337         if ($newPageID) {
     338             if (isset($page['PARENT'])) {
     339                 // если тип страницы MATERIAL_TREE (у нее есть поле PARENT) - для MATERIALS детей не ищем
     340                 //Импортируем сначала из MATERIAL_TREE
     341                 $records = DB::query("SELECT * FROM \"{$this->oldDB}\".MATERIAL_TREE WHERE DELETED=0 AND PARENT={$page['ID']}");
     342                 if ($records->numRecords() > 0) {
     343                     foreach($records as $record) {
     344                         //debug::dump($record);
     345                         $this->parentRelationsMapping["MATERIAL_TREE_" . $record['ID']] = "MATERIAL_TREE_" . $page['ID'];
     346                         $this->importPageWithChildren($record, $newPageID);
     347
     348                     }
     349                 }
     350                 //затем из MATERIAL
     351                 $records = DB::query("SELECT * FROM \"{$this->oldDB}\".MATERIALS WHERE DELETED = 0 AND FOLDER={$page['ID']}");
     352                 if ($records->numRecords() > 0) {
     353                     foreach($records as $record) {
     354                         $this->parentRelationsMapping["MATERIALS_" . $record['ID']] = "MATERIAL_TREE_" . $page['ID'];
     355                         $this->importPageWithChildren($record, $newPageID);
     356                     }
     357                 }
     358             }
     359         }
     360         else {
     361             // !!! понему может не быть??? где реакция ???
     362         }
     363     }
     364
     365     //Создаем обычные страницы (DocPage)
     366     function importDocPage($page, $parentID) {
     367         if (isset($page['SYSPART']) && $page['SYSPART'] > 1) {
     368             return false;
     369         }
     370
     371         $label = Convert::raw2sql($page['LABEL']);
     372         $newPage = DataObject::get_one('DocPage', "ParentID = {$parentID} AND Title = '{$label}'");
     373         if (!$newPage)
     374             $newPage = new DocPage;
     375
     376         $newPage->ParentID = $parentID;
     377         $newPage->Title = $page['LABEL'];
     378         $newPage->Created = $page['CREATE_TIME'];
     379         $newPage->LastEdited = $page['MODIFY_TIME'];
     380         $newPage->URLSegment = self::correct_url_segment($page['VPATH']);
     381
     382         $newPage->MetaKeywords = $page['KEYWORDS'];
     383         $newPage->MetaDescription = $page['DESCR'];
     384         $newPage->Sort = $page['MORDER'];
     385
     386         if ($page['AUTH'])
     387             $newPage->CanViewType = 'LoggedInUsers';
     388
     389
     390         $newPageID = $newPage->write();
     391         $this->correctPathInContent($page['DESCRIPTION'], $newPage);
     392         if ($page['ACTIVE'] == 'Y') {
     393             $newPage->doPublish();
     394         }
     395
     396         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     397         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
     398         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     399             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
     400                 $this->OldNewUrlMapping[$path] = $newPage->Link();
     401             }
     402         }
     403
     404         //Добавляем прикрепленные изображения и файлы
     405
     406
     407         $this->importLinkedImages($page, $newPage, $table);
     408         $this->importLinkedFiles($page, $newPage, $table);
     409
     410         return $newPageID;
     411     }
     412
     413     //------------  ФОТОГАЛЕРЕЯ -------------------*/
     414     //Создаем страницу фотогалереи
     415     function importPhotoGallery($page, $parentID) {
     416
     417         if (isset($page['SYSPART']) && $page['SYSPART'] != 21) return false;
     418
     419         if (!class_exists('PhotoGalleryPage')) {
     420             return false;
     421         }
     422
     423         $label = Convert::raw2sql($page['LABEL']);
     424         $newPage = DataObject::get_one('PhotoGalleryPage', "ParentID = {$parentID} AND Title = '{$label}'");
     425         if (!$newPage)
     426             $newPage = new PhotoGalleryPage();
     427
     428         $newPage->ParentID = $parentID;
     429         $newPage->Title = $page['LABEL'];
     430         $newPage->Created = $page['CREATE_TIME'];
     431         $newPage->LastEdited = $page['MODIFY_TIME'];
     432         $newPage->URLSegment = self::correct_url_segment($page['VPATH']);
     433         $newPage->Content = $this->correctPathInContent($page['DESCRIPTION']);
     434         $newPage->MetaKeywords = $page['KEYWORDS'];
     435         $newPage->MetaDescription = $page['DESCR'];
     436         $newPage->Sort = $page['MORDER'];
     437         if ($page['AUTH'])
     438             $newPage->CanViewType = 'LoggedInUsers';
     439
     440         $newPageID = $newPage->write();
     441         $newPage->getCMSFields(); // костылек, чтоб создавалась папака галереи
     442         if ($page['ACTIVE'] == 'Y') {
     443             $newPage->doPublish();
     444         }
     445         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     446         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
     447         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     448             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
     449                 $this->OldNewUrlMapping[$path] = $newPage->Link();
     450             }
     451         }
     452         $this->importPhotoAlbum($page, $newPageID);
     453
     454         return $newPageID;
     455     }
     456
     457     //Импорт фотоальбомов
     458     function importPhotoAlbum($page, $newPageID) {
     459
     460         if (!$this->checkMySQLTableExists("MGAL_STRUCTURE")) {
     461             echo "Таблицы MGAL_STRUCTURE нет в БД\n";
     462             return false;
     463         }
     464
     465         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".MGAL_STRUCTURE WHERE FOLDER={$page['SYSFOLDER']}");
     466         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     467         if ($records->numRecords() > 0) {
     468             foreach($records as $record) {
     469                 $this->parentRelationsMapping["MGAL_STRUCTURE_" . $record['ID']] = "{$table}_" . $page['ID'];
     470                 $label = Convert::raw2sql($record['LABEL']);
     471                 $newPage = DataObject::get_one('PhotoAlbumPage', "ParentID = {$newPageID} AND Title = '{$label}'");
     472                 if (!$newPage)
     473                     $newPage = new PhotoAlbumPage();
     474                 $newPage->ParentID = $newPageID;
     475                 $newPage->Title = $record['LABEL'];
     476                 $newPage->Content = $this->correctPathInContent($record['DESCRIPTION']);
     477                 $newPage->Description = $record['ANONS'];
     478                 $newPage->RandomCover = true;
     479                 $newPage->URLSegment = self::correct_url_segment($record['VPATH']);
     480                 $newPage->Created = $record['CREATE_TIME'];
     481                 $newPage->LastEdited = $record['MODIFY_TIME'];
     482                 $newPage->Sort = $record['MORDER'];
     483                 if ($record['AUTH'])
     484                     $newPage->CanViewType = 'LoggedInUsers';
     485
     486                 $newPage->write();
     487                 $newPage->getCMSFields(); // костылек, чтоб создавалась папака альбома
     488
     489                 if ($record['ACTIVE'] == 1) { //Здесь почему то ACTIVE типа boolean
     490                     $newPage->doPublish();
     491                 }
     492                 $this->urlMapping["MGAL_STRUCTURE_" . $record['ID']] = $record['VPATH'];
     493                 if (isset($record['ACTIVE']) && ($record['ACTIVE'] == 'Y')) {
     494                     if ($path = $this->getAbsoluteOldPath("MGAL_STRUCTURE_" . $record['ID'])) {
     495                         $this->OldNewUrlMapping[$path] = $newPage->Link();
     496                     }
     497                 }
     498                 $this->importAlbumImages($record, $newPage);
     499             }
     500         }
     501     }
     502
     503     function importAlbumImages($page, $album) {
     504         $params = self::$attachedGalleryParams['MGAL_STRUCTURE'];
     505         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".GALLERY_FILES WHERE SMODE={$params['SMODE']} AND PART={$params['PART']} AND MATERIAL={$page['ID']} ORDER BY INNER_PRIOR");
     506
     507         $album->Items()->removeAll();
     508
     509         if ($records->numRecords() > 0) {
     510             foreach($records as $record) {
     511                 if (!isset($this->imageMapping[$record['FILE']])) continue;
     512                 $imageID = $this->imageMapping[$record['FILE']];
     513                 $image = DataObject::get_by_id('Image', $imageID);
     514                 if (!$image) continue;
     515                 //перемещаем изображение в папку альбома галереи
     516                 $image->ParentID = $album->FolderID;
     517             //  echo '**'.$image->ParentID.'**';
     518                 $image->write();
     519
     520                 /* теперь в фотогалерее хранятся обычные Image
     521                 $image->ClassName = 'PhotoAlbumImage';
     522                 $image->write();
     523                 */
     524
     525
     526                 $newAlbumItem = new PhotoAlbumItem();
     527                 $newAlbumItem->ImageID = $image->ID;
     528                 $newAlbumItem->Caption = $record['LABEL'];
     529                 $newAlbumItem->AlbumID = $album->ID;
     530                 $newAlbumItem->SortOrder = $record['INNER_PRIOR'];
     531                 $newAlbumItem->write();
     532                 $album->Items()->add($newAlbumItem);
     533             }
     534         }
     535     }
     536
     537     //------------  НОВОСТИ -------------------*/
     538     //Создаем NewsHolder
     539     function importNews($page, $parentID) {
     540         if (isset($page['SYSPART']) && $page['SYSPART'] != 2) {
     541             return false;
     542         }
     543
     544         if (!class_exists('NewsHolder')) {
     545             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль news!\n";
     546             return false;
     547         }
     548
     549         $label = Convert::raw2sql($page['LABEL']);
     550         $newNews = DataObject::get_one('NewsHolder', "ParentID = {$parentID} AND Title = '{$label}'");
     551         if (!$newNews)
     552             $newNews = new NewsHolder();
     553
     554         $newNews->ParentID = $parentID;
     555         $newNews->Title = $page['LABEL'];
     556         $newNews->Created = $page['CREATE_TIME'];
     557         $newNews->LastEdited = $page['MODIFY_TIME'];
     558         $newNews->URLSegment = self::correct_url_segment($page['VPATH']);
     559         // !! нет его на 3.1 $newNews->Content = $this->correctPathInContent($page['DESCRIPTION']);
     560         $newNews->MetaKeywords = $page['KEYWORDS'];
     561         $newNews->MetaDescription = $page['DESCR'];
     562         $newNews->Sort = $page['MORDER'];
     563         $newNews->ShowInMenus = 1;
     564         $newNews->ShowInSearch = 1;
     565         $newNews->ShowInSiteMap = 1;
     566         if ($page['AUTH'])
     567             $newNews->CanViewType = 'LoggedInUsers';
     568
     569         $newNewsID = $newNews->write();
     570         if ($page['ACTIVE'] == 'Y') {
     571             $newNews->doPublish();
     572         }
     573         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     574         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
     575         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     576             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
     577                 $this->OldNewUrlMapping[$path] = $newNews->Link();
     578             }
     579         }
     580         $this->importNewsEnries($page, $newNewsID);
     581
     582         return $newNewsID;
     583     }
     584
     585     //Импорт новостей
     586     function importNewsEnries($page, $newNewsHolderID) {
     587
     588         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".NEWS WHERE DELETED=0 AND SYSPART=0 AND FOLDER={$page['SYSFOLDER']}");
     589         if ($records->numRecords() > 0) {
     590             $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     591             foreach($records as $record) {
     592                 $this->parentRelationsMapping["NEWS_" . $record['ID']] = "{$table}_" . $page['ID'];
     593                 $label = Convert::raw2sql($record['LABEL']);
     594                 $newsEntry = DataObject::get_one('NewsEntry', "ParentID = {$newNewsHolderID} AND SiteLogicImportID = " . $record['ID']);
     595                 if (!$newsEntry) {
     596                     $newsEntry = new NewsEntry();
     597                     $newsEntry->SiteLogicImportID = $record['ID'];
     598                 }
     599
     600                 $newsEntry->ParentID = $newNewsHolderID;
     601                 $newsEntry->Date = $record['DT'];
     602                 $newsEntry->Title = $record['LABEL'];
     603
     604                 //$newsEntry->Content = $this->correctPathInContent($record['DESCRIPTION']);
     605                 $newsEntry->Description = str_replace('&nbsp;', ' ', $record['ANONS']); //Убираем неразрывные пробелы, т.к. $newsEntry->Description типа Text
     606                 $newsEntry->URLSegment = self::correct_url_segment($record['VPATH']);
     607                 $newsEntry->Created = $record['CREATE_TIME'];
     608                 $newsEntry->LastEdited = $record['MODIFY_TIME'];
     609                 if ($record['AUTH'])
     610                     $newsEntry->CanViewType = 'LoggedInUsers';
     611
     612                 $newsEntry->write();
     613
     614                 //перекидываем картинку в папку новости и цепляем ее к новости
     615                 if ($record['IMAGE'] && isset($this->imageMapping[$record['IMAGE']])) {
     616                     $file = DataObject::get_by_id('Image', $this->imageMapping[$record['IMAGE']]);
     617                     if ($file) {
     618                         $this->changeFileFolder($file, $newsEntry);
     619                         $newsEntry->PhotoID = $file->ID;
     620                     }
     621                 }
     622
     623
     624                 $this->correctPathInContent($record['DESCRIPTION'], $newsEntry);
     625                 if ($record['ACTIVE'] == 'Y') {
     626                     $newsEntry->doPublish();
     627                 }
     628                 $this->urlMapping["NEWS_" . $record['ID']] = date('Y', strtotime($record['DT'])) . '/' . $record['VPATH'];
     629                 if (isset($record['ACTIVE']) && ($record['ACTIVE'] == 'Y')) {
     630                     if ($path = $this->getAbsoluteOldPath("NEWS_" . $record['ID'])) {
     631                         $this->OldNewUrlMapping[$path] = $newsEntry->Link();
     632                     }
     633                 }
     634                 $this->importLinkedImages($record, $newsEntry, 'NEWS');
     635                 $this->importLinkedFiles($record, $newsEntry, 'NEWS');
     636             }
     637         }
     638     }
     639
     640     //------------  МЕРОПРИЯТИЯ -------------------*/
     641     //Создаем Calendar
     642     function importEvents($page, $parentID) {
     643         if (isset($page['SYSPART']) && $page['SYSPART'] != 16) {
     644             return false;
     645         }
     646
     647         if (!class_exists('Calendar')) {
     648             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль events!\n";
     649             return false;
     650         }
     651
     652         $label = Convert::raw2sql($page['LABEL']);
     653         $newCalendar = DataObject::get_one('Calendar', "ParentID = {$parentID} AND Title = '{$label}'");
     654         if (!$newCalendar)
     655             $newCalendar = new Calendar();
     656
     657         $newCalendar->ParentID = $parentID;
     658         $newCalendar->Title = $page['LABEL'];
     659         $newCalendar->Created = $page['CREATE_TIME'];
     660         $newCalendar->LastEdited = $page['MODIFY_TIME'];
     661         $newCalendar->URLSegment = self::correct_url_segment($page['VPATH']);
     662         $newCalendar->Content = $this->correctPathInContent($page['DESCRIPTION']);
     663         $newCalendar->MetaKeywords = $page['KEYWORDS'];
     664         $newCalendar->MetaDescription = $page['DESCR'];
     665         $newCalendar->Sort = $page['MORDER'];
     666         if ($page['AUTH'])
     667             $newCalendar->CanViewType = 'LoggedInUsers';
     668
     669         $newCalendarID = $newCalendar->write();
     670         if ($page['ACTIVE'] == 'Y') {
     671             $newCalendar->doPublish();
     672         }
     673         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     674         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
     675         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     676             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
     677                 $this->OldNewUrlMapping[$path] = $newCalendar->Link();
     678             }
     679         }
     680         $this->importCalendarEnries($page, $newCalendarID);
     681
     682         return $newCalendarID;
     683     }
     684
     685     //Импорт мероприятий
     686     function importCalendarEnries($page, $newCalendarID) {
     687
     688         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".NEWS WHERE DELETED=0 AND SYSPART=2 AND FOLDER={$page['SYSFOLDER']}"); //SYSPART==2 - мероприятия
     689         if ($records->numRecords() > 0) {
     690             $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     691             foreach($records as $record) {
     692                 $this->parentRelationsMapping["NEWS_" . $record['ID']] = "{$table}_" . $page['ID'];
     693                 $label = Convert::raw2sql($record['LABEL']);
     694                 $newCalendarEvent = DataObject::get_one('CalendarEvent', "ParentID = {$newCalendarID} AND Title = '{$label}'");
     695                 if (!$newCalendarEvent)
     696                     $newCalendarEvent = new CalendarEvent();
     697
     698                 $newCalendarEvent->ParentID = $newCalendarID;
     699                 $newCalendarEvent->Title = $record['LABEL'];
     700
     701                 $newCalendarEvent->Content = $this->correctPathInContent($record['DESCRIPTION']);
     702                 $newCalendarEvent->Description = $record['ANONS'];
     703                 $newCalendarEvent->URLSegment = self::correct_url_segment($record['VPATH']);
     704                 $newCalendarEvent->Created = $record['CREATE_TIME'];
     705                 $newCalendarEvent->LastEdited = $record['MODIFY_TIME'];
     706                 if ($record['AUTH'])
     707                     $newCalendarEvent->CanViewType = 'LoggedInUsers';
     708
     709                 $newCalendarEventID = $newCalendarEvent->write();
     710                 if ($record['ACTIVE'] == 'Y') {
     711                     $newCalendarEvent->doPublish();
     712                 }
     713                 $this->urlMapping["NEWS_" . $record['ID']] = date('Y/n', strtotime($record['DT'])) . '/' .$record['VPATH'];
     714                 if (isset($record['ACTIVE']) && ($record['ACTIVE'] == 'Y')) {
     715                     if ($path = $this->getAbsoluteOldPath("NEWS_" . $record['ID'])) {
     716                         $this->OldNewUrlMapping[$path] = $newCalendarEvent->Link();
     717                     }
     718                 }
     719                 $this->importLinkedImages($record, $newCalendarEvent, 'EVENTS');
     720                 $this->importLinkedFiles($record, $newCalendarEvent, 'EVENTS');
     721
     722                 //Период события (свзязанные CalendarDateTime)
     723                 $newCalendarEvent->DateTimes()->removeAll();
     724                 $eventDateTime = new CalendarDateTime();
     725                 $eventDateTime->StartDate = $record['DT'];
     726                 $eventDateTime->EndDate = $record['DT_END'];
     727                 $eventDateTime->write();
     728                 $newCalendarEvent->DateTimes()->add($eventDateTime);
     729             }
     730         }
     731     }
     732
     733     //------------  ПУБЛИКАЦИИ -------------------*/
     734     //Создаем корневой PublHolder
     735     function importPublications($page, $parentID) {
     736         if (isset($page['SYSPART']) && $page['SYSPART'] != 5) {
     737             return false;
     738         }
     739
     740         if (!class_exists('PublHolder')) {
     741             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль publication!\n";
     742             return false;
     743         }
     744         $newPublHolderID = $this->importPublicationHolder($page, $parentID);
     745         return $newPublHolderID;
     746     }
     747
     748     //Импорт вложенных PublHolder
     749     function importPublicationHolder($page, $parentID, $prevPage=false) {
     750         if ($prevPage) {
     751             $prevTable = (isset($prevPage['SYSPART'])) ? 'MATERIAL_TREE' : 'ARTICLE_TREE';
     752             $nowTable = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'ARTICLE_TREE';
     753             $this->parentRelationsMapping["{$nowTable}_" . $page['ID']] = "{$prevTable}_" . $prevPage['ID'];
     754         }
     755         $label = Convert::raw2sql($page['LABEL']);
     756         $newPage = DataObject::get_one('PublHolder', "ParentID = {$parentID} AND SiteTree.Title = '{$label}'");
     757         if (!$newPage)
     758             $newPage = new PublHolder();
     759
     760         $newPage->ParentID = $parentID;
     761         $newPage->Title = $page['LABEL'];
     762         $newPage->Created = $page['CREATE_TIME'];
     763         $newPage->LastEdited = $page['MODIFY_TIME'];
     764         $newPage->URLSegment = self::correct_url_segment($page['VPATH']);
     765         $newPage->Content = $this->correctPathInContent($page['DESCRIPTION']);
     766         $newPage->MetaKeywords = $page['KEYWORDS'];
     767         $newPage->MetaDescription = $page['DESCR'];
     768         $newPage->Sort = $page['MORDER'];
     769
     770         if ($page['AUTH'])
     771             $newPage->CanViewType = 'LoggedInUsers';
     772
     773         $newPageID = $newPage->write();
     774         if ($page['ACTIVE'] == 'Y') {
     775             $newPage->doPublish();
     776         }
     777
     778         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'ARTICLE_TREE';
     779         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
     780         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     781             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
     782                 $this->OldNewUrlMapping[$path] = $newPage->Link();
     783             }
     784         }
     785         $this->importLinkedImages($page, $newPage, $table);
     786         $this->importLinkedFiles($page, $newPage, $table);
     787
     788         if (isset($page['SYSFOLDER'])) {
     789             $records = DB::query("SELECT * FROM \"{$this->oldDB}\".ARTICLE_TREE WHERE FOLDER={$page['SYSFOLDER']}");
     790             if ($records->numRecords() > 0) {
     791                 foreach($records as $record) {
     792                     $this->importPublicationHolder($record, $newPage->ID, $page);
     793                 }
     794             }
     795         }
     796         $this->importPublHolderEnries($page, $newPageID);
     797         return $newPageID;
     798     }
     799
     800     //Импорт публикаций
     801     function importPublHolderEnries($page, $parentID) {
     802         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".ARTICLES WHERE FOLDER={$page['ID']}");
     803         if ($records->numRecords() > 0) {
     804             $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'ARTICLE_TREE';
     805             foreach($records as $record) {
     806                 $this->parentRelationsMapping["ARTICLES_" . $record['ID']] = "{$table}_" . $page['ID'];
     807                 $label = Convert::raw2sql($record['LABEL']);
     808                 $newPage = DataObject::get_one('Publication', "ParentID = {$parentID} AND Title LIKE '{$label}'");
     809                 if (!$newPage)
     810                     $newPage = new Publication();
     811
     812                 $newPage->ParentID = $parentID;
     813                 $newPage->Date = $record['DT'];
     814                 $newPage->Title = $record['LABEL'];
     815
     816                 $newPage->Author = $record['AUTHOR'];
     817                 $newPage->Source = $record['SOURCE'];
     818                 $newPage->SourceLink = $record['SOURCE_URL'];
     819
     820                 //$newPage->Content = $this->correctPathInContent($record['DESCRIPTION']);
     821                 $newPage->Description = $record['ANONS'];
     822                 $newPage->URLSegment = self::correct_url_segment($record['VPATH']);
     823                 $newPage->Created = $record['CREATE_TIME'];
     824                 $newPage->LastEdited = $record['MODIFY_TIME'];
     825                 $newPage->Sort = $record['MORDER'];
     826                 $newPage->MetaKeywords = $record['KEYWORDS'];
     827                 $newPage->MetaDescription = $record['DESCR'];
     828
     829                 if ($record['AUTH'])
     830                     $newPage->CanViewType = 'LoggedInUsers';
     831
     832                 $newPage->write();
     833
     834                 //перекидываем картинку в папку публикации и цепляем ее к публикации
     835                 if ($record['IMAGE'] && isset($this->imageMapping[$record['IMAGE']])) {
     836                     $file = DataObject::get_by_id('Image', $this->imageMapping[$record['IMAGE']]);
     837                     if ($file) {
     838                         $this->changeFileFolder($file, $newPage);
     839                         $newPage->PhotoID = $file->ID;
     840                     }
     841                 }
     842
     843
     844                 $this->correctPathInContent($record['DESCRIPTION'], $newPage);
     845                 if ($record['ACTIVE'] == 'Y') {
     846                     $newPage->doPublish();
     847                 }
     848                 $this->urlMapping["ARTICLES_" . $record['ID']] = $record['VPATH'];
     849                 if (isset($record['ACTIVE']) && ($record['ACTIVE'] == 'Y')) {
     850                     if ($path = $this->getAbsoluteOldPath("ARTICLES_" . $record['ID'])) {
     851                         $this->OldNewUrlMapping[$path] = $newPage->Link();
     852                     }
     853                 }
     854                 $this->importLinkedImages($record, $newPage, 'ARTICLES');
     855                 $this->importLinkedFiles($record, $newPage, 'ARTICLES');
     856             }
     857         }
     858     }
     859
     860     //------------  FAQ -------------------*/
     861     //Создаем FAQHolder
     862     function importFAQ($page, $parentID) {
     863         if (isset($page['SYSPART']) && $page['SYSPART'] != 8) {
     864             return false;
     865         }
     866
     867         if (!class_exists('FAQHolder')) {
     868             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль faq!\n";
     869             return false;
     870         }
     871
     872         $label = Convert::raw2sql($page['LABEL']);
     873         $newPage = DataObject::get_one('FaqHolder', "ParentID = {$parentID} AND Title = '{$label}'");
     874         if (!$newPage)
     875             $newPage = new FaqHolder();
     876
     877         $newPage->Title = $page['LABEL'];
     878         $newPage->ParentID = $parentID;
     879         $newPage->Content = $this->correctPathInContent($page['DESCRIPTION']);
     880         $newPage->URLSegment = self::correct_url_segment($page['VPATH']);
     881         $newPage->Created = $page['CREATE_TIME'];
     882         $newPage->LastEdited = $page['MODIFY_TIME'];
     883         $newPage->Sort = $page['MORDER'];
     884         $newPage->MetaKeywords = $page['KEYWORDS'];
     885         $newPage->MetaDescription = $page['DESCR'];
     886
     887         if ($page['AUTH'])
     888             $newPage->CanViewType = 'LoggedInUsers';
     889
     890         $newPage->write();
     891         if ($page['ACTIVE'] == 'Y') {
     892             $newPage->doPublish();
     893         }
     894         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
     895         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
     896         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     897             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
     898                 $this->OldNewUrlMapping[$path] = $newPage->Link();
     899             }
     900         }
     901         if ($newPage->ID) {
     902             $records = DB::query("SELECT * FROM \"{$this->oldDB}\".FAQ_TREE WHERE FOLDER={$page['SYSFOLDER']}");
     903             if ($records->numRecords() > 0) {
     904                 foreach($records as $record) {
     905                     $this->parentRelationsMapping["FAQ_TREE_" . $record['ID']] = "{$table}_" . $page['ID'];
     906                     $this->importFAQSections($record, $newPage->ID);
     907                 }
     908             }
     909         }
     910         return $newPage->ID;
     911     }
     912
     913     //Импорт вложенных Sections
     914     function importFAQSections($page, $parentID) {
     915         $label = Convert::raw2sql($page['LABEL']);
     916         $newFAQSection = DataObject::get_one('FaqSection', "ParentID = {$parentID} AND SiteTree.Title = '{$label}'");
     917         if (!$newFAQSection)
     918             $newFAQSection = new FaqSection();
     919
     920         $newFAQSection->ParentID = $parentID;
     921         $newFAQSection->Title = $page['LABEL'];
     922         $newFAQSection->Created = $page['CREATE_TIME'];
     923         $newFAQSection->LastEdited = $page['MODIFY_TIME'];
     924         $newFAQSection->URLSegment = self::correct_url_segment($page['VPATH']);
     925         $newFAQSection->Sort = $page['MORDER'];
     926
     927         $newFAQSectionID = $newFAQSection->write();
     928         if ($page['ACTIVE'] == 'Y') {
     929             $newFAQSection->doPublish();
     930         }
     931         $this->urlMapping["FAQ_TREE_" . $page['ID']] = $page['VPATH'];
     932         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
     933             if ($path = $this->getAbsoluteOldPath("FAQ_TREE_" . $page['ID'])) {
     934                 $this->OldNewUrlMapping[$path] = $newFAQSection->Link();
     935             }
     936         }
     937         $this->importFaqQuestion($page, $newFAQSectionID);
     938         return $newFAQSectionID;
     939     }
     940
     941     //Импорт Вопросов-ответов
     942     function importFaqQuestion($page, $parentID) {
     943         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".FAQ WHERE FOLDER={$page['ID']}");
     944         if ($records->numRecords() > 0) {
     945             foreach($records as $record) {
     946                 $this->parentRelationsMapping["FAQ_" . $record['ID']] = "FAQ_TREE_" . $page['ID'];
     947                 $label = Convert::raw2sql($record['QUESTION']);
     948                 $newFaqQuestion = DataObject::get_one('FaqQuestion', "SectionID = {$parentID} AND Question = '{$label}'");
     949                 if (!$newFaqQuestion)
     950                     $newFaqQuestion = new FaqQuestion();
     951
     952                 $newFaqQuestion->SectionID = $parentID;
     953                 $newFaqQuestion->Question = $record['QUESTION'];
     954                 $newFaqQuestion->Answer = str_replace('&#1042;','В', htmlspecialchars_decode(strip_tags($record['ANSWER']))); //Выдает в тексте &#1042; (русская В) - самому на В заменять чтоле???
     955                 $newFaqQuestion->Email = $record['EMAIL'];
     956                 $newFaqQuestion->Created = $record['DT'];
     957                 $newFaqQuestion->LastEdited = $record['MODIFY_TIME'];
     958                 $newFaqQuestion->Published = ($record['ACTIVE'] == 'Y');
     959                 $newFaqQuestion->write();
     960             }
     961         }
     962     }
     963
     964     //------------  КАТАЛОГ ПРОДУКЦИИ -------------------*/
     965     //Создаем StartCatalog
     966     function importCatalog($page, $parentID) {
     967         if (isset($page['SYSPART']) && $page['SYSPART'] != 3) {
     968             return false;
     969         }
     970
     971         if (!class_exists('StartCatalog')) {
     972             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль catalog!\n";
     973             return false;
     974         }
     975
     976         if (!Object::has_extension('Catalog', 'CatalogOldFieldsDecorator')) {
     977             echo "Для импорта каталога необходимо подключить к нему декоратор CatalogOldFieldsDecorator\n";
     978             echo "DataObject::add_extension('Catalog', 'CatalogOldFieldsDecorator');\n";
     979             echo "Каталог не будет импортирован\n";
     980             return false;
     981         }
     982
     983         $label = Convert::raw2sql($page['LABEL']);
     984         $newPage = DataObject::get_one('StartCatalog', "ParentID = {$parentID} AND Title = '{$label}'");
     985         if (!$newPage)
     986             $newPage = new StartCatalog();
     987
     988         $newPage->ParentID = $parentID;
     989         $newPage->Title = $page['LABEL'];
     990         $newPage->URLSegment = self::correct_url_segment($page['VPATH']);
     991         $newPage->Created = $page['CREATE_TIME'];
     992         $newPage->LastEdited = $page['MODIFY_TIME'];
     993         $newPage->Sort = $page['MORDER'];
     994         $newPage->MetaKeywords = $page['KEYWORDS'];
     995         $newPage->MetaDescription = $page['DESCR'];
     996         $newPage->Content = $this->correctPathInContent($page['DESCRIPTION']);
     997
     998         if ($page['AUTH'])
     999             $newPage->CanViewType = 'LoggedInUsers';
    1000
    1001         $newPageID = $newPage->write();
    1002         if ($page['ACTIVE'] == 'Y') {
    1003             $newPage->doPublish();
    1004         }
    1005         $table = (isset($page['SYSPART'])) ? 'MATERIAL_TREE' : 'MATERIALS';
    1006         $this->urlMapping["{$table}_" . $page['ID']] = $page['VPATH'];
    1007         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
    1008             if ($path = $this->getAbsoluteOldPath("{$table}_" . $page['ID'])) {
    1009                 $this->OldNewUrlMapping[$path] = $newPage->Link();
    1010             }
    1011         }
    1012         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".CATALOG_TREE WHERE FOLDER={$page['SYSFOLDER']}");
    1013         if ($records->numRecords() > 0) {
    1014             foreach($records as $record) {
    1015                 $this->parentRelationsMapping["CATALOG_TREE_" . $record['ID']] = "{$table}_" . $page['ID'];
    1016                 $this->createCatalog($record, $newPage->ID);
    1017             }
    1018         }
    1019         return $newPage->ID;
    1020     }
    1021
    1022     function createCatalog($page, $parentID) {
    1023         $label = Convert::raw2sql($page['LABEL']);
    1024         $newCatalog = DataObject::get_one('Catalog', "ParentID = {$parentID} AND SiteTree.Title = '{$label}'");
    1025         if (!$newCatalog)
    1026             $newCatalog = new Catalog();
    1027
    1028         $newCatalog->ParentID = $parentID;
    1029         $newCatalog->Title = $page['LABEL'];
    1030         $newCatalog->Description = $page['ANONS'];
    1031         $newCatalog->Content = $this->correctPathInContent($page['DESCRIPTION']);
    1032         $newCatalog->URLSegment = self::correct_url_segment($page['VPATH']);
    1033         $newCatalog->Created = $page['CREATE_TIME'];
    1034         $newCatalog->LastEdited = $page['MODIFY_TIME'];
    1035         $newCatalog->Sort = $page['MORDER'];
    1036         $newCatalog->MetaKeywords = $page['KEYWORDS'];
    1037         $newCatalog->MetaDescription = $page['DESCR'];
    1038
    1039         if ($page['IMAGE'] && isset($this->imageMapping[$page['IMAGE']]))
    1040             $newCatalog->PhotoID = $this->imageMapping[$page['IMAGE']];
    1041
    1042         $newCatalog->NAME_P1 = $page['NAME_P1'];
    1043         $newCatalog->NAME_P2 = $page['NAME_P2'];
    1044         $newCatalog->NAME_P3 = $page['NAME_P3'];
    1045
    1046         $newCatalog->write();
    1047         if ($page['ACTIVE'] == 'Y') {
    1048             $newCatalog->doPublish();
    1049         }
    1050         $this->urlMapping["CATALOG_TREE_" . $page['ID']] = $page['VPATH'];
    1051         if (isset($page['ACTIVE']) && ($page['ACTIVE'] == 'Y')) {
    1052             if ($path = $this->getAbsoluteOldPath("CATALOG_TREE_" . $page['ID'])) {
    1053                 $this->OldNewUrlMapping[$path] = $newCatalog->Link();
    1054             }
    1055         }
    1056         $this->importLinkedImages($page, $newCatalog, 'CATALOG_TREE');
    1057         $this->importLinkedFiles($page, $newCatalog, 'CATALOG_TREE');
    1058
    1059         // в 2.5 в CATALOG_TREE не было поля PARENT, т.к. не было подрубрик (только 2 уровня)
    1060         $hasParentField = DB::query("show columns FROM \"{$this->oldDB}\".CATALOG_TREE where `Field` = 'PARENT'");
    1061         if ($hasParentField->numRecords() > 0) {
    1062             $records = DB::query("SELECT * FROM \"{$this->oldDB}\".CATALOG_TREE WHERE PARENT={$page['ID']}");
    1063             if ($records->numRecords() > 0) {
    1064                 foreach($records as $record) {
    1065                     $this->parentRelationsMapping["CATALOG_TREE_" . $record['ID']] = "CATALOG_TREE_" . $page['ID'];
    1066                     $this->createCatalog($record, $newCatalog->ID);
    1067                 }
    1068             }
    1069         }
    1070
    1071         $this->importCatalogProducts($page, $newCatalog->ID);
    1072
    1073         return $newCatalog->ID;
    1074     }
    1075
    1076     // Импорт продуктов раздела каталога
    1077     function importCatalogProducts($page, $parentID) {
    1078         if (!Object::has_extension('Product', 'ProductOldFieldsDecorator')) {
    1079             echo "Для импорта продуктов каталога необходимо подключить к нему декоратор ProductOldFieldsDecorator\n";
    1080             echo "DataObject::add_extension('Product', 'ProductOldFieldsDecorator');\n";
    1081             echo "Продукты каталога не будут импортированы\n";
    1082             return false;
    1083         }
    1084
    1085         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".CATALOG WHERE FOLDER={$page['ID']}");
    1086         if ($records->numRecords() > 0) {
    1087             foreach($records as $record) {
    1088                 $this->parentRelationsMapping["CATALOG_" . $record['ID']] = "CATALOG_TREE_" . $page['ID'];
    1089                 $label = Convert::raw2sql($record['LABEL']);
    1090                 $newProduct = DataObject::get_one('Product', "ParentID = {$parentID} AND Title = '{$label}'");
    1091                 if (!$newProduct)
    1092                     $newProduct = new Product();
    1093
    1094                 $newProduct->ParentID = $parentID;
    1095                 $newProduct->Title = $record['LABEL'];
    1096                 $newProduct->Description = strip_tags($record['ANONS']);
    1097                 //$newProduct->Content = $this->correctPathInContent($record['DESCRIPTION']);
    1098                 $newProduct->URLSegment = self::correct_url_segment($record['VPATH']);
    1099                 $newProduct->Created = $record['CREATE_TIME'];
    1100                 $newProduct->LastEdited = $record['MODIFY_TIME'];
    1101                 $newProduct->Sort = $record['MORDER'];
    1102                 $newProduct->MetaKeywords = $record['KEYWORDS'];
    1103                 $newProduct->MetaDescription = $record['DESCR'];
    1104
    1105                 if ($record['PRICE2']) { //заменяем в ценах запятые на точки
    1106                     $newProduct->BasePrice = (float)str_replace(',', '.', $record['PRICE2']);
    1107                     $newProduct->CostPrice = (float)str_replace(',', '.', $record['PRICE']);
    1108                 } else {
    1109                     $newProduct->BasePrice = (float)str_replace(',', '.', $record['PRICE']);
    1110                 }
    1111                 $newProduct->Available = $record['SKLAD'];
    1112
    1113                 // Допполя старого каталога
    1114                 $newProduct->VALUE_P1 = $record['VALUE_P1'];
    1115                 $newProduct->VALUE_P2 = $record['VALUE_P2'];
    1116                 $newProduct->VALUE_P3 = $record['VALUE_P3'];
    1117
    1118                 if ($record['AUTH'])
    1119                     $newProduct->CanViewType = 'LoggedInUsers';
    1120
    1121                 $newProduct->write();
    1122
    1123                 if ($record['IMAGE'] && isset($this->imageMapping[$record['IMAGE']])) {
    1124                     $file = DataObject::get_by_id('Image', $this->imageMapping[$record['IMAGE']]);
    1125                     if ($file) {
    1126                         $this->changeFileFolder($file, $newProduct);
    1127                         $newProduct->PhotoID = $file->ID;
    1128                     }
    1129                 }
    1130                 $this->correctPathInContent($record['DESCRIPTION'], $newProduct);
    1131
    1132                 if ($record['ACTIVE'] == 'Y') {
    1133                     $newProduct->doPublish();
    1134                 }
    1135                 $this->urlMapping["CATALOG_" . $record['ID']] = $record['VPATH'];
    1136                 if (isset($record['ACTIVE']) && ($record['ACTIVE'] == 'Y')) {
    1137                     if ($path = $this->getAbsoluteOldPath("CATALOG_" . $record['ID'])) {
    1138                         $this->OldNewUrlMapping[$path] = $newProduct->Link();
    1139                     }
    1140                 }
    1141                 $this->productsMapping[$record['ID']] = $newProduct->ID;
    1142
    1143                 $this->importLinkedImages($record, $newProduct, 'CATALOG');
    1144                 $this->importLinkedFiles($record, $newProduct, 'CATALOG');
    1145
    1146                 //Помещение товара в СпецКаталог (SpecialCatalog находится в модуле Cart)
    1147                 if (class_exists('SpecialCatalog')) {
    1148                     $specials = array(
    1149                         'NEW' => 'Новинки',
    1150                         'LIDER' => 'Лидеры продаж',
    1151                         'SPEC' => 'Специальные предложения',
    1152                     );
    1153                     foreach ($specials as $key => $title) {
    1154                         if ($record[$key]) {
    1155                             $special = $this->getSpecCatalog($title);
    1156                             $products = $special->Products()->getIdList();
    1157                             if (!isset($products[$newProduct->ID]))
    1158                                 $special->Products()->add($newProduct);
    1159                         }
    1160                     }
    1161                 }
    1162             }
    1163         }
    1164     }
    1165
    1166     //------------  ОТЗЫВЫ -------------------*/
    1167     //Создаем Guestbook
    1168     function importGuestbook() {
    1169         if (!$this->checkMySQLTableExists("GUEST")) {
    1170             echo "Таблицы GUEST нет в БД\n";
    1171             return false;
    1172         }
    1173
    1174         if (!class_exists('Guestbook')) {
    1175             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль guestbook!\n";
    1176             return false;
    1177         }
    1178
    1179         if ($page = DataObject::get_one('Page', "URLSegment='guest'")) {
    1180             $page->URLSegment = 'guest-old';
    1181             $page->doPublish();
    1182         }
    1183
    1184         $newGuestbook = DataObject::get_one('Guestbook');
    1185         if (!$newGuestbook)
    1186             $newGuestbook = new Guestbook();
    1187
    1188         $newGuestbook->Title = 'Отзывы';
    1189         $newGuestbook->URLSegment = 'guest';
    1190         $newGuestbook->doPublish();
    1191         $this->OldNewUrlMapping['/guest'] = $newGuestbook->Link();
    1192
    1193         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".GUEST");
    1194         if ($records->numRecords() > 0) {
    1195             foreach($records as $record) {
    1196                 $label = Convert::raw2sql($record['DESCRIPTION']);
    1197                 $newGuestbookEntry = DataObject::get_one('GuestbookEntry', "GuestbookID = {$newGuestbook->ID} AND Comment = '{$label}'");
    1198                 if (!$newGuestbookEntry)
    1199                     $newGuestbookEntry = new GuestbookEntry();
    1200
    1201                 $newGuestbookEntry->GuestbookID = $newGuestbook->ID;
    1202                 $newGuestbookEntry->Name = $record['FIO'];
    1203                 $newGuestbookEntry->Phone = $record['CONTACT'];
    1204                 $newGuestbookEntry->Comment = $record['DESCRIPTION'];
    1205                 $newGuestbookEntry->Created = $record['CREATE_TIME'];
    1206                 $newGuestbookEntry->LastEdited = $record['MODIFY_TIME'];
    1207                 $newGuestbookEntry->Status = 'new';
    1208                 if ($record['ACTIVE'] == 'Y') {
    1209                     $newGuestbookEntry->Status = 'published';
    1210                 }
    1211                 $newGuestbookEntry->write();
    1212             }
    1213         }
    1214     }
    1215
    1216     //------------  Анонсы -------------------*/
    1217     //Создаем Announcement
    1218     function importAnnouncement() {
    1219         if (!$this->checkMySQLTableExists("ANONS")) {
    1220             echo "Таблицы ANONS нет в БД\n";
    1221             return false;
    1222         }
    1223
    1224         if (!class_exists('AnnouncementHolder')) {
    1225             echo "НЕ ИМПОРТИРОВАНО! Не установлен модуль anons!\n";
    1226             return false;
    1227         }
    1228
    1229         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".ANONS");
    1230         if ($records->numRecords() > 0) {
    1231             foreach($records as $record) {
    1232                 $anonsHolder = $this->findOrMakeAnnouncementHolder($record['TYPENUMBER']); //Создаем или находим нужный Holder
    1233                 $label = Convert::raw2sql($record['LABEL']);
    1234                 $newAnnouncement = DataObject::get_one('Announcement', "ParentID = {$anonsHolder->ID} AND Title = '{$label}'");
    1235                 if (!$newAnnouncement)
    1236                     $newAnnouncement = new Announcement();
    1237
    1238                 $newAnnouncement->ParentID = $anonsHolder->ID;
    1239                 $newAnnouncement->Title = $record['LABEL'];
    1240                 $newAnnouncement->Description = $record['ANONS'];
    1241
    1242                 //$newAnnouncement->Content = $this->correctPathInContent($record['DESCRIPTION']);
    1243
    1244                 $newAnnouncement->LinkType = 3;
    1245                 if ($record['HREF']) {
    1246                     $newAnnouncement->LinkType = 1;
    1247                     $newAnnouncement->ExternalLink = $record['HREF'];
    1248                 } elseif ($record['VHREF']) {
    1249                     $link = str_replace('.html', '', $record['VHREF']);
    1250                     $page = SiteTree::get_by_link($link);
    1251                     if ($page) {
    1252                         $newAnnouncement->LinkType = 2;
    1253                         $newAnnouncement->InternalLinkID = $page->ID;
    1254                     }
    1255                 }
    1256                 $newAnnouncement->Date = $record['DT'];
    1257                 $newAnnouncement->URLSegment = self::correct_url_segment($record['VPATH']);
    1258                 $newAnnouncement->Created = $record['CREATE_TIME'];
    1259                 $newAnnouncement->LastEdited = $record['MODIFY_TIME'];
    1260                 $newAnnouncement->MetaKeywords = $record['KEYWORDS'];
    1261                 $newAnnouncement->MetaDescription = $record['DESCR'];
    1262
    1263                 $newAnnouncement->write();
    1264
    1265                 //перекидываем картинку в папку анонса и цепляем ее к анонсу
    1266                 if ($record['IMAGE'] && isset($this->imageMapping[$record['IMAGE']])) {
    1267                     $file = DataObject::get_by_id('Image', $this->imageMapping[$record['IMAGE']]);
    1268                     if ($file) {
    1269                         $this->changeFileFolder($file, $newAnnouncement);
    1270                         $newAnnouncement->PhotoID = $file->ID;
    1271                     }
    1272                 }
    1273
    1274                 $this->correctPathInContent($record['DESCRIPTION'], $newAnnouncement);
    1275                 if ($record['ACTIVE'] == 'Y') {
    1276                     $newAnnouncement->doPublish();
    1277                 }
    1278                 $this->OldNewUrlMapping['/anons/' . $record['ID']] = $newAnnouncement->Link();
    1279
    1280                 $this->importLinkedImages($record, $newAnnouncement, 'ANONS');
    1281                 $this->importLinkedFiles($record, $newAnnouncement, 'ANONS');
    1282             }
    1283         }
    1284     }
    1285
    1286     // Создаем Holder для каждой области анонсов (в 2.6 могут быть до 3х областей)
    1287     function findOrMakeAnnouncementHolder($number) {
    1288         $anonsHolder = DataObject::get_one('AnnouncementHolder', "Title = 'Анонсы_{$number}'");
    1289         if (!$anonsHolder)
    1290             $anonsHolder = new AnnouncementHolder();
    1291         $anonsHolder->Title = 'Анонсы_' . $number;
    1292         $anonsHolder->URLSegment = 'announcement_' . $number;
    1293         $anonsHolder->doPublish();
    1294         return $anonsHolder;
    1295     }
    1296
    1297     /*--------------- ПОЛЬЗОВАТЕЛИ САЙТА ---------------------*/
    1298     //Импорт пользователей сайта (если $adm == true, то импорт админов)
    1299     function importSiteUsers($adm = false) {
    1300         $adminPass = array();
    1301         $table = 'ACCOUNTS';
    1302         if ($adm) {
    1303             $table = 'SITE_ADMINS';
    1304             if (is_file(self::base_dir() . '/admin_pass.txt'))
    1305                 unlink(self::base_dir() . '/admin_pass.txt');
    1306         }
    1307
    1308         if (!$this->checkMySQLTableExists($table)) {
    1309             echo "Таблицы {$table} нет в БД\n";
    1310             return false;
    1311         }
    1312
    1313
    1314         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".{$table}");
    1315         if ($records->numRecords() > 0) {
    1316             foreach($records as $record) {
    1317                 if ($record['EMAIL'] == 'support@mediaweb.ru') continue;
    1318                 if ($record['EMAIL'] == 'oleg@mediaweb.ru') continue;
    1319                 $email = false;
    1320                 if ($record['EMAIL']) {
    1321                     $email = $record['EMAIL'];
    1322                 }
    1323                 elseif ($record['LOGIN']) {
    1324                     $email = $record['LOGIN'];
    1325                 }
    1326
    1327                 if (!$email) continue;
    1328
    1329
    1330                 if ($member = DataObject::get_one('Member', "Email='{$email}'")) {
    1331                     if (!$member->checkPassword($record['PASSWORD'])->valid())
    1332                         echo "НЕ ИМПОРТИРОВАНО! Пользователь c Email: " . $email . " уже существует\n";
    1333                     continue;
    1334                 }
    1335
    1336                 $member = new Member();
    1337                 $member->Email = $email;
    1338                 $member->Password = $record['PASSWORD'];
    1339                 if ($adm) {
    1340                     $member->Password = $this->generatePassword(); //Генерим админам новые пароли
    1341                     $adminPass[$member->Email] = $member->Password;
    1342                 }
    1343                 if ($record['NAME'] != null) {
    1344                     $name = explode(' ', $record['NAME']);
    1345                     if (count($name) == 1) { //если нет пробела
    1346                         $member->FirstName = $record['NAME'];
    1347                     } else {
    1348                         $member->FirstName = $name[0];
    1349                         $member->Surname = $name[1];
    1350                     }
    1351                 }
    1352                 else {
    1353                     $member->FirstName = $email;
    1354                 }
    1355                 $member->write();
    1356
    1357                 if ($adm) {
    1358                     if ($record['STATUS'] == 1) { //Администраторы
    1359                         Group::addToGroupByName($member, 'administrators');
    1360                     } elseif ($record['STATUS'] == 2) { //редакторы
    1361                         Group::addToGroupByName($member, 'content-authors');
    1362                     }
    1363                 }
    1364             }
    1365
    1366             if (count($adminPass) > 0) {
    1367                 $lines = "";
    1368                 foreach($adminPass as $login=>$pass) {
    1369                     $lines .= $login . ":" . $pass . "\n";
    1370                 }
    1371                 file_put_contents(self::base_dir() . '/admin_pass.txt', $lines);
    1372             }
    1373         }
    1374     }
    1375
    1376     // Импортируем связанные со страницей изображения
    1377     function importLinkedImages($page, $newPage, $type) {
    1378
    1379         if (!$newPage->has_many('Photos')) return false;
    1380
    1381         if (!isset(self::$attachedGalleryParams[$type])) return false;
    1382
    1383         $params = self::$attachedGalleryParams[$type];
    1384         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".GALLERY_FILES WHERE MATERIAL={$page['ID']} AND SMODE={$params['SMODE']} AND PART={$params['PART']} ORDER BY INNER_PRIOR");
    1385
    1386         $newPage->Photos()->removeAll();
    1387         if ($records->numRecords() > 0) {
    1388             foreach($records as $record) {
    1389                 if (!isset($this->imageMapping[$record['FILE']])) continue;
    1390
    1391                 $storedImage = DataObject::get_by_id('Image', $this->imageMapping[$record['FILE']]);
    1392                 if ($storedImage) {
    1393                     $this->changeFileFolder($storedImage, $newPage);
    1394
    1395                     $image = new MediawebPage_Photo();
    1396                     $image->MediawebPageID = $newPage->ID;
    1397                     $image->PhotoID = $storedImage->ID;
    1398                     $image->Caption = $record['LABEL'];
    1399                     $image->SortOrder = $record['INNER_PRIOR'];
    1400                     $image->write();
    1401                 }
    1402
    1403
    1404                 //$newPage->Photos()->add($image);
    1405             }
    1406         }
    1407     }
    1408
    1409     // Импортируем связанные со страницей файлы
    1410     function importLinkedFiles($page, $newPage, $type) {
    1411         // $newPage is subclass of MediawebPage || hasExtension('Attachdfiles')
    1412         if (!$newPage->has_many('Files')) return false;
    1413
    1414         $params = self::$attachedGalleryParams[$type];
    1415         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".MATERIAL_FILES WHERE MATERIAL={$page['ID']} AND SMODE={$params['SMODE']} AND PART={$params['PART']} ORDER BY MORDER");
    1416
    1417         $newPage->Files()->removeAll();
    1418         if ($records->numRecords() > 0) {
    1419             foreach($records as $record) {
    1420                 if (!isset($this->fileMapping[$record['FILE']])) continue;
    1421
    1422                 $storedFile = DataObject::get_by_id('File', $this->fileMapping[$record['FILE']]);
    1423                 if ($storedFile) {
    1424                     $this->changeFileFolder($storedFile, $newPage);
    1425
    1426                     $file = new MediawebPage_File();
    1427                     $file->MediawebPageID = $newPage->ID;
    1428                     $file->AttachID = $storedFile->ID;
    1429                     $file->Caption = $file->Attach()->Title;
    1430                     $file->SortOrder = $record['MORDER'];
    1431                     $file->write();
    1432                 }
    1433                 //$newPage->Files()->add($file);
    1434             }
    1435         }
    1436     }
    1437
    1438     // Импортируем связанную со страницей форму
    1439     function importForms() {
    1440         $forms = DB::query("SELECT * FROM \"{$this->oldDB}\".UD_FORMS WHERE ACTIVE = 1");//Переносим только активные формы
    1441         if ($forms->numRecords() > 0) {
    1442             foreach($forms as $form) {
    1443                 $newForm = new UserDefinedForm();
    1444                 $newForm->OnCompleteMessage = $form['AFTER_TEXT'];
    1445                 $newForm->Title = $form['NAME'];
    1446                 $newForm->SubmitButtonText = $form['SUBMIT'];
    1447                 $newForm->Created = $form['CREATE_TIME'];
    1448                 $newForm->LastEdited = $form['MODIFY_TIME'];
    1449                 $newForm->ShowInMenus = 0;
    1450                 $newForm->ShowInSearch = 0;
    1451                 $newForm->ShowInSiteMap = 0;
    1452                 $newForm->write();
    1453
    1454                 $emailRecipient = new UserDefinedForm_EmailRecipient();
    1455                 $emailRecipient->EmailAddress = $form['ALTERNATE_EMAIL'];
    1456                 $emailRecipient->write();
    1457                 $newForm->EmailRecipients()->add($emailRecipient);
    1458
    1459                 $fields = DB::query("SELECT * FROM \"{$this->oldDB}\".UD_FORM_FIELDS WHERE FORM={$form['ID']}");    //Переносим только активные поля формы AND ACTIVE = 1
    1460                 if ($fields->numRecords() > 0) {
    1461                     foreach($fields as $field) {
    1462                         if (!$field['TYPE'])
    1463                             continue;
    1464                         $settings = array();
    1465                         $settings['ShowOnLoad'] = 'Show';
    1466                         if ($field['ACTIVE'] != 1) {
    1467                             $settings['ShowOnLoad'] = 'Hide';
    1468                         }
    1469                         if ($field['TYPE'] == 1) {
    1470                             $newField = new EditableTextField();
    1471                         }
    1472                         if ($field['TYPE'] == 2) {
    1473                             $newField = new EditableTextField();
    1474                             $settings['Rows'] = 10;
    1475                         }
    1476                         if ($field['TYPE'] == 3) {
    1477                             $newField = new EditableDropdown();
    1478                             $options = explode("\n", $field['SUBITEMS']);
    1479                             $newField->write();
    1480                             foreach($options as $key=>$option) {
    1481                                 $newOption = new EditableOption();
    1482                                 $newOption->Title = $option;
    1483                                 $newOption->Sort = ($key+1);
    1484                                 $id = $newOption->write();
    1485                                 $newOption->Name = 'option'.$id;
    1486                                 $newOption->write();
    1487                                 $newField->Options()->add($newOption);
    1488                             }
    1489                         }
    1490                         if ($field['TYPE'] == 4) {
    1491                             $newField = new EditableCheckbox();
    1492                         }
    1493                         if ($field['TYPE'] == 5) {
    1494                             $newField = new EditableRadioField();
    1495                             $options = explode("\n", $field['SUBITEMS']);
    1496                             $newField->write();
    1497                             foreach($options as $key=>$option) {
    1498                                 $newOption = new EditableOption();
    1499                                 $newOption->Title = $option;
    1500                                 $newOption->Sort = ($key+1);
    1501                                 $id = $newOption->write();
    1502                                 $newOption->Name = 'option'.$id;
    1503                                 $newOption->write();
    1504                                 $newField->Options()->add($newOption);
    1505                             }
    1506                         }
    1507                         if ($field['TYPE'] == 6) {
    1508                             $newField = new EditableEmailField();
    1509                         }
    1510                         if ($field['TYPE'] == 7) {
    1511                             $newField = new EditableDateField();
    1512                         }
    1513                         if ($field['TYPE'] == 8) {
    1514                             $newField = new EditableSpamProtectionField();
    1515                         }
    1516                         if ($field['TYPE'] == 9) {
    1517                             $newField = new EditableFileField();
    1518                         }
    1519                         //Проверка на обязательность
    1520                         if ($field['SYS']) {
    1521                             if ($field['TYPE'] != 8) { //Для новой капчи (StealthCaptha) обязательность не нужна
    1522                                 $newField->Required = 1;
    1523                                 $newField->CustomErrorMessage = $field['REQUIRED'];
    1524                             }
    1525                         }
    1526                         $newField->Title = $field['NAME'];
    1527                         $newField->Created = $field['CREATE_TIME'];
    1528                         $newField->LastEdited = $field['MODIFY_TIME'];
    1529                         $newField->Sort = $field['MORDER'];
    1530                         $newField->CustomSettings = serialize($settings);
    1531                         $id = $newField->write();
    1532                         $newField->Name = $newField->ClassName.$id;
    1533                         $newField->write();
    1534                         $newForm->Fields()->add($newField);
    1535                     }
    1536                 }
    1537                 $newForm->doPublish();
    1538             }
    1539         }
    1540     }
    1541
    1542     // Импорт библиотеки Изображений сайта
    1543     function importImageLibrary() {
    1544         $top = Folder::findOrMake(ASSETS_PATH . '/images');
    1545
    1546         //картинки с корня
    1547         $this->importFolderImages(-1, $top->ID);
    1548
    1549         //картинки от визаульного редактора (пережитки 2.5)
    1550         $this->importFolderImages(0, $top->ID);
    1551
    1552         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".IMAGE_LIBRARY WHERE PARENT=-1");
    1553         if ($records->numRecords() > 0) {
    1554             foreach($records as $record) {
    1555                 $this->importImageLibraryBranch($record, $top->ID);
    1556             }
    1557         }
    1558     }
    1559
    1560     function importImageLibraryBranch($folder, $parentID) {
    1561         $newID = $this->findOrMakeFolder($folder, $parentID);
    1562
    1563         $this->importFolderImages($folder['ID'], $newID);
    1564
    1565         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".IMAGE_LIBRARY WHERE PARENT={$folder['ID']}");
    1566         if ($records->numRecords() > 0) {
    1567             foreach($records as $record) {
    1568                 $this->importImageLibraryBranch($record, $newID);
    1569             }
    1570         }
    1571     }
    1572
    1573     function findOrMakeFolder($folder, $parentID) {
    1574         $label = Convert::raw2sql($folder['NAME']);
    1575         $newFolder = DataObject::get_one('Folder', "ParentID={$parentID} AND Title = '{$label}'");
    1576         if (!$newFolder)
    1577             $newFolder = new Folder();
    1578
    1579         $newFolder->Created = $folder['CREATE_TIME'];
    1580         $newFolder->LastEdited = $folder['MODIFY_TIME'];
    1581         $newFolder->Title = $folder['NAME'];
    1582         $newFolder->setName($folder['ID']);
    1583         $newFolder->ParentID = $parentID;
    1584         $newID = $newFolder->write();
    1585         if(!file_exists($newFolder->getFullPath())) {
    1586             Filesystem::makeFolder($newFolder->getFullPath());
    1587         }
    1588         return $newID;
    1589     }
    1590
    1591     function importFolderImages($folderID, $newFolderID) {
    1592         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".IMAGES WHERE FOLDER={$folderID}");
    1593         if ($records->numRecords() > 0) {
    1594             foreach($records as $record) {
    1595                 $class = 'Image';
    1596                 if (isset(self::$imageExtensions[$record['TYPE']])) {
    1597                     $type = self::$imageExtensions[$record['TYPE']];
    1598                 }
    1599                 elseif (isset(self::$fileExtensions[$record['TYPE']])) {
    1600                     $type = self::$fileExtensions[$record['TYPE']];
    1601                     $class = 'File';
    1602                 }
    1603                 else continue;
    1604                 $fileName = $record['ID'] . '.' . $type;
    1605                 $oldName = $this->oldPath . '/images/' . $fileName;
    1606                 if(!file_exists($oldName)) continue;
    1607
    1608                 $newImage = DataObject::get_one($class, "ParentID={$newFolderID} AND OldImportID = '".$record['ID']."'");
    1609                 if (!$newImage) {
    1610                     $newImage = new $class();
    1611                     $newImage->OldImportID = $record['ID'];
    1612                 }
    1613
    1614                 $newImage->Created = $record['CREATE_TIME'];
    1615                 $newImage->LastEdited = $record['MODIFY_TIME'];
    1616                 $newImage->Title = $record['NAME'];
    1617                 $newImage->Name = $fileName;
    1618                 $newImage->ParentID = $newFolderID;
    1619                 $newImage->write();
    1620                 copy($oldName, $newImage->getFullPath());
    1621
    1622                 $this->imageMapping[$record['ID']] = $newImage->ID;
    1623                 // файл из корня или виз.реда
    1624                 if (($folderID == -1) || ($folderID == 0)) {
    1625                     $this->fileFolderChanging[$newImage->ID] = 1;
    1626                 }
    1627             }
    1628         }
    1629     }
    1630
    1631     // Импорт библиотеки Файлов сайта
    1632     function importFileLibrary() {
    1633         $top = Folder::findOrMake(ASSETS_PATH . '/files');
    1634
    1635         //файлы с корня
    1636         $this->importFolderFiles(-1, $top->ID);
    1637         //файлы от визаульного редактора (пережитки 2.5)
    1638         $this->importFolderFiles(0, $top->ID);
    1639
    1640         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".FILE_LIBRARY WHERE PARENT=-1");
    1641         if ($records->numRecords() > 0) {
    1642             foreach($records as $record) {
    1643                 $this->importFileLibraryBranch($record, $top->ID);
    1644             }
    1645         }
    1646     }
    1647
    1648     function importFileLibraryBranch($folder, $parentID) {
    1649         $newID = $this->findOrMakeFolder($folder, $parentID);
    1650
    1651         $this->importFolderFiles($folder['ID'], $newID);
    1652
    1653         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".FILE_LIBRARY WHERE PARENT={$folder['ID']}");
    1654         if ($records->numRecords() > 0) {
    1655             foreach($records as $record) {
    1656                 $this->importFileLibraryBranch($record, $newID);
    1657             }
    1658         }
    1659     }
    1660
    1661     function importFolderFiles($folderID, $newFolderID) {
    1662         $records = DB::query("SELECT * FROM \"{$this->oldDB}\".FILES WHERE FOLDER={$folderID}");
    1663         if ($records->numRecords() > 0) {
    1664             foreach($records as $record) {
    1665                 $fileName = $record['FILENAME'];
    1666                 $ext = pathinfo($fileName, PATHINFO_EXTENSION);
    1667                 $name = pathinfo($fileName, PATHINFO_FILENAME);
    1668                 $fileName = $name . '-' . $record['ID'] . '.' . $ext;
    1669                 /*
    1670                 $searchName = preg_replace('/\s+/', '-', Convert::rus2lat($fileName));
    1671                 $searchName = preg_replace('/[^A-Za-z0-9.+_\-]/','',$searchName);
    1672                 $searchName = preg_replace('/^[_.]+/','',$searchName);
    1673                 */
    1674                 if (!$record['FILE']) {
    1675                     $oldName = $this->oldPath . '/files/' . $record['ID'];
    1676                     if (!file_exists($oldName)) {
    1677                         $oldName .= '.' . $ext;
    1678                     }
    1679                     if (!file_exists($oldName)) {
    1680                         echo "File not found: {$record['ID']} ({$record['FILENAME']})\n";
    1681                         continue;
    1682                     }
    1683                 }
    1684
    1685                 $newFile = DataObject::get_one('File', "ParentID={$newFolderID} AND OldImportID = '".$record['ID']."'"); //Name = '".Convert::raw2sql($searchName)."'"
    1686                 if (!$newFile) {
    1687                     $newFile = new File();
    1688                     $newFile->OldImportID = $record['ID'];
    1689                 }
    1690                 $newFile->Created = $record['CREATE_TIME'];
    1691                 $newFile->LastEdited = $record['MODIFY_TIME'];
    1692                 $newFile->Title = $record['NAME'];
    1693                 $newFile->Name = $fileName;
    1694                 $newFile->ParentID = $newFolderID;
    1695                 $newFile->write();
    1696                 if ($record['FILE']) {
    1697                     file_put_contents($newFile->getFullPath(), $record['FILE']);
    1698                     unset($record['FILE']);
    1699                 }
    1700                 else {
    1701                     copy($oldName, $newFile->getFullPath());
    1702                 }
    1703
    1704                 $this->fileMapping[$record['ID']] = $newFile->ID;
    1705             }
    1706         }
    1707     }
    1708
    1709     // Кооректировка ссылок и путей к картинкам и файлам в содержании
    1710     // $this->correctPathInContent($page['DESCRIPTION'], $newPage);
    1711     function correctPathInContent($content, $newPage=false) {
    1712         $content = str_replace('&#1042;', 'В', $content);
    1713         if ($this->siteName)
    1714             $content = preg_replace('!http://('.join('|', $this->siteName).')/!', '/', $content);
    1715
    1716         $content = $this->correctInternalLinks($content);
    1717         $content = $this->correctFileLinks($content, $newPage);
    1718         $content = $this->correctImageLinks($content, $newPage);
    1719         if ($newPage) {
    1720             $newPage->Content = $content;
    1721             $newPage->write();
    1722         }
    1723         return $content;
    1724     }
    1725
    1726     //ссылки на файлы
    1727     function correctFileLinks($content, $newPage) {
    1728         preg_match_all('!/file\.cgi\?id=([0-9]+)"!i', $content, $m);
    1729         if ($m) {
    1730             foreach($m[1] as $fileID) {
    1731                 if (!isset($this->fileMapping[$fileID])) {
    1732                     echo "file: $fileID not found!\n";
    1733                     continue;
    1734                 }
    1735                 $newFile = DataObject::get_by_id('File', $this->fileMapping[$fileID]);
    1736                 //если у страницы есть прикрепленная папака - запихнем в нее файл
    1737                 if ($newPage)
    1738                     $this->changeFileFolder($newFile, $newPage);
    1739
    1740                 //$fileLink = (Object::has_extension('SiteTree', 'SiteTreeSubsites')) ? $newFile->RelativeLink() : $newFile->Link(); //Если есть модуль subsites, то полный путь
    1741                 $fileLink = $newFile->RelativeLink();
    1742                 $content = preg_replace('!/file\.cgi\?id='.$fileID.'"!i', $fileLink . '"', $content);
    1743             }
    1744         }
    1745         return $content;
    1746     }
    1747
    1748     //ссылки на файлы
    1749     function correctImageLinks($content, $newPage) {
    1750         // /images/1234.jpg -> /img.cgi?id=1234
    1751         // /images/t_1234.jpg -> /img.cgi?id=1234
    1752         $content = preg_replace('!(=|")/images/([tsaf2]+_)?(\d+)\.[^"]+"!', '$1/img.cgi?id=$3"', $content);
    1753
    1754         // <a href="javascript:NewWindow('imlib_popup_win_522','/bigimg.cgi?id=522',346,800)">
    1755         // -> <a href="/img.cgi?id=522" class="ssImagePopup" rel="contentImage" target="_blank">
    1756         $content = preg_replace("!href=\"javascript:NewWindow\('[a-z0-9_]+','/bigimg.cgi\?id=(\d+)',\d+,\d+\)\"!i", 'href="/img.cgi?id=$1" class="ssImagePopup" rel="contentImage" target="_blank"', $content);
    1757
    1758         // /bigimg.cgi?id=1234 -> /img.cgi?id=1234
    1759         $content = preg_replace("!/bigimg\.cgi!", '/img.cgi', $content);
    1760
    1761         // /img.cgi?id=1234 -> new
    1762         preg_match_all('!/img\.cgi\?id=(\d+)"!i', $content, $m);
    1763         if ($m) {
    1764             foreach($m[1] as $imageID) {
    1765                 if (!isset($this->imageMapping[$imageID])) {
    1766                     echo "image: $imageID not found!\n";
    1767                     continue;
    1768                 }
    1769                 $newImage = DataObject::get_by_id('File', $this->imageMapping[$imageID]);
    1770
    1771                 //если у страницы есть прикрепленная папка - запихнем в нее картинку
    1772                 if ($newPage)
    1773                     $this->changeFileFolder($newImage, $newPage);
    1774
    1775                 //$imageLink = (Object::has_extension('SiteTree', 'SiteTreeSubsites')) ? $newImage->Link() : $newImage->RelativeLink(); //Если есть модуль subsites, то полный путь
    1776                 $imageLink = $newImage->RelativeLink(); //всегда относительный путь (от assets)
    1777                 $content = preg_replace('!/img\.cgi\?id='.$imageID.'"!i', $imageLink . '"', $content);
    1778             }
    1779         }
    1780         return $content;
    1781     }
    1782
    1783     //ссылки на другие страницы сайта
    1784     function correctInternalLinks($content) {
    1785         // насчет str_replace("_", "_", "$1/") - раньше было str_replace("_", "-", "$1/"), но потом SS при сохранении страниц перестал заменять их в URLSegment
    1786         return preg_replace('!(href="/[^"]+)(\.html)!ie', 'str_replace("_", "_", "$1/")', $content); //Просто удаляем .html в конце внутренних ссылок
    1787     }
    1788
    1789     function generatePassword($length = 8){
    1790         $chars = 'abcdefghijkmnopqrstvwxyzABCDEFGHJKLMNPQRSTVWXYZ23456789';
    1791         $numChars = strlen($chars);
    1792         $string = '';
    1793         for ($i = 0; $i < $length; $i++) {
    1794             $string .= substr($chars, rand(1, $numChars) - 1, 1);
    1795         }
    1796         return $string;
    1797     }
    1798
    1799     function checkMySQLTableExists($table) {
    1800         $conn = DB::getConn();
    1801         $save = $conn->currentDatabase();
    1802         $conn->selectDatabase($this->oldDB);
    1803         $result = $conn->hasTable($table);
    1804         $conn->selectDatabase($save);
    1805         return $result;
    1806     }
    1807
    1808     function getSpecCatalog($title) {
    1809         if (!isset($this->specCatalogMapping[$title])) {
    1810             $catalog = DataObject::get_one('SpecialCatalog', "SiteTree.Title='".Convert::raw2sql($title)."'");
    1811             if (!$catalog) {
    1812                 $catalog = new SpecialCatalog();
    1813                 $catalog->Title = $title;
    1814                 $catalog->ShowInMenus = 0;
    1815                 $catalog->ShowInSearch = 0;
    1816                 $catalog->ShowInSiteMap = 0;
    1817                 $catalog->DevEditType = 'fixed';
    1818             }
    1819             $catalog->doPublish();
    1820             $this->specCatalogMapping[$title] = $catalog;
    1821         }
    1822         return $this->specCatalogMapping[$title];
    1823     }
    1824
    1825     // перемещаем файл в AssociatedFolder страницы, переносим только файлы из корня или виз.реда
    1826     function changeFileFolder($file, $page) {
    1827         if (isset($this->fileFolderChanging[$file->ID]) && $page->AssociatedFolderID) {
    1828             //перекинем картинку в связанную папку страницы
    1829             $file->ParentID = $page->AssociatedFolderID;
    1830             $file->write();
    1831             // чтоб еще раз не перенеслось
    1832             unset($this->fileFolderChanging[$file->ID]);
    1833         }
    1834     }
    1835
    1836     /*
    1837      * Меняем папку изображений, лежащих в общих папках
    1838      * Раскладываем файлы из папок "assets/images", "assets/images/root", "assets/images/Из документов"
    1839      * по папкам вида assets/images/Imported_N по 200 файлов в папку (пока 50)
    1840      * чтобы при вставке картинок из виз.реда дерево файлов и папок не подвисало
    1841      *
    1842      */
    1843     function correctImageFolders() {
    1844         $commonFolders = array(
    1845         array('Path' => 'assets/images', 'Title' => false),
    1846         array('Path' => 'assets/images', 'Title' => 'root'),
    1847         array('Path' => 'assets/images', 'Title' => 'Из документов'),
    1848         );
    1849
    1850         $n = '01';
    1851         $filesCount = 0;
    1852
    1853         foreach($commonFolders as $commonFolder) {
    1854             $imageFolder = Folder::findOrMake($commonFolder['Path']);
    1855             if (!$imageFolder)
    1856             continue;
    1857             if ($commonFolder['Title']) {
    1858                 $folder = DataObject::get_one('Folder', "Title = '".$commonFolder['Title']."' AND ParentID = {$imageFolder->ID}");
    1859             } else {
    1860                 $folder = $imageFolder;
    1861             }
    1862             if ($folder) {
    1863                 $files = DataObject::get('Image', "ParentID = {$folder->ID}");
    1864                 if ($files) {
    1865                     foreach($files as $file) {
    1866                         if ($filesCount && ($filesCount % 50 == 0)) { //пока по 50 файлов в папку
    1867                             $n++;
    1868                             if ($n < 10) {
    1869                                 $n = '0'.$n;
    1870                             }
    1871                         }
    1872                         $folder = Folder::findOrMake('images/Imported_' . $n);
    1873                         $file->setParentID($folder->ID);
    1874                         $file->write();
    1875                         $filesCount++;
    1876                     }
    1877                 }
    1878             }
    1879         }
    1880     }
    1881
    1882     /*
    1883      * Меняем папку файлов, лежащих в общих папках
    1884      * Раскладываем файлы из папок "assets/files", "assets/files/root", "assets/files/Из документов"
    1885      * по папкам вида assets/files/Imported_N по 200 файлов в папку (пока 50)
    1886      * чтобы при вставке картинок из виз.реда дерево файлов и папок не подвисало
    1887      *
    1888      */
    1889     function correctFileFolders() {
    1890         $commonFolders = array(
    1891         array('Path' => 'assets/files', 'Title' => false),
    1892         array('Path' => 'assets/files', 'Title' => 'root'),
    1893         array('Path' => 'assets/files', 'Title' => 'Из документов'),
    1894         );
    1895
    1896         $n = '01';
    1897         $filesCount = 0;
    1898
    1899         foreach($commonFolders as $commonFolder) {
    1900             $fileFolder = Folder::findOrMake($commonFolder['Path']);
    1901             if (!$fileFolder)
    1902                 continue;
    1903             if ($commonFolder['Title']) {
    1904                 $folder = DataObject::get_one('Folder', "Title = '".$commonFolder['Title']."' AND ParentID = {$fileFolder->ID}");
    1905             } else {
    1906                 $folder = $fileFolder;
    1907             }
    1908             if ($folder) {
    1909                 $files = DataObject::get('File', "ParentID = {$folder->ID}");
    1910                 if ($files) {
    1911                     foreach($files as $file) {
    1912                         if ($file->ClassName != 'File') //могут попадаться Folder
    1913                         continue;
    1914                         if ($filesCount && ($filesCount % 50 == 0)) { //пока по 50 файлов в папку
    1915                             $n++;
    1916                             if ($n < 10) {
    1917                                 $n = '0'.$n;
    1918                             }
    1919                         }
    1920                         $folder = Folder::findOrMake('files/Imported_' . $n);
    1921                         $file->setParentID($folder->ID);
    1922                         $file->write();
    1923                         $filesCount++;
    1924                     }
    1925                 }
    1926             }
    1927         }
    1928     }
    1929
    1930     /*
    1931      * Строим путь до страницы старого сайта относительно корня
    1932      *
    1933      * @param (int) $pageID - ID старой страницы
    1934      *
    1935      * @return (string) URL старой страницы
    1936      */
    1937     function getAbsoluteOldPath($pageID) {
    1938         $url = '';
    1939         while(isset($this->parentRelationsMapping[$pageID]) && isset($this->urlMapping[$pageID])) {
    1940             $url = $this->urlMapping[$pageID] . '/' . $url;
    1941             $newPageID = $this->parentRelationsMapping[$pageID];
    1942             if ($newPageID != $pageID) { // чтоб не зацикливалось
    1943                 $pageID = $newPageID;
    1944             } else {
    1945                 break;
    1946             }
    1947         }
    1948         return '/' . $url;
    1949     }
    1950 }
    1951

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -