0

I'm building a basic video management plugin, with an embed feature that will have URLs like: mysite.com/wp-content/plugins/embed-video.php?video=[POST ID]

I plan on using the [POST ID] url parameter to query the database and retrieve the relevant information for the embeds (stored in custom fields). However, because the file is referenced directly WP isn't being loaded.

Could anyone tell me what the best (and correct) way to load WordPress (and its DB) directly from this file would be?

I don't even know where to start with this, so any help or insight would be greatly appreciated.

  • 1
    Why is "the file referenced directly"? Why does get loaded outside WordPress context? – kaiser Mar 7 '14 at 9:09
  • The file is referenced directly because it will be embedded in other websites. The content of the file is just an iframe video player and some php to grab things like video title, url, etc.. from the DB. The only issue I have is (correctly) connecting to the DB and bringing it into the context of WP so I can execute those queries. I would be open to a learning a method that loads the file within the context of WordPress from the start if you know of one. – DLR Mar 7 '14 at 9:18
  • I've just found one way of doing this and it's surprisingly simple - Using wp-load.php to load up WordPress: require( dirname(__FILE__) . '/wp-load.php' ); This "Works" but i'd still be interested in hearing from anyone with a bit more experience about whether this is the best way of doing this. – DLR Mar 7 '14 at 9:30
1

If you plan to share/sell your plugin I strongly suggest don't load your plugin directly.

That because to load WordPress you need to load the bootstrap file, that is /wp-load.php so, you should put in your embed-video.php something like:

require '/wordpress/path/wp-load.php';

Do you notice the problem here? The /wordpress/path/ part is different for user to user, and, really, even if you use something like

require dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/wp-load.php';

It's not enough, because wp_content folder and/or plugins folder can be moved from standard position, so you can never be sure where they are.

If you are writing a plugin only for yourself, you can do it, because you know where your files are, just be sure to use a flexible manner to define the path, because even youcan need to move your folders in future.

If you are writing plugin to share/sell you'll need to use an alternative.

One is to send requests to admin-ajax.php and use the ajax api. I know that you are thinking that your request is not ajax, but that's not a problem: any ajax request is just an http request, so it will work even if you send a "normal" GET request.

Example code:

add_action( 'plugins_loaded', function() {
  /*
  once we use ajax api we can check if DOING_AJAX is set
  even if we are not really doing ajax
  that will reduce the times we perform code, speeding up you others requests
  */
  if ( ! defined('DOING_AJAX') ) return;

  /*
  check if the url contain the GET argument 'action' set to 'embedvideo'
  and contain the video id in the argument 'video'
  if not do nothing
  */
  $action = filter_input( INPUT_GET, 'action', FILTER_SANITIZE_STRING );
  $embed = (int) filter_input( INPUT_GET, 'video', FILTER_SANITIZE_NUMBER_INT );
  if ( $action === 'embed_video' || ! $embed > 0 ) return; 

  /* add the ajax action for logged and not logged users */
  add_action( "wp_ajax_{$action}", 'video_request'  );
  add_action( "wp_ajax_nopriv_{$action}", 'video_request'  );
});

Previous code add the action only when needed, speeding up all others requests, because 'plugins_loaded' hooks is fired for every request.

Now add the action function, where you'll put the logic:

function video_request() {
   /* 
   check if the url contain a video id in the GET argument 'video' if not do nothing
   */
   $video = (int) filter_input( INPUT_GET, 'video', FILTER_VALIDATE_NUMBER_INT );
   if ( ! $video > 0 ) return;

   /* your post ID is in $video variable and you have WordPress available */
   $post = get_post( $video );

   // do stuff

   /*
   must exit(), because even not sended via ajax, we use ajax api that require to exit
   */
   exit(); 
}

Adding previous code to your plugin, you can use a function to easily generate the right urls:

function get_video_embed_url( $videoid = NULL ) {
  if ( is_numeric( $videoid ) && (int) $postid > 0 ) {
    $args = array( 'action' => 'embed_video', 'video' => $postid );
    return add_query_arg( $args, admin_url( 'admin_ajax.php' );
  }
  return '#';
}

function video_embed_url( $videoid = NULL ) {
  echo get_video_embed_url( $videoid );
}

After that, wherever you need the url video_embed_url( $id ) will echo the url (e.g. in html markup) get_video_embed_url( $id ) will return the url to use in code.

The urls will be something like

mysite.com/wp-admin/admin_ajax.php?action=embed_video&video={$videoid}

This code can seems more than you need, but:

  • it uses best practice, and allow you to share/sell your plugin
  • it's developed using ajax api, and even if now you aren't using ajax, in future you can mind to use it, and in that case you have to do nothing: your plugin is ready

A trick: use it with caution, or not use it at all

As said, when write code only for yourself, you can think to directly load your plugin file. And I also said that is better use a flexible way to defined paths. This is an example of how you can flexible define them: not define at all, but pass in the url:

/* in main plugin file, that I suppose to be in the same folder of embed-video.php */
function my_embed_url( $id ) {
  if ( is_numeric( $id ) && $id > 0 ) {
    $base = plugins_url( '/embed-video.php', __FILE__ );
    $path = urlencode( base64_encode( trailingslashit( ABSTPATH ) . 'wp-load.php' ) );
    return add_aquery_arg( array( 'path' => $path, 'video' => $id ), $base );
  }
}

Previous function will return something like mysite.com/wp-content/plugins/myplugin/embed-video.php?path=L3Zhci93d3cvd29yZHByZXNzL3dwLWxvYWQucGhw&video=123 use this function to output the embed video (if you need to use url in post content use a shortcode).

Doing so, in first lines of embed-video.php you can:

$raw = filter_input( INPUT_GET, 'path', FILTER_SANITIZE_STRING );
$videoid = (int) filter_input( INPUT_GET, 'video', FILTER_SANITIZE_NUMBER_INT );
if ( empty($raw) || empty($videoid) || ! $videoid > 0 ) exit();
$path =  urldecode( base64_decode( $raw ) );
if ( ! file_exists( $path ) ) exit();

define( 'SHORTINIT', 1 ); // this allow you to load only minimun WP environment
require_once $path;

/* WordPress is available */
$post = get_post( $videoid );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.