Last active
June 21, 2017 17:54
-
-
Save staylor/25fd57ec11d4f8942d8b0be62321f8a6 to your computer and use it in GitHub Desktop.
WP CLI commands to regenerate all of the oembed data for your posts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace GraphQL; | |
class Commands extends \WP_CLI_Command | |
{ | |
private $responses = []; | |
// @codingStandardsIgnoreLine | |
private function fetchURL( $url, $attr ) { | |
global $wp_embed; | |
$wp_embed->usecache = false; | |
add_filter( 'embed_oembed_html', [ $this, '__embed_oembed_html' ], 10, 2 ); | |
add_filter( 'oembed_dataparse', [ $this, '__oembed_dataparse' ], 10, 3 ); | |
$wp_embed->shortcode( $attr, $url ); | |
} | |
// @codingStandardsIgnoreLine | |
private function parseIDs( $ids ) { | |
global $wp_embed; | |
$oembed = _wp_oembed_get_object(); | |
foreach ($ids as $id) { | |
$post = get_post( $id ); | |
if ($post->post_status !== 'publish') { | |
continue; | |
} | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%c' . sprintf( 'Finding URLs in: %d', $id ) . '%n' ) | |
); | |
$matched = []; | |
// PREG_SET_ORDER | |
preg_match_all( | |
'|^(\s*)(https?://[^\s<>"]+)(\s*)$|im', | |
$post->post_content, | |
$matches1, | |
PREG_SET_ORDER | |
); | |
if (!empty( $matches1 )) { | |
foreach ($matches1 as $m) { | |
$matched[] = $m[2]; | |
} | |
} | |
preg_match_all( | |
'|(<p(?: [^>]*)?>\s*)(https?://[^\s<>"]+)(\s*<\/p>)|i', | |
$post->post_content, | |
$matches2, | |
PREG_SET_ORDER | |
); | |
if (!empty( $matches2 )) { | |
foreach ($matches2 as $m) { | |
$matched[] = $m[2]; | |
} | |
} | |
preg_match_all( | |
'/' . get_shortcode_regex( [ 'embed' ] ) . '/s', | |
$post->post_content, | |
$matches3, | |
PREG_SET_ORDER | |
); | |
if (!empty( $matches3 )) { | |
foreach ($matches3 as $m) { | |
$matched[] = $m[5]; | |
} | |
} | |
if (! empty( $matched )) { | |
foreach (array_unique( $matched ) as $match) { | |
\WP_CLI::line( '- ' . $match ); | |
$data = $oembed->get_data( $match ); | |
if (! empty( $data )) { | |
$this->responses[ $match ] = $data; | |
$GLOBALS['post'] = $post; | |
$this->fetchURL( $match, [ 'width' => 450, 'height' => 0 ] ); | |
$this->fetchURL( $match, [ 'width' => 740, 'height' => 0 ] ); | |
$GLOBALS['post'] = null; | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%RJSON: %n' ) . json_encode( $data ) | |
); | |
} else { | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%YNo response - (could be) setting to draft...%n' ) | |
); | |
continue; | |
// \WP_CLI::error( 'Quit due to error.' ); | |
// wp_update_post( [ 'ID' => $id, 'post_status' => 'draft' ] ); | |
// \WP_CLI::line( | |
// \WP_CLI::colorize( '%Y' . $id . ' set to draft.%n' ) | |
// ); | |
} | |
} | |
} else { | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%3No matches: deleting oembed caches... %n' ) | |
); | |
$wp_embed->delete_oembed_caches( $id ); | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%R' . sprintf( 'Removed ombed data for: %d. ', $id ) . '%n' ) | |
); | |
} | |
} | |
} | |
// @codingStandardsIgnoreLine | |
private function __getFormattedHTML( $data ) { | |
$escaped = []; | |
foreach ($data as $key => $value) { | |
$escaped[ $key ] = htmlentities( $value ); | |
} | |
return sprintf( | |
'<figure class="embed"><img src="%s" alt="%s" /><figcaption>%s</figcaption>' . | |
'<script type="application/json">%s</script></figure>', | |
str_replace( 'hqdefault', 'maxresdefault', $data['thumbnail_url'] ), | |
esc_attr( $data['title'] ), | |
$data['title'], | |
json_encode( $escaped ) | |
); | |
} | |
// @codingStandardsIgnoreLine | |
public function __embed_oembed_html( $html, $url ) { | |
remove_filter( 'embed_oembed_html', [ $this, '__embed_oembed_html' ] ); | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%REmbed HTML: %n' ) . $html | |
); | |
$data = (array) $this->responses[ $url ]; | |
$formatted = $this->__getFormattedHTML( $data ); | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%RSpecial HTML: %n' ) . $formatted | |
); | |
return $formatted; | |
} | |
// @codingStandardsIgnoreLine | |
public function __oembed_dataparse( $html, $response, $url ) { | |
remove_filter( 'embed_oembed_html', [ $this, '__oembed_dataparse' ] ); | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%REmbed HTML: %n' ) . $html | |
); | |
$data = (array) $response; | |
$formatted = $this->__getFormattedHTML( $data ); | |
\WP_CLI::line( | |
\WP_CLI::colorize( '%RSpecial HTML: %n' ) . $formatted | |
); | |
return $formatted; | |
} | |
// @codingStandardsIgnoreLine | |
private function regenerate() { | |
global $wpdb; | |
\WP_CLI::line( 'Regenerating oembed data...' ); | |
$sql = $wpdb->prepare( | |
"SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key LIKE %s", | |
esc_sql( '_oembed_%' ) | |
); | |
$ids = $wpdb->get_col( $sql ); | |
if (empty( $ids )) { | |
$sql = $wpdb->prepare( | |
"SELECT ID FROM $wpdb->posts WHERE post_content LIKE %s", | |
esc_sql( '%http%' ) | |
); | |
$ids = $wpdb->get_col( $sql ); | |
} | |
$this->parseIDs( $ids ); | |
\WP_CLI::success( 'All done!' ); | |
} | |
// @codingStandardsIgnoreLine | |
private function unknown() { | |
global $wpdb; | |
\WP_CLI::line( 'Regenerating unknown oembed data...' ); | |
$sql = $wpdb->prepare( | |
"SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_value = '{{unknown}}' AND meta_key LIKE %s", | |
esc_sql( '_oembed_%' ) | |
); | |
$ids = $wpdb->get_col( $sql ); | |
$this->parseIDs( $ids ); | |
\WP_CLI::success( 'All done!' ); | |
} | |
// @codingStandardsIgnoreLine | |
public function oembed( $args ) { | |
if ($args && 'regenerate' === $args[0]) { | |
$this->regenerate(); | |
} elseif ($args && 'unknown' === $args[0]) { | |
$this->unknown(); | |
} | |
} | |
} | |
\WP_CLI::add_command( 'graphql', Commands::class ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@staylor What'd you think about the experience of writing a command? Anything we can improve?
Btw, regenerating oEmbed data seems like it might be a generally useful command. Feel free to throw it into https://github.com/wp-cli/ideas/issues