Загрузка объектов недвижимости на wordpress через xml по крону
Заказать разработку плагинов для wordpress можно через мой кворк или обратившись ко мне напрямую.
Описание решения
За основу взята статья WORDPRESS WOOCOMMERCE: ДОБАВЛЕНИЕ КАТЕГОРИЙ И ТОВАРОВ ПО API В КАТАЛОГ
На проекте используются:
- Residence Real Estate WordPress Theme
- функционал https://skr.sh/sEXsRFo6zvF
- WP 6.0
- выгрузка из CRM в формате xml
- крон
Создаем в корне сайта папку for_xml_feed и кладем туда два файла:
- главный файл index.php
- файл функций lib.php
Скриншоты



Главный файл index.php
<?php //БЛОК1 require_once( '../wp-config.php' ); require_once( '../wp-load.php' ); require_once( ABSPATH . '/wp-admin/includes/taxonomy.php'); require_once( 'lib.php' ); ini_set('display_errors', 'On'); // сообщения с ошибками будут показываться error_reporting(E_ALL); // E_ALL - отображаем ВСЕ ошибки set_time_limit(0); //Не ограничиваем время работы скрипта if(file_exists('file_properties.xml')) unlink('file_properties.xml'); $url = 'https://api.for-est.me/listings/feed/generic'; $str = file_get_contents($url); file_put_contents('file_properties.xml',$str); if(file_exists('lastparsing.txt') AND filesize('file_properties.xml')===(int)file_get_contents('lastparsing.txt')) die('Синхронизация не требуется, т.к. файл выгрузки CRM не изменился'); $xml = simplexml_load_file("file_properties.xml"); //БЛОК2 //СТАРТ БЛОКА ДОБАВЛЕНИЯ КАТЕГОРИЙ $count = count($xml->property); $key = 0; while ($count > $key) { $CatName = $xml->property[$key]->category; $ParentID = 0; $k = SearchCat($CatName); $ParentCatID = ''; if (!$k) { if ( $ParentID ) { $x = SearchParentId ($ParentID, $xmlCat); if ($x) { $x = SearchCat($x); }; if ($x) { $ParentCatID = (array)$x -> term_id; $ParentCatID = (string)$ParentCatID[0]; } }; $cat_defaults = array( 'cat_name' => $CatName, // название категории. Обязательный. 'category_description' => '', // описание категории 'category_nicename' => '', // слаг категории 'category_parent' => $ParentCatID, // ID родительской категории 'taxonomy' => 'product_cat' ); $cat_id = wp_insert_category( $cat_defaults, true); } else {/*echo 'Категория ID ' ,$k -> term_id,' существует' */;}; $key++; }; //КОНЕЦ БЛОКА ДОБАВЛЕНИЯ КАТЕГОРИЙ // БЛОК3 $postIds = "; foreach ($xml->property as $k => $v) { $Find = FindArt($v); if (!$Find){ $id =Xml2Perem($v); if($id) $postIds .= ",".$id; } else { echo "Листинг --".$v->title."-- уже есть. Его ид = $Find".'<br/>'; $postIds .= ",".$Find; }; }; $postIds = trim($postIds,','); $postIds = "(".$postIds; $postIds .= ")"; $link = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD,DB_NAME) or die('Не удалось соединиться: ' . mysqli_error()); mysqli_set_charset($link, "utf8"); $query = "DELETE FROM `wp_term_relationships` WHERE `object_id` IN (SELECT id FROM `wp_posts` WHERE `post_type` = 'estate_property' AND `id` NOT IN $postIds);"; $result = query_do($link,$query); $query = "DELETE FROM `wp_postmeta` WHERE `post_id` IN (SELECT id FROM `wp_posts` WHERE `post_type` = 'estate_property' AND `id` NOT IN $postIds)"; $result = query_do($link,$query); $query = "DELETE FROM `wp_pmxi_posts` WHERE `post_id` IN (SELECT id FROM `wp_posts` WHERE `post_type` = 'estate_property' AND `id` NOT IN $postIds)"; $result = query_do($link,$query); $query = "DELETE FROM `wp_pmxi_hash` WHERE `post_id` IN (SELECT id FROM `wp_posts` WHERE `post_type` = 'estate_property' AND `id` NOT IN $postIds)"; $result = query_do($link,$query); $query = "CREATE TEMPORARY TABLE `wp_posts_copy` ( `id` int(11) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8"; $result = query_do($link,$query); $query = "INSERT INTO wp_posts_copy (id) SELECT id FROM `wp_posts` WHERE `post_type` = 'estate_property' AND `id` NOT IN $postIds"; $result = query_do($link,$query); $query = "DELETE FROM `wp_posts` WHERE `post_type` = 'attachment' AND `post_parent` IN (SELECT id FROM `wp_posts_copy`)"; $result = query_do($link,$query); $query = "DELETE FROM `wp_posts` WHERE `post_type` = 'estate_property' AND `id` IN (SELECT id FROM `wp_posts_copy`)"; $result = query_do($link,$query); mysqli_close($link); function query_do($link,$sql) { $result = mysqli_query($link,$sql); if(!empty(mysqli_error($link))) { printf("Error: %sn%snn", mysqli_error($link), $sql); mysqli_close($link); die; } return $result; } file_put_contents('lastparsing.txt',filesize('file_properties.xml')); die('Синхронизация завершена'); ?>
Файл функций lib.php
<?php Function SearchCat ($Cat) { $cat_id = get_term_by( 'name', $Cat, 'property_category', 'OBJECT', 'raw' ); if ($cat_id) {return $cat_id;} else {return false;}; } Function SearchParentId ($ParentID, $xmlCat) { $size = sizeof( $xmlCat ) - 1; $i = 0; while($i <= $size) { $CatID = (string)$xmlCat[$i]['id'] ; if (isset( $xmlCat[$i] ) ){ if ($CatID == $ParentID) { return (string)$xmlCat[$i]; } } else {return False;}; $i++; } } Function FindArt ($xmlOffer){ $Art = (string)$xmlOffer->title; $NumArt = SearchArt ($Art,'estate_property'); if ($NumArt) { return $NumArt; } else { return false; }; }; Function SearchArt ($Art,$type ) { $Art = trim($Art); $Art = str_replace(array('+','-'),' ',$Art); $query = new WP_Query("s=$Art"); $index = array_search($Art,array_column($query->posts,'post_title')); //или вот так //$index = 0; /* $query->posts = array_filter($query->posts, function ($var) { global $Art; return($var['post_title'] === $Art); }); */ $post_id = 0; if($index !==false) { $post_id = (array)$query->posts[$index]; if($post_id['post_type'] === $type) $post_id = $post_id['ID']; } wp_reset_postdata(); return $post_id ; } Function Xml2Perem ($xmlOffer) { $title = trim((string)($xmlOffer -> title)); $title = str_replace(array('+','-'),' ',$title); $post = array( 'post_author' => 1, 'post_content' => (string)($xmlOffer -> description), 'post_excerpt' => '', 'post_status' => "publish", 'post_title' => $title, 'post_type' => "estate_property", ); $post_id = wp_insert_post($post); wp_set_object_terms( $post_id, (string)($xmlOffer->category), 'property_category' ); wp_set_object_terms( $post_id, (string)$xmlOffer->property_for, 'property_for' ); wp_set_object_terms( $post_id, (string)$xmlOffer->city, 'property_city' ); wp_set_object_terms( $post_id, (string)$xmlOffer->project_status, 'project_status' ); wp_set_object_terms( $post_id, (string)$xmlOffer->property_type, 'property_action_category'); update_post_meta( $post_id, 'property_price', (string)$xmlOffer->price.(string)$xmlOffer->price_currency ); update_post_meta( $post_id, 'property_size', (string)$xmlOffer->size); update_post_meta( $post_id, 'property_label', ' / '.(string)$xmlOffer->size_unit.'.'); update_post_meta( $post_id, 'property_bedrooms', (string)$xmlOffer->bedrooms); update_post_meta( $post_id, 'property_bathrooms', (string)$xmlOffer->bathrooms); update_post_meta( $post_id, 'mls', (string)$xmlOffer->reference); update_post_meta( $post_id, 'property_latitude', (string)$xmlOffer->latitude); update_post_meta( $post_id, 'property_longitude', (string)$xmlOffer->longitude); update_post_meta( $post_id, 'property_label_before', 'from'); require_once(ABSPATH . 'wp-admin/includes/file.php'); require_once(ABSPATH . 'wp-admin/includes/media.php'); require_once(ABSPATH . "wp-admin" . '/includes/image.php'); $thumb_url = (string)($xmlOffer->images->image[0]); $thumb_url_all = $xmlOffer->images->image; unset($thumb_url_all[0]); $tmp = download_url( $thumb_url ); if( !is_wp_error( $tmp ) ) { preg_match('/[^?]+.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $thumb_url, $matches); $file_array['name'] = basename($matches[0]); $file_array['tmp_name'] = $tmp; $thumbid = media_handle_sideload( $file_array, $post_id, $title); //Описание изображения set_post_thumbnail($post_id, $thumbid); } foreach($thumb_url_all as $key => $value) { $tmp2 = download_url( (string)$value ); if ($tmp2) { preg_match('/[^?]+.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', (string)$value, $matches); $file_array2['name'] = basename($matches[0]); $file_array2['tmp_name'] = $tmp2; $imgID = media_handle_sideload( $file_array2, $post_id, $title); }; } wp_update_post( $post_id); shell_exec('rm -rf /tmp/*'); /*agent*/ //estate_agent estate_property $agt_name = (string)$xmlOffer->agent->name; $agt_id = SearchArt($agt_name,'estate_agent'); if($agt_id) { update_post_meta( $post_id, 'property_agent', $agt_id); } else { $agt = array( 'post_author' => 1, 'post_content' => '', 'post_excerpt' => '', 'post_status' => "publish", 'post_title' => $agt_name, 'post_type' => "estate_agent", ); $agt_id = wp_insert_post($agt); update_post_meta( $agt_id, 'agent_email', (string)$xmlOffer->agent->email); update_post_meta( $agt_id, 'agent_mobile', (string)$xmlOffer->agent->mobile); // update_post_meta( $agt_id, 'agent_facebook', $agt_id); foreach ($xmlOffer->agent->link as $item => $link) { # code... $net = (string)$link; if(preg_match('/linkedin/', $net)) { update_post_meta( $agt_id, 'agent_linkedin', $net); } // if(preg_match('/t.me/', $net)) { // update_post_meta( $agt_id, 'agent_telegram', $net); // } if(preg_match('/@/', $net)) { update_post_meta( $agt_id, 'agent_instagram', $net); } if(preg_match('/instagram/', $net)) { update_post_meta( $agt_id, 'agent_instagram', $net); } } update_post_meta( $post_id, 'property_agent', $agt_id); $thumb_url = (string)($xmlOffer->agent->profile_picture); $tmp = download_url( $thumb_url ); if( !is_wp_error( $tmp ) ) { preg_match('/[^?]+.(jpg|JPG|jpe|JPE|jpeg|JPEG|gif|GIF|png|PNG)/', $thumb_url, $matches); $file_array['name'] = basename($matches[0]); $file_array['tmp_name'] = $tmp; $thumbid = media_handle_sideload( $file_array, $agt_id, $agt_name); //Описание изображения set_post_thumbnail($agt_id, $thumbid); wp_update_post( $agt_id); shell_exec('rm -rf /tmp/*'); } echo ' Агент № - '.$agt_id .'<br/>'; } /*agent*/ echo ' Пост № - '.$post_id .'<br/>'; return $post_id; }