Проблемы с кодировкой HTML и отображением изображений в формате WP http XML-ответа
Это мой самый первый WP-плагин. Вероятно, здесь будет больше одного вопроса, и все они связаны, поэтому я собираюсь задать все здесь.
Рабочий тест здесь
Используемый номер отслеживания: lc0614061377
Пример XML-ответа от tracenow.net
:
<Consignment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<consignmentNumber>lc0614061377</consignmentNumber>
<customerRef/>
<itemCount>1</itemCount>
<name>six red squares</name>
<address1>unit 7b victoria business park</address1>
<address2>short street</address2>
<town>SOUTHEND ON SEA</town>
<county>ESSEX</county>
<postcode>ss2 5by</postcode>
<country>United Kingdom</country>
<recipient>cannon</recipient>
<status>Delivered</status>
<collected>0001-01-01T00:00:00</collected>
<delivered>2014-07-25T10:00:50</delivered>
<collectionCode/>
<deliveryCode>Delivered OK</deliveryCode>
<comments/>
<created>2014-07-24T15:00:40</created>
<deliveryLatitude>51.54617</deliveryLatitude>
<deliveryLongitude>0.712245</deliveryLongitude>
<deliverySignature>
http://resources.tracenow.net/signatures/d5dbffb4-0336-44bf-b72c-00fb9aaac759/0a630170-1390-4ca4-b104-5ca4b9b6199f.jpg
</deliverySignature>
<deliveryImage>
http://resources.tracenow.net/images/d5dbffb4-0336-44bf-b72c-00fb9aaac759/6de6c2bd-236b-447d-a106-b1a7bd537645.jpg
</deliveryImage>
</Consignment>
Это текущее состояние моего кода:
// tracenow.php
<?php
/*
Plugin Name: TraceNow Tracking
Plugin URI: http://www.titandesign.co.uk
Description: A simple parcel tracking plugin for Codeway TraceNow.
Version: 4.0
Author: Richard King
Author URI: http://www.titandesign.co.uk/
License: GPL-2.0+
License URI: http://www.opensource.org/licenses/gpl-license.php
*/
wp_enqueue_script( 'my-ajax-handle', plugin_dir_url( __FILE__ ) . 'ajax.js', array( 'jquery' ) );
wp_enqueue_style( 'my-ajax-handle', plugin_dir_url( __FILE__ ) . 'style.css' );
wp_localize_script( 'my-ajax-handle', 'the_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
// THE TRACKING FUNCTION
if( !class_exists( 'WP_Http' ) )
include_once( ABSPATH . WPINC. '/class-http.php' );
function tracking_function(){
//if ( isset( $_POST['consignmentNumber'] ) && '1' == $_POST['consignmentNumber'] ){
$consignmentNumber = $_POST['consignmentNumber'];
$url = ('http://services.tracenow.net/TraceNowAccess.asmx/GetConsignment?consignmentNumber=' .($consignmentNumber) .'&externalAccessGuid=d5dbffb4-0336-44bf-b72c-00fb9aaac759');
$args = array(
'method' => 'GET',
'timeout' => 45,
'redirection' => 5,
'httpversion' => '1.1',
'content-type' => 'application/x-www-form-urlencoded',
'body' => array(),
'headers' => array(),
'blocking' => true,
'cookies' => array(),
'connection' => 'close',
);
$response = wp_remote_get( $url, $args );
if ( is_wp_error( $response ) ) {
$error_message = $response->get_error_message();
echo "Something went wrong: $error_message";
} else {
/*include ('/render_xml_to_html.php');
if(function_exists('render_xml_data')){
render_xml_data('example_data.xml');
}else{
echo null;
} */
echo '<h3>Consignment Details</h3>' . '<pre>' . print_r($response['body'], true) . '</pre>';// this is passed back to the javascript function
die();
} // end if
//} // end if
}
// THE AJAX ADD ACTIONS
add_action( 'wp_ajax_the_ajax_hook', 'tracking_function' );
add_action( 'wp_ajax_nopriv_the_ajax_hook', 'tracking_function' ); // need this to serve non logged in users
// ADD TRACKING FORM TO THE PAGE
function tracenow_frontend(){
$the_form = '
<form id="theForm" method="POST">
<input id="consignmentNumber" name="consignmentNumber" value="Consignment No" type="text" />
<input name="action" type="hidden" value="the_ajax_hook" /> <!-- this puts the action the_ajax_hook into the serialized form -->
<input id="submit_button" value="Track" type="button" onClick="submit_me();" />
</form>
<div id="response_area">
Your tracking details will appear here
</div>';// END DIV RESPONSE AREA
return $the_form;
}
add_shortcode("tn_ajax_frontend", "tracenow_frontend");
// ajax.js
function submit_me(){
jQuery.post(the_ajax_script.ajaxurl, jQuery('#theForm').serialize()
,
function(response_from_tracking_function){
jQuery("#response_area").html(response_from_tracking_function);
}
);
jQuery('#theForm').find('input[type=text]').val('Consignment No');
}
// render_xml_to_html.php
<?php
/*
Written by Gary Hollands Sept 2010
This work is available under the terms of the GNU General Public License, http://www.gnu.org/licenses/gpl.html
render_xml_data is a function that can use XML data and present that data as HTML.
*/
function render_xml_data($path_to_xml_file){
if (!file_exists($path_to_xml_file)){
return;
}else{
$chars_to_replace = array('[\r]','[\n]','[\t]');
$xmlstring = trim(preg_replace($chars_to_replace, '', file_get_contents($path_to_xml_file)));
}
$xml = new SimpleXMLElement($xmlstring);
foreach ($xml->consignment as $consign) {
echo '<div class="consignment">'."\n";
echo '<h3>'.$consign->consignmentnumber.'</h3>'."\n";
echo '<p><span class="category">Customer Ref: </span>'.$consign->customerref.'</p>'."\n";
echo '<p><span class="category">Number of items: </span>'.$consign->itemcount.'</p>'."\n";
echo '<p><span class="category">Name: </span>'.$consign->name.'</p>'."\n";
echo '<p><span class="category">Address 1: </span>'.$consign->address1.'</p>'."\n";
echo '<p><span class="category">Address 2: </span>'.$consign->address2.'</p>'."\n";
echo '<p><span class="category">Town: </span>'.$consign->town.'</p>'."\n";
echo '<p><span class="category">County: </span>'.$consign->county.'</p>'."\n";
echo '<p><span class="category">Postcode: </span>'.$consign->postcode.'</p>'."\n";
echo '<p><span class="category">Country: </span>'.$consign->country.'</p>'."\n";
echo '<p><span class="category">Recipient: </span>'.$consign->recipient.'</p>'."\n";
echo '<p><span class="category">Status: </span>'.$consign->status.'</p>'."\n";
echo '<p><span class="category">Collected: </span>'.$consign->collected.'</p>'."\n";
echo '<p><span class="category">Delivered: </span>'.$consign->delivered.'</p>'."\n";
echo '<p><span class="category">Collection Code: </span>'.$consign->collectioncode.'</p>'."\n";
echo '<p><span class="category">Delivery Code: </span>'.$consign->deliverycode.'</p>'."\n";
echo '<p><span class="category">Comments: </span>'.$consign->comments.'</p>'."\n";
echo '<p><span class="category">Created: </span>'.$consign->created.'</p>'."\n";
echo '<p><span class="category">Delivery Latitude: </span>'.$consign->deliverylatitude.'</p>'."\n";
echo '<p><span class="category">Delivery Longitude: </span>'.$consign->deliverylongitude.'</p>'."\n";
echo '<p><span class="category">Delivery Signature: </span><img src="/'.$consign->deliverysignature.'/"/></p>'."\n";
echo '<p><span class="category">Delivery Image: </span><img src="/'.$consign->deliveryimage.'/"/></p>'."\n";
echo '</div><!--end consignment-->'."\n";
}
}
Итак, для начала. Функция отслеживания заключается в работает и возвращает ответ с сервера нормально.
- Как мне получить ответ для отображения в виде HTML, который будет отображаться на странице. В данный момент он возвращает XML-текст запроса, который является именно тем, что мне нужно. Мне нужно нацелиться на узлы, которые не являются пустыми, и вернуть их с заголовком.
Пример для номера отправления я хочу добавить заголовок
'Consignment No:'
. То же самое дляaddress
,status
,time
,GeoLoc
и т.д. Я рассматривал возможность использования jQuery и CSS: перед добавлением заголовка. У меня также есть файлrender_xml_to_html.php
, который, как я предполагал, был правильным методом, однако единственный результат, который я получаю, когда подразумевается, равен 0. Есть какие-нибудь предложения? - В XML-ответе есть ссылки на 2 изображения, но у них нет тега img, классов или идентификаторов, поэтому мне сложно настроить таргетинг на эти файлы изображений. Я попытался настроить таргетинг.jpg, но это просто не сработало. Мне нужно добавить
img
,src=""
и тегиalt=""
, чтобы я мог отображать ссылки на изображения в виде изображений. Помогите, пожалуйста. - Защита плагина: У меня есть попытался добавить wp_nonce в вызов ajax для проверки запроса формы. Я также пытался создать и добавить nonce в функцию отслеживания, но снова получаю ошибку. Это действительно поставило меня в тупик. Сейчас я прочитал так много блогов о добавлении nonce, что я совершенно сбит с толку и мог бы сделать легкий толчок в правильном направлении.
- Я хотел бы отправить ответ на страницу под названием результаты. Это существующая страница. Я проверил кодекс, но единственным вариантом, который я смог найти, был
addpage
, который каждый раз создает новую страницу. Причина: Я хотел бы иметь возможность добавить плагин в качестве виджета.
1 answers
Регистрация зависимостей
WordPress использует для этого API зависимостей . Это довольно просто: зарегистрируйте и поставьте в очередь скрипт, затем передайте данные, которые вы хотите передать из WP/PHP в JS, используя wp_localize_script()
, который добавляет тег <script>
, содержащий массив, в ваш DOM (точно до того, как ваш скрипт будет добавлен в него):
add_action( 'wp_enqueue_scripts', function()
{
$name = 'handle';
wp_register_script(
$name,
plugins_url( 'assets/ajax.js', __FILE__ ),
[ 'jquery' ],
filemtime( plugins_dir_path( __FILE__ ).'assets/ajax.js' ),
true
);
wp_enqueue_script( $name );
wp_localize_script(
$name,
"{$name}Obj", // This string is what gives you access to below array
[
'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
'_ajax_nonce' => wp_create_nonce( "{$name}_action" ),
'action' => "{$name}_action",
'data' => [ /* additional data as array */ ],
]
);
} );
Вы можете заметить, что я использовал wp_create_nonce()
и передал атрибут действия вызову по соображениям безопасности (проверка происхождения запроса в вашем обратный вызов).
Как выполнить удаленный запрос и получить XML-данные
При загрузке данных из удаленного запроса следует использовать WP HTTP API, но с функциями более высокого уровня.
Пример плагина, который выполнит запрос и добавит результат под вашим нижним колонтитулом (как для администратора, так и для внешнего интерфейса):
<?php
/** Plugin Name: (#160775) Fetch XML from TraceNow.net - Part 1 */
add_action( 'shutdown', function()
{
$request = wp_remote_get(
'http://services.tracenow.net/TraceNowAccess.asmx/GetConsignment?'.
join( '&', [
'consignmentNumber' => 'lc0614061377',
'externalAccessGuid' => 'd5dbffb4-0336-44bf-b72c-00fb9aaac759'
],
);
$response = wp_remote_retrieve_body( $request, [
// *additional args
] );
is_wp_error( $response )
AND wp_send_json_error( $response->get_error_code() );
if (
'OK' !== wp_remote_retrieve_response_message( $response )
OR 200 !== wp_remote_retrieve_response_code( $response )
)
wp_send_json_error( $response );
var_dump( wp_send_json_success( $response ) );
} );
Это самый простой способ выполнения таких запросов. Как вы можете видеть, я использую JSON. XML исчез из WPs HTTP API, так как некоторые версии, такие как JSON, проще в использовании.
Подсказка: wp_remote_*()
принимает второй аргумент, массив аргументов, о которых вы можете прочитать в коде.
Выполнение действия
Независимо от того, включен ли AJAX (см. Архив ajax для получения дополнительной информации) или нет, вам нужна форма.
<form id="asktracenow">
<input name="consignmentNumber" />
<input name="submit" value="submit" />
</form>
Теперь, когда эта форма отправляет данные $_POST
, вы захотите очистить их, прежде чем использовать в своем URL-адресе. У вас есть несколько вариантов в зависимости от того, как построены данные. Сначала мы просто $cnum = trim( $_POST['consignmentNumber'] )
, затем мы проверьте и в случае необходимости очистите его.
if ( false !== filter_var( $cnum, FILTER_VALIDATE_INT ) )
{
// do stuff with your absolute, positive integer
// adjust the check to only pass valid data
}
Убедитесь, что вы придаете этому большое значение - вы никогда не знаете, что получите взамен.
Аяксификация вещей
Просто подключайте вещи к действию WP. Подводя итог, это будет выглядеть примерно так.
// Public or private?
add_action( 'wp_ajax_handle_action', function( $data )
{
check_ajax_referer( $data['action'] );
# @TODO sanitize data here:
// filter_var() filter_var_array() and filter_input()
# @TODO Custom logic here
// Error?
if ( is_wp_error( $thing ) )
wp_send_json_error( $data );
// Success!
wp_send_json_success( $data );
} );
Подсказка: Поместите все это в отдельный плагин для разделения проблем и переносимости.
JavaScript AJAX/обработка запросов
Чтобы сделать этот ответ немного более полным, вот ссылка к другому моему ответу, в котором это подробно объясняется и к которому прилагается огромный пример.