6235 | | // FIXME: does url_to_postid() cover all these cases already? |
6236 | | // if so, then let's use it and drop the old code. |
6237 | | $urltest = parse_url($pagelinkedto); |
6238 | | if ( $post_ID = url_to_postid($pagelinkedto) ) { |
6239 | | // $way |
6240 | | } elseif ( isset( $urltest['path'] ) && preg_match('#p/[0-9]{1,}#', $urltest['path'], $match) ) { |
6241 | | // the path defines the post_ID (archives/p/XXXX) |
6242 | | $blah = explode('/', $match[0]); |
6243 | | $post_ID = (int) $blah[1]; |
6244 | | } elseif ( isset( $urltest['query'] ) && preg_match('#p=[0-9]{1,}#', $urltest['query'], $match) ) { |
6245 | | // the querystring defines the post_ID (?p=XXXX) |
6246 | | $blah = explode('=', $match[0]); |
6247 | | $post_ID = (int) $blah[1]; |
6248 | | } elseif ( isset($urltest['fragment']) ) { |
6249 | | // an #anchor is there, it's either... |
6250 | | if ( intval($urltest['fragment']) ) { |
6251 | | // ...an integer #XXXX (simplest case) |
6252 | | $post_ID = (int) $urltest['fragment']; |
6253 | | } elseif ( preg_match('/post-[0-9]+/',$urltest['fragment']) ) { |
6254 | | // ...a post id in the form 'post-###' |
6255 | | $post_ID = preg_replace('/[^0-9]+/', '', $urltest['fragment']); |
6256 | | } elseif ( is_string($urltest['fragment']) ) { |
6257 | | // ...or a string #title, a little more complicated |
6258 | | $title = preg_replace('/[^a-z0-9]/i', '.', $urltest['fragment']); |
6259 | | $sql = $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE post_title RLIKE %s", $title ); |
6260 | | if (! ($post_ID = $wpdb->get_var($sql)) ) { |
6261 | | // returning unknown error '0' is better than die()ing |
6262 | | return $this->pingback_error( 0, '' ); |
6263 | | } |
6264 | | } |
6265 | | } else { |
6266 | | // TODO: Attempt to extract a post ID from the given URL |
| 6235 | $post_ID = url_to_postid($pagelinkedto); |
| 6236 | if ( ! $post_ID ) { |
| 6280 | // Make sure the resource is a valid one before retrieving it |
| 6281 | $request = wp_safe_remote_head( $pagelinkedfrom, $http_api_args ); |
| 6282 | $content_type = wp_remote_retrieve_header( $request, 'content-type' ); |
| 6283 | if ( is_wp_error( $request ) ) { |
| 6284 | return $this->pingback_error( 16, __( 'The source URL does not exist.' ) ); |
| 6285 | } |
| 6286 | // Protect Against Someone Trying to Make Us Download Media Files |
| 6287 | if ( preg_match( '#(image|audio|video|model)/#is', $content_type ) ) { |
| 6288 | return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) ); |
| 6289 | } |
6323 | | // Work around bug in strip_tags(): |
6324 | | $remote_source = str_replace( '<!DOC', '<DOC', $remote_source ); |
6325 | | $remote_source = preg_replace( '/[\r\n\t ]+/', ' ', $remote_source ); // normalize spaces |
6326 | | $remote_source = preg_replace( "/<\/*(h1|h2|h3|h4|h5|h6|p|th|td|li|dt|dd|pre|caption|input|textarea|button|body)[^>]*>/", "\n\n", $remote_source ); |
6327 | | |
6328 | | preg_match( '|<title>([^<]*?)</title>|is', $remote_source, $matchtitle ); |
6329 | | $title = $matchtitle[1]; |
6330 | | if ( empty( $title ) ) |
6331 | | return $this->pingback_error( 32, __('We cannot find a title on that page.' ) ); |
6332 | | |
6333 | | $remote_source = strip_tags( $remote_source, '<a>' ); // just keep the tag we need |
6334 | | |
6335 | | $p = explode( "\n\n", $remote_source ); |
6336 | | |
6337 | | $preg_target = preg_quote($pagelinkedto, '|'); |
6338 | | |
6339 | | foreach ( $p as $para ) { |
6340 | | if ( strpos($para, $pagelinkedto) !== false ) { // it exists, but is it a link? |
6341 | | preg_match("|<a[^>]+?".$preg_target."[^>]*>([^>]+?)</a>|", $para, $context); |
6342 | | |
6343 | | // If the URL isn't in a link context, keep looking |
6344 | | if ( empty($context) ) |
6345 | | continue; |
6346 | | |
6347 | | // We're going to use this fake tag to mark the context in a bit |
6348 | | // the marker is needed in case the link text appears more than once in the paragraph |
6349 | | $excerpt = preg_replace('|\</?wpcontext\>|', '', $para); |
| 6304 | $verified = strpos( $remote_source, str_replace( array( 'http://www.', 'http://', 'https://www.', 'https://' ), '', untrailingslashit( preg_replace( '/#.*/', '', $pagelinkedto ) ) ) ); |
| 6305 | /** |
| 6306 | * Filter the verification to allow for stricter controls. |
| 6307 | * |
| 6308 | * @since 4.6.0 |
| 6309 | * |
| 6310 | * @param boolean $verified Is the provided |
| 6311 | * @param string $remote_source Response source for the page linked from. |
| 6312 | * @param string $pagelinkedto URL of the page linked to. |
| 6313 | * @param string $content_type The content type of the remote source. |
| 6314 | */ |
| 6315 | $verified = apply_filters( 'ping_source_verified', $verified, $remote_source, $pagelinkedto, $content_type ); |
| 6316 | if ( ! $verified ) { // Link to target not found |
| 6317 | return $this->pingback_error( 17, __( 'The source URL does not contain a link to the target URL, and so cannot be used as a source.' ) ); |
| 6318 | } |
6355 | | $marker = '<wpcontext>'.$context[1].'</wpcontext>'; // set up our marker |
6356 | | $excerpt= str_replace($context[0], $marker, $excerpt); // swap out the link for our marker |
6357 | | $excerpt = strip_tags($excerpt, '<wpcontext>'); // strip all tags but our context marker |
6358 | | $excerpt = trim($excerpt); |
6359 | | $preg_marker = preg_quote($marker, '|'); |
6360 | | $excerpt = preg_replace("|.*?\s(.{0,100}$preg_marker.{0,100})\s.*|s", '$1', $excerpt); |
6361 | | $excerpt = strip_tags($excerpt); // YES, again, to remove the marker wrapper |
6362 | | break; |
6363 | | } |
| 6323 | preg_match( '/<title>(.+)<\/title>/i', $remote_source, $matchtitle); |
| 6324 | $title = trim( $matchtitle[1] ); |
| 6325 | // If there is no title use the domain name |
| 6326 | if ( empty( $title ) ) { |
| 6327 | $host = wp_parse_url( $pagelinkedfrom ); |
| 6328 | $title = preg_replace( '/^www\./', '', $host['host'] ); |