Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[WordPress][Plugin] 外部サイトをクロールして、特定の要素を XPath で切り出して表示するウィジェット
<?php
/**
* Adds Remote_Site_Parts widget.
*/
add_action( 'widgets_init', function(){
register_widget( 'Remote_Site_Parts' );
});
class Remote_Site_Parts extends WP_Widget {
private $options = [
'title' => 'Title:',
'url' => 'URL:',
'xpath_query' => 'XPATH:',
'expiration' => 'Expiration:',
'user_agent' => 'User-Agent (option):',
'user' => 'BASIC Auth User (option):',
'password' => 'BASIC Auth Password (option):',
];
private $transient_key;
const DEFAULT_EXPIRATION = 60 * MINUTE_IN_SECONDS;
/**
* Register widget with WordPress.
*/
function __construct() {
parent::__construct(
'remote_site_parts', // Base ID
'Remote site parts' // Name
);
$this->transient_key = $this->get_field_id( 'transients' );
}
/**
* Outputs the options form on admin
*
* @see WP_Widget::form()
*
* @param array $instance The widget options
*/
public function form( $instance ) {
echo "<p>\n";
foreach ( $this->options as $key => $lavel ) {
$value = (! empty( $instance[$key] )) ? $instance[$key] : '';
if ( $key === 'expiration' ) {
$value = intval( isset( $instance[$key] ) ? $instance[$key] : self::DEFAULT_EXPIRATION );
}
printf(
'<label for="%s">%s</label>',
$this->get_field_id( $key ),
$lavel
);
printf(
'<input class="widefat" id="%s" name="%s" type="text" value="%s">',
$this->get_field_id( $key ),
$this->get_field_name( $key ),
esc_attr( $value )
);
echo "\n";
}
echo "</p>\n";
}
/**
* Sanitize widget form values as they are saved.
*
* @see WP_Widget::update()
*
* @param array $new_instance Values just sent to be saved.
* @param array $old_instance Previously saved values from database.
*
* @return array Updated safe values to be saved.
*/
public function update( $new_instance, $old_instance ) {
$instance = array();
foreach ( $this->options as $key => $lavel ) {
if ( $key === 'expiration' ) {
$value = intval( isset( $new_instance[$key] ) ? $new_instance[$key] : self::DEFAULT_EXPIRATION );
} else {
$value = sanitize_text_field( isset( $new_instance[$key] ) ? $new_instance[$key] : '' );
}
$instance[$key] = $value;
}
delete_transient( $this->transient_key );
return $instance;
}
/**
* Front-end display of widget.
*
* @see WP_Widget::widget()
*
* @param array $args Widget arguments.
* @param array $instance Saved values from database.
*/
public function widget( $args, $instance ) {
$defaults = [
'expiration' => self::DEFAULT_EXPIRATION
];
$instance = wp_parse_args((array) $instance, $defaults );
if ( empty( $instance['url'] ) || empty( $instance['xpath_query'] ) ) {
return;
}
if ( false === ( $output_html = get_transient( $this->transient_key ) ) ) {
$output_html = '';
$remote_get_args = [];
if ( ! empty( $instance['user'] ) && ! empty( $instance['password'] ) ) {
$remote_get_args['headers'] = [
'Authorization' => 'Basic '.base64_encode( "{$instance['user']}:{$instance['password']}" ),
];
}
if ( ! empty( $instance['user_agent'] ) ) {
$remote_get_args['user-agent'] = $instance['user_agent'];
}
$response = wp_remote_get( $instance['url'], $remote_get_args );
if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) == 200 ) {
$html = wp_remote_retrieve_body( $response );
$dom = new DOMDocument;
@$dom->loadHTML( $html );
$xpath = new DOMXPath( $dom );
foreach ( $xpath->query( $instance['xpath_query'] ) as $node ) {
$output_html .= $this->getInnerHtml( $node );
}
unset( $dom );
unset( $xpath );
set_transient( $this->transient_key, $output_html, intval( $instance['expiration'] ) );
}
unset( $remote_get_args );
unset( $response );
}
echo isset($args['before_widget']) ? $args['before_widget'] : '';
echo $output_html;
echo isset($args['after_widget']) ? $args['after_widget'] : '';
}
/**
*
*
* @param array $node object
*/
private function getInnerHtml($node){
$children = $node->childNodes;
$html = '';
foreach( $children as $child ){
$html .= $node->ownerDocument->saveHTML( $child );
}
unset( $children );
return $html;
}
} // class Remote_Site_Parts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment