/functions.php

  1. <?php 
  2.  
  3. /** 
  4. * EXTENDED DIAGNOSTIC LOGGING - set value below from "0" to "1" to enable dx logging (or vice-versa). 
  5. * Note: If the plugin is already activated, leave this alone and change the setting on the "Advanced" tab. 
  6. * This option is intended only for logging installation and activation problems when the setting is not 
  7. * available. 
  8. *  
  9. * The diagnostic log should be written to a temporary table in your wp database. 
  10. *  
  11. * When this is set to "1", logging will be attempted regardless of the setting. 
  12. */ 
  13. @define( 'GDE_DX_LOGGING', 0 ); 
  14.  
  15. // set up environment 
  16. if ( ! defined( 'ABSPATH' ) ) { exit; } 
  17. @define( 'GDE_PLUGIN_DIR', trailingslashit( plugin_dir_path( __FILE__ ) ) ); 
  18. @define( 'GDE_PLUGIN_URL', trailingslashit( plugin_dir_url( __FILE__ ) ) ); 
  19.  
  20. // help links 
  21. @define( 'GDE_STDOPT_URL', 'https://wordpress.org/plugins/google-document-embedder/' ); 
  22. @define( 'GDE_ENHOPT_URL', 'https://wordpress.org/plugins/google-document-embedder/' ); 
  23. @define( 'GDE_PROOPT_URL', 'https://wordpress.org/plugins/google-document-embedder/' ); 
  24. @define( 'GDE_ADVOPT_URL', 'https://wordpress.org/plugins/google-document-embedder/' ); 
  25. @define( 'GDE_FORUM_URL', 'http://wordpress.org/support/plugin/google-document-embedder' ); 
  26. @define( 'GDE_WP_URL', 'http://wordpress.org/extend/plugins/google-document-embedder/' ); 
  27.  
  28. /** 
  29. * List supported extensions & MIME types 
  30. * 
  31. * @since 2.5.0.1 
  32. * @return array List of all supported extensions and their MIME types 
  33. */ 
  34. function gde_supported_types() { 
  35. global $gdetypes; 
  36.  
  37. if ( is_array( $gdetypes ) ) { 
  38. return $gdetypes; 
  39. } else { 
  40. $no_output = 1; 
  41. include_once( GDE_PLUGIN_DIR . 'libs/lib-exts.php' ); 
  42.  
  43. if ( isset( $types ) ) { 
  44. return $types; 
  45. } else { 
  46. return false; 
  47.  
  48. /** 
  49. * Get profile data 
  50. * 
  51. * @since 2.5.0.1 
  52. * @return array Array of profiles with their data, or a specific profile 
  53. */ 
  54. function gde_get_profiles( $ident = '', $include_id = true, $include_desc = false ) { 
  55. global $wpdb; 
  56. $table = $wpdb->prefix . 'gde_profiles'; 
  57.  
  58. if ( empty( $ident ) ) { 
  59. $where = "WHERE 1 = 1 ORDER BY profile_id ASC"; 
  60. } elseif ( ! is_numeric( $ident ) ) { 
  61. $where = "WHERE profile_name = '$ident'"; 
  62. } else { 
  63. $where = "WHERE profile_id = $ident"; 
  64.  
  65. $profiles = $wpdb->get_results( "SELECT * FROM $table $where", ARRAY_A ); 
  66.  
  67. if ( ! is_array( $profiles ) ) { 
  68. gde_dx_log("Requested profile $ident not found"); 
  69. return false; 
  70. } elseif ( ! empty( $ident ) ) { 
  71. // return specific profile data 
  72. if ( isset( $profiles[0] ) ) { 
  73. $data = unserialize($profiles[0]['profile_data']); 
  74. if ( $include_id ) { 
  75. $data['profile_id'] = $profiles[0]['profile_id']; 
  76. if ( $include_desc ) { 
  77. $data['profile_desc'] = $profiles[0]['profile_desc']; 
  78.  
  79. $profiles = $data; 
  80. } else { 
  81. gde_dx_log("Requested profile $ident doesn't exist"); 
  82. return false; 
  83.  
  84. return $profiles; 
  85.  
  86. /** 
  87. * Test for valid shortcode syntax, other file errors 
  88. * 
  89. * @return string Error message (if any) 
  90. */ 
  91. function gde_validate_file( $file = NULL, $force ) { 
  92.  
  93. // error messages 
  94. $nofile = __('File not specified, check shortcode syntax', 'google-document-embedder'); 
  95. $badlink = __('Requested URL is invalid', 'google-document-embedder'); 
  96. $badtype = __('Unsupported File Type', 'google-document-embedder') . " (%e)"; 
  97. $unktype = __('Unable to determine file type from URL', 'google-document-embedder'); 
  98. $notfound = __('Error retrieving file - if necessary turn off error checking', 'google-document-embedder') . " (%e)"; 
  99.  
  100. if ( ! $file ) { 
  101. return $nofile; 
  102.  
  103. $result = gde_valid_url( $file ); 
  104. if ( $result === false ) { 
  105. // validation skipped due to service failure 
  106. return -1; 
  107. } elseif ( $force == "1" || $force == "yes" ) { 
  108. if ( is_array( $result ) ) { 
  109. return $result; 
  110. } else { 
  111. // couldn't get file size due to service failure 
  112. return -1; 
  113. } elseif ( ! $result ) { 
  114. // can't validate 
  115. return -1; 
  116. } else { 
  117. if ( isset( $result['code'] ) && $result['code'] != 200 ) { 
  118. if ( ! gde_valid_link( $file ) ) { 
  119. return $badlink; 
  120. } else { 
  121. $err = $result['code'] . ":" . $result['message']; 
  122. $notfound = str_replace( "%e", $err, $notfound ); 
  123.  
  124. return $notfound; 
  125. } else { 
  126. if ( ! gde_valid_type( $file ) ) { 
  127. $fn = basename( $file ); 
  128. $fnp = gde_split_filename( $fn ); 
  129. $type = $fnp[1]; 
  130.  
  131. if ( $type == '' ) { 
  132. return $unktype; 
  133. $badtype = str_replace( "%e", $type, $badtype ); 
  134.  
  135. return $badtype; 
  136. } else { 
  137. return $result; 
  138.  
  139. function gde_valid_link( $link ) { 
  140.  
  141. $urlregex = '/^(([\w]+:)?\/\/)(([\d\w]|%[a-fA-f\d]{2, 2})+(:([\d\w]|%[a-fA-f\d]{2, 2})+)?@)?([\d\w][-\d\w]{0, 253}[\d\w]\.)+[\w]{2, 4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2, 2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2, 2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2, 2})*)?$/i'; 
  142.  
  143. if ( preg_match( $urlregex, $link ) ) { 
  144. return true; 
  145. } else { 
  146. return false; 
  147.  
  148. function gde_valid_type( $link ) { 
  149. global $gdetypes; 
  150.  
  151. if ( is_array( $gdetypes ) ) { 
  152. $supported_exts = implode( "|", array_keys( $gdetypes ) ); 
  153.  
  154. if ( preg_match( "/\.($supported_exts)$/i", $link ) ) { 
  155. return true; 
  156. } else { 
  157. return false; 
  158.  
  159. function gde_valid_url( $url, $method = "head", $stop = 0 ) { 
  160.  
  161. if ( $method == "head" ) { 
  162. $result = wp_remote_head( $url ); 
  163. } elseif ( $stop == 0 ) { 
  164. $stop++; 
  165. $result = wp_remote_get( $url ); 
  166. } else { 
  167. gde_dx_log("can't get URL to test; skipping"); 
  168. return false; 
  169.  
  170. if ( is_array( $result ) ) { 
  171. $code = $result['response']['code']; 
  172. if ( ! empty( $code ) && ( $code == "301" || $code == "302" ) ) { 
  173. // HEAD requests don't redirect. Probably a file/directory with spaces in it... 
  174. return gde_valid_url( $url, 'get', $stop ); 
  175. } else { 
  176. // capture file size if determined 
  177. if ( isset( $result['headers']['content-length'] ) ) { 
  178. $result['response']['fsize'] = $result['headers']['content-length']; 
  179. } else { 
  180. $result['response']['fsize'] = ''; 
  181. return $result['response']; 
  182. } elseif ( is_wp_error( $result ) ) { 
  183. // unable to get head 
  184. $error = $result->get_error_message(); 
  185. gde_dx_log("bypassing URL check; cant validate URL $url: $error"); 
  186. return false; 
  187. } else { 
  188. gde_dx_log("cant determine URL validity; skipping"); 
  189. return false; 
  190.  
  191. function gde_split_filename( $filename ) { 
  192. $pos = strrpos( $filename, '.' ); 
  193. if ( $pos === false ) { 
  194. return array( $filename, '' ); // no extension (dot is not found in the filename) 
  195. } else { 
  196. $basename = substr( $filename, 0, $pos ); 
  197. $ext = substr( $filename, $pos + 1 ); 
  198. return array( $basename, $ext ); 
  199.  
  200. function gde_format_bytes( $bytes, $precision = 2 ) { 
  201. if ( ! is_numeric( $bytes ) || $bytes < 1 ) { 
  202. return __('Unknown', 'google-document-embedder'); 
  203. } else { 
  204. $units = array( 'B', 'KB', __('MB', 'google-document-embedder'), 'GB', 'TB' ); 
  205.  
  206. $bytes = max( $bytes, 0 ); 
  207. $pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) ); 
  208. $pow = min( $pow, count( $units ) - 1 ); 
  209.  
  210. $bytes /= pow( 1024, $pow ); 
  211.  
  212. if ( $units[$pow] == "KB" ) { 
  213. // less precision for small file sizes 
  214. return round( $bytes ) . "KB"; 
  215. } else { 
  216. return round( $bytes, $precision ) . $units[$pow]; 
  217.  
  218. /** 
  219. * Sanitize dimensions (width, height) 
  220. * 
  221. * @since 2.5.0.1 
  222. * @return string Sanitized dimensions, or false if value is invalid 
  223. * @note Replaces old gde_sanitizeOpts function 
  224. */ 
  225. function gde_sanitize_dims( $dim ) { 
  226. // remove any spacing junk 
  227. $dim = trim( str_replace( " ", "", $dim ) ); 
  228.  
  229. if ( ! strstr( $dim, '%' ) ) { 
  230. $type = "px"; 
  231. $dim = preg_replace( "/[^0-9]*/", '', $dim ); 
  232. } else { 
  233. $type = "%"; 
  234. $dim = preg_replace( "/[^0-9]*/", '', $dim ); 
  235. if ( (int) $dim > 100 ) { 
  236. $dim = "100"; 
  237.  
  238. if ( $dim ) { 
  239. return $dim.$type; 
  240. } else { 
  241. return false; 
  242.  
  243. /** 
  244. * Shorten ("mask") the URL to the embedded file 
  245. * 
  246. * @since 2.5.0.1 
  247. * @return string Short url response from API call, or false on error 
  248. */ 
  249. function gde_get_short_url( $u ) { 
  250. return $u; //bypass this function - breaks in current viewer 
  251.  
  252. $u = urlencode( $u ); 
  253. $service[] = "http://tinyurl.com/api-create.php?url=" . $u; 
  254. $service[] = "http://is.gd/create.php?format=simple&url=" . $u; 
  255.  
  256. foreach ( $service as $url ) { 
  257. $passed = false; 
  258. $response = wp_remote_get( $url ); 
  259. if ( is_wp_error( $response ) || empty ( $response['body'] ) ) { 
  260. continue; 
  261. } else { 
  262. // check for rate limit exceeded or other error response 
  263. if ( ! gde_valid_link( $response['body'] ) ) { 
  264. continue; 
  265. } else { 
  266. $passed = true; 
  267. break; 
  268.  
  269. if ( $passed ) { 
  270. return $response['body']; 
  271. } else { 
  272. // can't shorten - return original URL 
  273. gde_dx_log("Shorten URL failed: " . urldecode( $u )); 
  274. return urldecode( $u ); 
  275.  
  276. /** 
  277. * Request secure URL to document 
  278. * 
  279. * @since 2.5.0.1 
  280. * @return string Secure URL, or false on error 
  281. */ 
  282. function gde_get_secure_url( $u ) { 
  283. return $u; //bypass this function - breaks in current viewer 
  284.  
  285. require_once( GDE_PLUGIN_DIR . 'libs/lib-secure.php' ); 
  286.  
  287. if ( ! $url = gde_make_secure_url( $u ) ) { 
  288. return false; 
  289. } else { 
  290. return $url; 
  291.  
  292. /** 
  293. * Check if settings allow a file to be privatized (downloads blocked) 
  294. * 
  295. * @since 2.5.0.2 
  296. * @return bool Whether or not the file can be blocked from download 
  297. */ 
  298. function gde_is_blockable( $profile ) { 
  299. if ( $profile['viewer'] == "standard" || $profile['link_show'] !== "none" ) { 
  300. return false; 
  301. } elseif ( ! strstr( $profile['tb_flags'], "n" ) && $profile['tb_fullscr'] == "default" ) { 
  302. return false; 
  303. } else { 
  304. return true; 
  305.  
  306. /** 
  307. * Google Analytics Integration 
  308. * 
  309. * @since 2.5.0.1 
  310. * @return string GA tracking event tag, or blank if disabled 
  311. */ 
  312. function gde_ga_event( $file ) { 
  313. global $gdeoptions; 
  314.  
  315. if ( $gdeoptions['ga_enable'] == "no" ) { 
  316. return ''; 
  317. } elseif ( $gdeoptions['ga_enable'] == "compat" ) { 
  318. $fnp = gde_split_filename( basename( $file ) ); 
  319. $category = "'Download'"; // intentionally not translated (it wasn't a translated string in < 2.5) 
  320. $action = "'" . strtoupper( $fnp[1] ) . "'"; 
  321. $label = "this.href"; 
  322. } else { 
  323. $category = "'" . addslashes( $gdeoptions['ga_category'] ) . "'"; 
  324. $action = "'" . __('Download', 'google-document-embedder') . "'"; 
  325. if ( $gdeoptions['ga_label'] == "url" ) { 
  326. $label = "this.href"; 
  327. } else { 
  328. $label = "'" . basename( $file ) . "'"; 
  329.  
  330. $str = "_gaq.push(['_trackEvent', ".$category.", ".$action.", ".$label."]);"; 
  331. return " onClick=\"" . $str . "\""; 
  332.  
  333. /** 
  334. * Get plugin data 
  335. * 
  336. * @since 2.4.0.1 
  337. * @return array Array of plugin data parsed from main plugin file 
  338. */ 
  339. function gde_get_plugin_data() { 
  340. $mainfile = 'gviewer.php'; 
  341. $slug = 'google-document-embedder'; 
  342.  
  343. if ( ! function_exists( 'get_plugin_data' ) ) { 
  344. require_once( ABSPATH . '/wp-admin/includes/plugin.php' ); 
  345. $plugin_data = get_plugin_data( GDE_PLUGIN_DIR . $mainfile ); 
  346.  
  347. // add custom data (lowercase to avoid any future conflicts) 
  348. $plugin_data['slug'] = $slug; 
  349. $plugin_data['mainfile'] = $mainfile; 
  350. $plugin_data['basename'] = $plugin_data['slug'] . "/" . $mainfile; 
  351.  
  352. return $plugin_data; 
  353.  
  354. /** 
  355. * GDE Extended Logging 
  356. * 
  357. * @since 2.5.0.1 
  358. * @return bool Whether or not log write was successful 
  359. */ 
  360. function gde_dx_log( $text ) { 
  361. global $gdeoptions, $wpdb; 
  362.  
  363. if ( GDE_DX_LOGGING > 0 || ( isset( $gdeoptions['error_log'] ) && $gdeoptions['error_log'] == "yes" ) ) { 
  364. // filter to trap any "unexpected output" to log 
  365. add_action( 'activated_plugin', 'gde_save_error' ); 
  366.  
  367. $table = $wpdb->base_prefix . 'gde_dx_log'; 
  368.  
  369. // create/update table if necessary, then write to log 
  370. if ( gde_dx_log_create() ) { 
  371. // write to log 
  372. $blogid = get_current_blog_id(); 
  373. $text = date( "d-m-Y, H:i:s" ) . " - $text"; 
  374.  
  375. if ( ! $wpdb->insert( 
  376. $table,  
  377. array( 
  378. 'blogid' => $blogid,  
  379. 'data' => $text 
  380. ),  
  381. array( 
  382. '%d', '%s' 
  383. ) ) { 
  384. // couldn't write to db 
  385. return false; 
  386. } else { 
  387. return true; 
  388. } else { 
  389. // can't create db table 
  390. return false; 
  391. } else { 
  392. // logging disabled 
  393. return false; 
  394.  
  395. /** 
  396. * Create/update database table to store dx log 
  397. * 
  398. * @since 2.5.2.1 
  399. * @return bool Whether or not table creation/update was successful 
  400. */ 
  401. function gde_dx_log_create() { 
  402. global $wpdb, $gde_db_ver; 
  403.  
  404. $table = $wpdb->base_prefix . 'gde_dx_log'; 
  405. $db_ver_installed = get_site_option( 'gde_db_version', 0 ); 
  406.  
  407. $sql = "CREATE TABLE " . $table . " ( 
  408. id mediumint(9) UNSIGNED NOT NULL AUTO_INCREMENT,  
  409. blogid smallint(5) UNSIGNED NOT NULL,  
  410. data longtext NOT NULL,  
  411. UNIQUE KEY (id) 
  412. ) ENGINE=MyISAM DEFAULT CHARSET=utf8; "; 
  413.  
  414. if ( version_compare( $gde_db_ver, $db_ver_installed, ">" ) ) { 
  415. // upgrade table if needed 
  416. require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); 
  417. dbDelta( $sql ); 
  418. } elseif ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) == $table ) { 
  419. // table's OK 
  420. return true; 
  421. } else { 
  422. // table doesn't exist, try to create 
  423. require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); 
  424. dbDelta( $sql ); 
  425.  
  426. if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) == $table ) { 
  427. // table's OK 
  428. return true; 
  429. } else { 
  430. // can't create 
  431. return false; 
  432.  
  433. /** 
  434. * Capture activation errors ("unexpected output") to dx log 
  435. * 
  436. * @since 2.5.0.1 
  437. * @return void 
  438. * @note Writes any activation errors to log, when enabled 
  439. */ 
  440. function gde_save_error() { 
  441. $buffer = ob_get_contents(); 
  442. if ( ! empty( $buffer ) ) { 
  443. gde_dx_log('Activation Msg: '. $buffer ); 
  444.  
  445. function gde_show_error( $status ) { 
  446. global $gdeoptions; 
  447.  
  448. $error = "GDE " . __('Error', 'google-document-embedder') . ": " . $status; 
  449. if ( $gdeoptions['error_display'] == "no" ) { 
  450. $code = "\n<!-- $error -->\n"; 
  451. } else { 
  452. $code = "\n".'<div class="gde-error">' . $error . "</div>\n"; 
  453.  
  454. return $code; 
  455.  
  456. /** 
  457. * Check health of database tables 
  458. * 
  459. * @since 2.5.0.3 
  460. * @return mixed 
  461. * @note Verbose text used in debug information 
  462. */ 
  463. function gde_debug_tables( $table = array('gde_profiles', 'gde_secure'), $verbose = false ) { 
  464. global $wpdb; 
  465.  
  466. if ( is_array( $table ) ) { 
  467. $ok = true; 
  468. foreach ( $table as $t ) { 
  469. $t = $wpdb->prefix . $t; 
  470. if ( $wpdb->get_var( "SHOW TABLES LIKE '$t'" ) == $t ) { 
  471. // table good 
  472. } else { 
  473. $ok = false; 
  474. gde_dx_log($t . " table missing"); 
  475. break; 
  476. } else { 
  477. $ok = true; 
  478. $table = $wpdb->prefix . $table; 
  479. if ( $wpdb->get_var( "SHOW TABLES LIKE '$table'" ) == $table ) { 
  480. $s = "OK "; 
  481. $c = $wpdb->get_var( "SELECT COUNT(*) FROM $table WHERE 1=1" ); 
  482. $s = $s . "($c items)"; 
  483. } else { 
  484. $s = "NOT OK ($table missing)"; 
  485. $ok = false; 
  486.  
  487. if ( ! $verbose ) { 
  488. return $ok; 
  489. } else { 
  490. return $s; 
  491.  
  492. ?> 
.