На примере этого переезда разбираемся с работой с MySQL через
Нашел интересную по данному вопросу на хабре. Кто интересуется - может более подробно изучить данный вопрос.
Итак, приступим.
Имеем сайт на какой-то CMS (честно: особо не интересовался, что то за CMS-ка такая...). Есть доступ к базе данных данного сайта.
Отключаем ограничение на время исполнения скрипта:
set_time_limit(0);
Подключаем пролог и необходимые модули:
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
CModule::IncludeModule("iblock");
CModule::IncludeModule("sale");
Создаем массив для продуктов:
$products=array();
Создаем функцию, которая будет получать данные:
function GetFromMysqlData(){
GLOBAL $products;
$hostname = 'XXX.XXX.XXX.XXX'; // IP сервера
$port='XXXX'; // порт (если для подключения к серверу MySQL нужен порт)
$username = 'UNAME';
$password = 'UPASSWORD';
$dbname='DBNAME';
$dsn = 'mysql:dbname='.$dbname.';host='.$hostname.';port='.$port;
// если порт для подключения не нужен последний параметр не нужен
// дальше подключаемся к базе данных:
try{
$DBH = new PDO($dsn, $username, $password,array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''));
}
catch(PDOException $e) {
echo $e->getMessage();
}
$sql="sel ect * from `products`"; // тут пишите свой запрос
// выполняем данный запрос:
$STH = $DBH->query($sql);
$STH->setFetchMode(PDO::FETCH_ASSOC);
// перебираем все строки запроса:
while($row = $STH->fetch()) {
$products[$row["id"]]=$row;
}
// если нужны еще какие-то запросы получаем данные по ним дальше
// закрывает подключение
$DBH = null;
return;
}
Пишем функцию добавления нового элемента инфоблока:
function addElement($Product) {
$IB=##; // инфоблок, в который будет добавляться товар
// тут ничего сверхествественного смотрите формирование массива для добавления тут :
//http://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/add.php
в массив параметров для добавления настоятельно рекомендую добавить вот такую строку:
$arLoadProductArray["XML_ID"]=$Product["productID"]; // , где $Product["productID"] - ID товара на сайте-оригинале
// добавляем новый элемент инфоблока:
if($PRODUCT_ID = $el->Add($arLoadProductArray)){
$res="New ID: ".$PRODUCT_ID." => ".$Product["productID"];
// добавляем товар в каталог продукции:
$arFields=array(
"ID"=>$PRODUCT_ID,
"QUANTITY"=>1
);
if(CCatalogProduct::Add($arFields))
$res.='
Добавили параметры товара к элементу каталога '.$PRODUCT_ID.'
';
else
$res.='
Ошибка добавления параметров
';
// устанавливаем цену на товар:
$PRICE_TYPE_ID = 1;
$arFields = Array(
"PRODUCT_ID" => $PRODUCT_ID,
"CATALOG_GROUP_ID" => $PRICE_TYPE_ID,
"PRICE" => $Price,
"CURRENCY" => "RUB" /*код валюты*/
);
$Priceres = CPrice::GetList(
array(),
array(
"PRODUCT_ID" => $PRODUCT_ID,
"CATALOG_GROUP_ID" => $PRICE_TYPE_ID
)
);
if ($arr = $Priceres->Fetch()){
CPrice::Update($arr["ID"], $arFields);
} else {
CPrice::Add($arFields);
}
}
return $res/*=array("array"=>$arLoadProductArray,"res"=>$res)*/;
}
Запускаем функцию получения данных из базы:
GetFromMysqlData();
Перебираем все товары, полученные из базы. Если нужны какие-то манипуции с данными, полученными из базы, перед подключением добавления нового товара проводим эти манипуляции:
foreach($products as $element){
addElement($element);
}
Вот в принципе и все. Получили данные из базы, обработали их, добавили на сайт.
И вот тут понимаем, что одна из таблиц сайта-оригинала содержит какие-то свойства, которые никак не привязаны напрямую к таблице с товарами.
Вот тут-то и понадобится параметр
$arLoadProductArray["XML_ID"]
который мы предусмотрительно создали при добавлении товаров. Воспользуемся им для обновления товаров.
Создаем еще один запрос к старой базе (у меня свойство было - доп. изображения товара):
$STH = $DBH->query('select photoID, productID, filename fr om product_pictures');
$STH->setFetchMode(PDO::FETCH_ASSOC);
while($row = $STH->fetch()) {
// вытаскиваем одну за другой строки, помещаем в $row
$photos[$row["productID"]][]=array(
"PhotoID"=>$row["photoID"],
"Photo"=>$row["filename"],
"ProductID"=>$row["productID"]
);
}
перебираем все товары в инфоблоке:
$arSelect = Array("ID", "NAME", "DATE_ACTIVE_FROM", "XML_ID" ,"PROPERTY_PHOTO_TITLE");
$arFilter = Array("IBLOCK_ID"=>IntVal(3), "ACTIVE_DATE"=>"Y", "ACTIVE"=>"Y");
$res = CIBlockElement::GetList(Array(), $arFilter, false, Array("nPageSize"=>5000), $arSelect);
while($arFields = $res->GetNext())
{
echo AddPhotos($arFields["ID"],$photos[$arFields["XML_ID"]]);
}
AddPhotos - функция добавления значений свойства типа "Файл" к товару:
function AddPhotos($ID,$photos){
$value="";
$k=0;
foreach($photos as $k=>$photo){
$img=$photo["Photo"];
$arFile=false;
if (file_exists($_SERVER["DOCUMENT_ROOT"]."/upload/oldimages/big/".$img)){
if(strlen($img)>0){
$arFile=CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"]."/upload/oldimages/big/".$img);
}
} elseif (file_exists($_SERVER["DOCUMENT_ROOT"]."/upload/oldimages/extra/".$img)){
if(strlen($img)>0){
$arFile=CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"]."/upload/oldimages/extra/".$img);
}
}
if(is_array($arFile)){
$arFile["MODULE_ID"] = "iblock";
}
$value["n".$k]=$arFile;
}
$res=CIBlockElement::SetPropertyValueCode($ID, "MORE_PHOTO", $value);
return $value;
}
Скажу честно: мне повезло, что все изображения для старого сайта хранились в 2-х папках: "big" и "extra" и привязка изображений к товарам делалась просто по имени файла изображения. Эти 2 папки просто перелил по ftp со старого сайта в папку uploads нового...
Вот и все... всем спасибо за внимание. Если кто-то впустую потратил время прочитав мою статью - звыняйте:) Кому хоть как-то помог - очень рад. У кого есть вопросы - пишите. Не обещаю ответить сразу, но постараюсь по мере возможности.
P.S.