Skip to content

Instantly share code, notes, and snippets.

@benbalter
Last active August 27, 2017 07:41
Show Gist options
  • Save benbalter/9c577f8719fc36bd50b04b1c980f11ca to your computer and use it in GitHub Desktop.
Save benbalter/9c577f8719fc36bd50b04b1c980f11ca to your computer and use it in GitHub Desktop.
<?php if ( $latest_version && apply_filters( 'document_revisions_enable_webdav', true ) ) { ?>
<object id="winFirefoxPlugin" type="application/x-sharepoint" width="0" height="0" style="visibility: hidden;"></object>
<a id="edit-desktop-button" href="<?php echo esc_url( get_permalink( $post->ID ) ); ?>" class="button" title="<?php esc_attr_e( 'Edit on Desktop', 'wp-document-revisions' ); ?>">
<?php esc_html_e( 'Edit on Desktop', 'wp-document-revisions' ); ?>
</a>
<?php } // End if(). %>
'desktopEditRuntimeError' => '<div id="message" class="error" style="display:none"><p>' . __( 'There was an error launching your Office software. You can try to <a href="#" onClick="location.reload();">reload this page</a> to see if this fixes the issue, or use the <strong>Upload</strong> option.', 'wp-document-revisions' ) . '</p></div>',
'desktopEditNotSupportedError' => '<div id="message" class="error" style="display:none"><p>' . __( 'Sorry, desktop editing not supported by this browser or your current Office software. Please use the <strong>Upload</strong> option.', 'wp-document-revisions' ) . '</p></div>',
@$('#edit-desktop-button').click @editDocument
# Setup our webdav editing
@fNewDoc = false
@EditDocumentButton = null
try
@EditDocumentButton = new ActiveXObject('SharePoint.OpenDocuments.3')
if @EditDocumentButton != null
@fNewDoc = true
catch buttonError
#console.log(buttonError)
#callback to edit document via webdav
editDocument: (e) =>
e.preventDefault()
file = @$(e.target).attr 'href'
if @fNewDoc
if !@EditDocumentButton.EditDocument(file)
if typeof convertEntities == 'function' #3.2 requires convertEntities, 3.3 doesn't
wp_document_revisions.desktopEditRuntimeError = convertEntities wp_document_revisions.desktopEditRuntimeError
@window.jQuery('#lock_override').before( wp_document_revisions.desktopEditRuntimeError ).prev().fadeIn()
return @window.jQuery("#edit-desktop-button").remove()
else
try
ffPlugin = document.getElementById("winFirefoxPlugin")
ffPlugin.EditDocument(file, null)
catch error
if typeof convertEntities == 'function' #3.2 requires convertEntities, 3.3 doesn't
wp_document_revisions.desktopEditNotSupportedError = convertEntities wp_document_revisions.desktopEditNotSupportedError
@window.jQuery('#lock_override').before( wp_document_revisions.desktopEditNotSupportedError ).prev().fadeIn()
return @window.jQuery("#edit-desktop-button").remove()
if typeof convertEntities == 'function' #3.2 requires convertEntities, 3.3 doesn't
wp_document_revisions.postDesktopNotice = convertEntities wp_document_revisions.postDesktopNotice
class WP_Document_Revisions_WebDAV extends HTTP_WebDAV_Server {
function __construct {
add_action( 'after_setup_theme', array( &$this, 'auth_webdav_requests' ) );
add_action( 'template_redirect', array( &$this, 'check_webdav_requests' ) );
}
/**
*
* Support some basic WebDav requests
*
* @param Object $post the Post Object
*/
function auth_webdav_requests( $post ) {
$request_method = $_SERVER['REQUEST_METHOD'];
// OPTIONS must always be unauthenticated
if ( 'OPTIONS' === $request_method ) {
nocache_headers();
parent::http_OPTIONS();
header( 'Allow: OPTIONS GET POST PUT HEAD LOCK' );
header( 'DAV: 1,2' );
status_header( 200 );
die();
}
$webdav_methods = array( 'LOCK', 'PUT' );
$private_checked_methods = array( 'GET', 'HEAD' );
if ( in_array( $request_method, $webdav_methods, true ) || ( in_array( $request_method, $private_checked_methods, true ) && $this->is_webdav_client() ) ) {
$this->basic_auth();
}
}
/**
* Is the current reqeust being made by a webDAV client?
*
* @return Bool true if a webdav client, otherwise false
*/
function is_webdav_client() {
if ( ! isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
return false;
}
$client = $_SERVER['HTTP_USER_AGENT'];
if ( strpos( $client, 'Office' ) !== false ) {
return true;
}
if ( strpos( $client, 'DAV' ) !== false ) {
return true;
}
if ( strpos( $client, 'cadaver' ) !== false ) {
return true;
}
return false;
}
/**
* Check for WebDav request types and handle them
*/
function check_webdav_requests() {
global $post;
if ( $post ) {
$request_method = $_SERVER['REQUEST_METHOD'];
switch ( $request_method ) {
case 'LOCK':
if ( current_user_can( 'edit_post', $post->ID ) ) {
$this->do_LOCK();
} else {
nocache_headers();
status_header( 403 );
die();
}
break;
case 'PUT':
if ( current_user_can( 'edit_post', $post->ID ) ) {
$this->do_PUT();
} else {
nocache_headers();
status_header( 403 );
die();
}
break;
}
}
}
/**
* Do basic authentication
*/
function basic_auth() {
nocache_headers();
if ( is_user_logged_in() ) {
return;
}
$usr = isset( $_SERVER['PHP_AUTH_USER'] ) ? $_SERVER['PHP_AUTH_USER'] : '';
$pwd = isset( $_SERVER['PHP_AUTH_PW'] ) ? $_SERVER['PHP_AUTH_PW'] : '';
if ( empty( $usr ) && empty( $pwd ) && isset( $_SERVER['HTTP_AUTHORIZATION'] ) && $_SERVER['HTTP_AUTHORIZATION'] ) {
list($type, $auth) = explode( ' ', $_SERVER['HTTP_AUTHORIZATION'] );
if ( strtolower( $type ) === 'basic' ) {
// @codingStandardsIgnoreLine WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
list($usr, $pwd) = explode( ':', base64_decode( $auth ) );
}
}
$creds = array();
$creds['user_login'] = $usr;
$creds['user_password'] = $pwd;
$creds['remember'] = false;
$login = wp_signon( $creds, false );
if ( ! is_wp_error( $login ) ) {
$current_user = wp_set_current_user( $login );
return;
}
header( 'WWW-Authenticate: Basic realm="Please Enter Your Password"' );
status_header( 401 );
echo 'Authorization Required';
die();
}
/**
* Check for lock on document
*
* @param Array $options lock options
* @return Bool true
*/
function LOCK( &$options ) {
$options['timeout'] = time() + 300; // 5min. hardcoded
$options['owner'] = '';
$options['scope'] = 'exclusive';
$options['type'] = 'write';
return true;
}
/**
* Lock a file opened via webDAV
*/
function do_LOCK() {
global $post;
if ( $post ) {
$current_user = wp_get_current_user();
include_once 'wp-admin/includes/post.php';
$current_owner = wp_check_post_lock( $post->ID );
if ( $current_owner && $current_owner !== $current_user->ID ) {
nocache_headers();
status_header( 423 );
die();
}
nocache_headers();
parent::http_LOCK();
die();
} else {
nocache_headers();
status_header( 404 );
die();
}
}
/**
* Handle a webDAV PUT request
*/
function do_PUT() {
global $post;
if ( $post ) {
$file = $this->_parsePutFile();
$dir = $this->document_upload_dir();
$wp_filetype = wp_check_filetype( basename( $file, null ) );
$file_array = apply_filters( 'wp_handle_upload_prefilter', array(
'name' => basename( $file ),
'tmp_name' => $file,
'type' => $wp_filetype['type'],
'size' => 1,
)
);
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file ) ),
'post_content' => '',
'post_status' => 'inherit',
);
$newfilepath = $dir . '/' . $file_array['name'];
copy( $file, $newfilepath );
unlink( $file );
$attach_id = wp_insert_attachment( $attachment, $newfilepath, $post->ID );
if ( ! is_wp_error( $attach_id ) ) {
$post_array = array(
'ID' => $post->ID,
'post_content' => $attach_id,
'post_excerpt' => __( 'Revised by Desktop Edit', 'wp-document-revisions' ),
);
$result = wp_update_post( $post_array );
wp_cache_flush();
if ( ! is_wp_error( $result ) ) {
nocache_headers();
status_header( 204 );
die();
} else {
nocache_headers();
status_header( 500 );
die();
}
}
} else {
nocache_headers();
status_header( 404 );
die();
}// End if().
}
/**
* Write PUT data to disk
*
* @return the path to the temporary file
*/
private function _parsePutFile() {
/* PUT data comes in on the stdin stream */
//@codingStandardsIgnoreLine WordPress.WP.WordPress.WP.AlternativeFunctions.file_system_read_fopen
$putdata = fopen( 'php://input', 'r' );
$raw_data = '';
/*
Read the data 1 KB at a time
and write to the file
*/
//@codingStandardsIgnoreLine WordPress.WP.WordPress.WP.AlternativeFunctions.file_system_read_fread
while ( $chunk = fread( $putdata, 1024 ) ) { $raw_data .= $chunk;
}
/*
Close the streams */
//@codingStandardsIgnoreLine WordPress.WP.WordPress.WP.AlternativeFunctions.file_system_read_fclose
fclose( $putdata );
// get tmp name
$path_only = wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
$filename_parts = pathinfo( $path_only );
$file = tempnam( ini_get( 'upload_tmp_dir' ), $filename_parts['filename'] ) . '.' . $filename_parts['extension'];
//@codingStandardsIgnoreLine WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
file_put_contents( $file, $raw_data );
// @codingStandardsIgnoreEnd WordPress.WP.WordPress.WP.AlternativeFunctions.file_system_read_fopen
// @codingStandardsIgnoreEnd WordPress.WP.WordPress.WP.AlternativeFunctions.file_system_read_fread
// @codingStandardsIgnoreEnd WordPress.WP.WordPress.WP.AlternativeFunctions.file_system_read_fclose
return $file;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment