urlyar.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  1. <?php
  2. /*
  3. Plugin Name: URLYar
  4. Plugin URI: https://salamzadeh.net/plugins/urlyar
  5. Description: This plugin provides integration of URL Shorteners (e.g. urlyar.ir, trew.ir, fsda.ir, saqw.ir and what you want).
  6. Author: Sasan Salamzadeh
  7. Author URI: http://www.salamzadeh.net
  8. Text Domain: url-shortener
  9. Version: 1.1.0
  10. */
  11. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  12. define('URLYAR_URL_SHORTENER_VERSION', '1.1.0');
  13. define('URLYAR_URL_SHORTENER_STATUS', 'stable');
  14. /*
  15. *****************************************
  16. *
  17. * Dependencies
  18. *
  19. *****************************************
  20. */
  21. if (!class_exists('ss_options')) :
  22. include(dirname(__FILE__) . '/include/class.ss_options.php');
  23. endif;
  24. if (!class_exists('ss_shortener')) :
  25. include(dirname(__FILE__) . '/include/class.ss_shortener.php');
  26. endif;
  27. /**
  28. * Load plugin textdomain.
  29. *
  30. * @since 1.0.0
  31. */
  32. function urlyar_load_textdomain() {
  33. load_plugin_textdomain( 'url-shortener', null, basename( dirname( __FILE__ ) ) . '/languages' );
  34. }
  35. add_action( 'init', 'urlyar_load_textdomain' );
  36. /*
  37. *****************************************
  38. *
  39. * Main Class Declaration
  40. *
  41. *****************************************
  42. */
  43. if (!class_exists('URLYAR_URL_Shortener')) :
  44. class URLYAR_URL_Shortener
  45. {
  46. /*
  47. *****************************************
  48. *
  49. * Class Variables
  50. *
  51. *****************************************
  52. */
  53. private $plugin_version,
  54. $plugin_status,
  55. $plugin_option, //(global) plugin options
  56. $plugin_url,
  57. $plugin_page, //options page
  58. $shortener, //(global) shared shortener assignment
  59. $shortener_modules; //available modules for shortener
  60. /*
  61. *****************************************
  62. *
  63. * Constructors
  64. *
  65. *****************************************
  66. */
  67. //php 5.3.3
  68. function __construct($version = '0.0', $status = 'dev')
  69. {
  70. $this->URLYAR_URL_Shortener($version, $status);
  71. }
  72. //backward compatibility
  73. function URLYAR_URL_Shortener($version = '0.0', $status = 'dev')
  74. {
  75. $this->plugin_version = $version;
  76. $this->plugin_status = $status;
  77. $this->plugin_option = new ss_options('urlyar_urlfx', $this->plugin_version, $this->plugin_status);
  78. $this->shortener = new ss_shortener($this->plugin_status);
  79. $this->shortener_modules = $this->shortener->get_modules();
  80. }
  81. /*
  82. *****************************************
  83. *
  84. * Plugin Activation Calls
  85. *
  86. *****************************************
  87. */
  88. //hooks and loaders
  89. public function activate_shortener()
  90. {
  91. $this->plugin_url = defined('WP_PLUGIN_URL') ? WP_PLUGIN_URL . '/' . dirname(plugin_basename(__FILE__)) : trailingslashit(get_bloginfo('wpurl')) . PLUGINDIR . '/' . dirname(plugin_basename(__FILE__));
  92. if ($this->plugin_option->get('urlserviceenable') == 'yes') {
  93. //FX registration mirrors WP stats plugin
  94. if (!function_exists('wp_get_shortlink')) {
  95. //Register these only for WP < 3.0.
  96. add_action('wp_head', array(&$this, 'urlyar_shortlink_wp_head'));
  97. add_action('wp', array(&$this, 'urlyar_shortlink_header'));
  98. //edit post-page button
  99. if ($this->check_wp_version(2.9)) {
  100. add_filter('get_sample_permalink_html', array(&$this, 'urlyar_get_shortlink_html'), 10, 2);
  101. }
  102. //compatibility - remove wp.me
  103. remove_action('wp_head', 'wpme_shortlink_wp_head');
  104. remove_action('wp', 'wpme_shortlink_header');
  105. remove_filter('get_sample_permalink_html', 'wpme_get_shortlink_html', 10, 2);
  106. } else {
  107. //Register a shortlink handler for WP >= 3.0.
  108. add_filter('get_shortlink', array(&$this, 'pub_gateway'), 10, 4);
  109. }
  110. //Future to Present
  111. add_action('future_to_publish', array(&$this, 'transition_get_shortlink'), 10, 1);
  112. }
  113. //Options
  114. add_action('admin_menu', array(&$this, 'plugin_menu'));
  115. //Tables
  116. add_filter('post_row_actions', array(&$this, 'table_hover_link'), 10, 2);
  117. add_filter('page_row_actions', array(&$this, 'table_hover_link'), 10, 2);
  118. add_action('admin_head', array(&$this, 'urlyar_urlshortener_adminhead'));
  119. add_action('load-edit.php', array(&$this, 'urlyar_urlshortener_edit_head'));
  120. add_action('load-edit-pages.php', array(&$this, 'urlyar_urlshortener_edit_head'));
  121. //AJAX Calls
  122. add_action('wp_ajax_urlshortener_act', array(&$this, 'urlyar_urlshortener_ajaxcallback'));
  123. //Nice IDs
  124. if ($this->plugin_option->get('niceid') == 'yes') {
  125. add_filter('template_redirect', array(&$this, 'template_redirect'), 10, 2);
  126. }
  127. //Shortcode
  128. if ($this->plugin_option->get('url_shortcode') != 'disable') {
  129. add_shortcode('urlyar_shortlink', array(&$this, 'shortcode_support'));
  130. }
  131. //Append Text
  132. add_filter('the_content', array(&$this, 'urlyar_filter_append_post'));
  133. //Append QR Code
  134. add_filter('the_content', array(&$this, 'urlyar_filter_append_post_qr'));
  135. }
  136. private function check_wp_version($version, $operator = ">=")
  137. {
  138. global $wp_version;
  139. return version_compare($wp_version, $version, $operator);
  140. }
  141. /*
  142. *****************************************
  143. * Check if shortener loaded.
  144. * Attempt to load it otherwise
  145. * Return false when all fails.
  146. *****************************************
  147. */
  148. private function shortener_loader()
  149. {
  150. if (!$this->shortener->load_status()) {
  151. $service = $this->plugin_option->get('urlservice');
  152. $this->shortener->set_user($this->plugin_option->get('apiuser_' . $service));
  153. $this->shortener->set_key($this->plugin_option->get('apikey_' . $service));
  154. $this->shortener->set_generic($this->plugin_option->get('generic_' . $service));
  155. $this->shortener->set_service($service);
  156. $result = $this->shortener->init_shortener();
  157. return ($result == 'OK') ? true : false;
  158. }
  159. return true;
  160. }
  161. /*
  162. *****************************************
  163. * Plugin Installer
  164. * Includes setting of default values
  165. * Migration Utility for v3.0 Series
  166. *****************************************
  167. */
  168. public function install()
  169. {
  170. $defaults = array(
  171. 'urlserviceenable' => 'no',
  172. 'urlservice' => '',
  173. 'useslug' => 'no',
  174. 'niceid' => 'no',
  175. 'niceid_prefix' => '/',
  176. 'appendurl' => array(
  177. 'home ' => 'no',
  178. 'single' => 'no',
  179. 'page' => 'no',
  180. 'product' => 'no',
  181. 'text' => 'Short URL:',
  182. ),
  183. 'appendqr' => array(
  184. 'home' => 'no',
  185. 'single' => 'no',
  186. 'page' => 'no',
  187. 'product' => 'no',
  188. 'text' => '',
  189. 'provider' => 'urlyar'
  190. ),
  191. 'url_shortcode' => 'disable',
  192. );
  193. $this->plugin_option->set_default($defaults);
  194. $this->plugin_option->migrate_options('about_plugin'); //check migration requirement
  195. $this->plugin_option->install_options();
  196. }
  197. /*
  198. *****************************************
  199. *
  200. * Shortlink Generation Main Functions
  201. *
  202. *****************************************
  203. */
  204. /*
  205. *****************************************
  206. * Automatic shortener
  207. *
  208. * Activated during Post Publishing or Post Viewing
  209. *****************************************
  210. */
  211. private function pub_get_shortlink($id = 0, $context = 'post', $allow_slugs = true, $transition = false)
  212. {
  213. include(dirname(__FILE__) . '/include/pub_get_shortlink.php');
  214. return $shortlink;
  215. }
  216. /*
  217. *****************************************
  218. * On demand shortener
  219. *
  220. * For calls directly from the public.
  221. * Shortener allocation must be different from global shortener
  222. * Fallback on default setting if service undefined
  223. *****************************************
  224. */
  225. public function od_get_shortlink($url = '', $service = '', $key = '', $user = '')
  226. {
  227. $shortlink = NULL;
  228. if (!empty($url)) {
  229. $od_shortener = new ss_shortener($this->plugin_status);
  230. if (empty($service)) {
  231. $service = $this->plugin_option->get('urlservice');
  232. $od_shortener->set_user($this->plugin_option->get('apiuser_' . $service));
  233. $od_shortener->set_key($this->plugin_option->get('apikey_' . $service));
  234. $od_shortener->set_generic($this->plugin_option->get('generic_' . $service));
  235. $od_shortener->set_service($service);
  236. } else {
  237. $od_shortener->config($service, $key, $user);
  238. }
  239. $status = $od_shortener->init_shortener();
  240. $shortlink = ($status == 'OK') ? $od_shortener->generate($url) : NULL;
  241. }
  242. return $shortlink;
  243. }
  244. /*
  245. *****************************************
  246. * Status hook for future posts
  247. * Hook to ensure generation only during publishing
  248. *****************************************
  249. */
  250. public function transition_get_shortlink($post)
  251. {
  252. $shortlink = $this->pub_get_shortlink($post->ID, 'post', true, true);
  253. }
  254. /*
  255. *****************************************
  256. *
  257. * Publishing CALLBACKS
  258. *
  259. *****************************************
  260. */
  261. //WP >= 3.0
  262. public function pub_gateway($shortlink, $id, $context, $allow_slugs)
  263. {
  264. $shortlink = $this->pub_get_shortlink($id, $context, $allow_slugs);
  265. return $shortlink;
  266. }
  267. //WP < 3.0
  268. public function urlyar_shortlink_wp_head()
  269. {
  270. global $wp_query;
  271. $shortlink = $this->pub_get_shortlink(0, 'query');
  272. if ($shortlink) {
  273. echo '<link rel="shortlink" href="' . $shortlink . '" />';
  274. }
  275. }
  276. public function urlyar_shortlink_header()
  277. {
  278. global $wp_query;
  279. if (headers_sent())
  280. return;
  281. $shortlink = $this->pub_get_shortlink(0, 'query');
  282. header('Link: <' . $shortlink . '>; rel=shortlink');
  283. }
  284. public function urlyar_get_shortlink_html($html, $post_id)
  285. {
  286. $shortlink = $this->pub_get_shortlink($post_id);
  287. if ($shortlink) {
  288. $html .= '<input id="shortlink" type="hidden" value="' . $shortlink . '" /><a href="' . $shortlink . '" class="button" onclick="prompt(&#39;URL:&#39;, jQuery(\'#shortlink\').val()); return false;">' . __('Get Shortlink') . '</a>';
  289. }
  290. return $html;
  291. }
  292. /*
  293. *****************************************
  294. *
  295. * WordPress Admin Pages
  296. *
  297. *****************************************
  298. */
  299. /*
  300. *****************************************
  301. * Plugin Options Page
  302. *****************************************
  303. */
  304. public function plugin_menu()
  305. {
  306. if (!is_admin())
  307. return;
  308. $this->plugin_page = add_options_page(__('URLYar', 'url-shortener'), __('URLYar', 'url-shortener'), 'manage_options', 'shorturl', array(&$this, 'options_page'));
  309. add_action('load-' . $this->plugin_page, array(&$this, 'options_style_scripts'));
  310. include(dirname(__FILE__) . '/include/options_page_help.php');
  311. add_contextual_help($this->plugin_page, $help_text);
  312. }
  313. public function options_page()
  314. {
  315. if (!is_admin())
  316. return;
  317. $action_url = $_SERVER['REQUEST_URI'];
  318. include(dirname(__FILE__) . '/include/options_page.php');
  319. }
  320. public function options_style_scripts()
  321. {
  322. wp_enqueue_style('url_shortener_options_css', $this->plugin_url . '/assets/css/options_page.css');
  323. }
  324. /*
  325. *****************************************
  326. * Table Pages
  327. *****************************************
  328. */
  329. public function table_hover_link($actions, $post)
  330. {
  331. $shortlink = $this->pub_get_shortlink($post->ID);
  332. if ($shortlink) {
  333. $actions['shortlink'] = '<a href="' . $shortlink . '" onclick="prompt(&#39;URL:&#39;, jQuery(this).attr(\'href\')); return false;">' . __('Get Shortlink') . '</a>';
  334. }
  335. return $actions;
  336. }
  337. public function urlyar_urlshortener_adminhead()
  338. {
  339. ?>
  340. <script type="text/javascript">
  341. var aaurl = '<?php echo admin_url('admin-ajax.php'); ?>';
  342. var nonce = '<?php echo wp_create_nonce('urlshortener_ajax');?>';
  343. </script>
  344. <?php
  345. }
  346. public function urlyar_urlshortener_edit_head()
  347. {
  348. wp_enqueue_script('urlyar_surl_ajax', $this->plugin_url . '/assets/js/jquery.ajaxq.js', array('jquery'), 1.0);
  349. wp_enqueue_script('urlyar_surl_edit', $this->plugin_url . '/assets/js/tablecol.js', array('jquery'), 1.0);
  350. }
  351. /*
  352. *****************************************
  353. *
  354. * AJAX CALLBACKS
  355. *
  356. *****************************************
  357. */
  358. /*
  359. *****************************************
  360. * Bulk Delete in Table Pages
  361. *****************************************
  362. */
  363. public function urlyar_urlshortener_ajaxcallback()
  364. {
  365. check_ajax_referer('urlshortener_ajax');
  366. $post_id = $_POST['pid'];
  367. delete_post_meta($post_id, 'shorturl');
  368. }
  369. /*
  370. *****************************************
  371. *
  372. * Misc Functions
  373. *
  374. *****************************************
  375. */
  376. /*
  377. *****************************************
  378. * QR Code Support
  379. * Used in:
  380. * - Shortcode
  381. * - Template Display
  382. * - Nice ID redirect
  383. *****************************************
  384. */
  385. public function get_qrcode($url, $size = '57', $qr_error = 'M', $url_only = false)
  386. {
  387. $append = $this->plugin_option->get('appendqr');
  388. if ($append["provider"] == "google")
  389. $link = 'https://chart.googleapis.com/chart?cht=qr&chl=' . $url . '&chs=' . $size . 'x' . $size . '&chld=' . $qr_error;
  390. else
  391. $link = $url . '/qr?chs=' . $size . 'x' . $size . '&chld=' . $qr_error;
  392. return ($url_only) ? $link : '<img class="urlyar-qr-img" width="' . $size . '" height="' . $size . '" src="' . $link . '" alt="" />';
  393. }
  394. /*
  395. *****************************************
  396. * Nice ID URL Redirect
  397. *****************************************
  398. */
  399. public function template_redirect($requested_url = null, $do_redirect = true)
  400. {
  401. global $wp;
  402. global $wp_query;
  403. if (is_404()) {
  404. $post_id = '';
  405. $request = $wp->request;
  406. $qr = false;
  407. //check for QR Code endings
  408. if (substr($request, -3) == '.qr') {
  409. $qr = true;
  410. $request = substr($request, 0, -3);
  411. }
  412. //matching for post id
  413. if (preg_match('/(\\d+)/', $request, $matches)) {
  414. $post_id = $matches[0];
  415. }
  416. //determine if still 404
  417. if (!empty($post_id) && is_numeric($post_id)) {
  418. $full_url = get_permalink($post_id);
  419. if ($full_url) {
  420. if ($qr) {
  421. header('Location: ' . $this->get_qrcode($full_url, 150, 'M', true));
  422. exit();
  423. } else {
  424. status_header(200);
  425. wp_redirect($full_url, 301);
  426. exit();
  427. }
  428. }
  429. }
  430. } //ends is_404 block
  431. }
  432. /*
  433. *****************************************
  434. * For use in template to
  435. * display shorturl
  436. *****************************************
  437. */
  438. public function urlyar_get_shortlink_display($post_id)
  439. {
  440. $shortlink = $this->pub_get_shortlink($post_id);
  441. return $shortlink;
  442. }
  443. /*
  444. *****************************************
  445. * Shortcode Support
  446. *****************************************
  447. */
  448. public function shortcode_support($atts, $content = null)
  449. {
  450. extract(shortcode_atts(array(
  451. 'name' => '',
  452. 'url' => '',
  453. 'service' => $this->plugin_option->get('urlservice'),
  454. 'key' => '',
  455. 'user' => '',
  456. 'qr' => false,
  457. 'size' => '',
  458. 'qr_error' => '',
  459. 'full' => false,
  460. ), $atts));
  461. global $post;
  462. $post_id = $post->ID;
  463. $full_url = get_permalink($post_id);
  464. //Assign URL as content if content not empty
  465. if (!empty($content)) {
  466. $url = $content;
  467. }
  468. //check if url still empty
  469. //Get shortlink if url true
  470. //Get Post URL and shortlink if false
  471. $shortlink = ($url) ? $this->od_get_shortlink($url, $service, $key, $user) :
  472. $this->pub_get_shortlink($post_id);
  473. //output type QR code?
  474. if (empty($qr)) {
  475. $output = '<a href="' . $shortlink . '">';
  476. $output .= ($name) ? $name : $shortlink;
  477. $output .= '</a>';
  478. } else {
  479. //determine if full URL used in QR code
  480. $output = ($full) ? '<a href="' . $full_url . '">' . $this->get_qrcode($full_url, $size, $qr_error) . '</a>' :
  481. '<a href="' . $shortlink . '">' . $this->get_qrcode($shortlink, $size, $qr_error) . '</a>';
  482. }
  483. return $output;
  484. }
  485. /*
  486. *****************************************
  487. * Append Shortlink to content
  488. *****************************************
  489. */
  490. public function urlyar_filter_append_post($content)
  491. {
  492. global $post;
  493. $append = $this->plugin_option->get('appendurl');
  494. if ((is_home() && $append['home'] == 'yes') ||
  495. (is_single() && $append['single'] == 'yes') ||
  496. (is_single() && $append['product'] == 'yes') ||
  497. (is_page() && $append['page'] == 'yes')
  498. ) {
  499. $shortlink = $this->pub_get_shortlink($post->ID);
  500. $content .= '<div class="urlyar-shortlink"><strong>' . $append['text'] . '</strong> <a class="urlyar-link" href="' . $shortlink . '">' . $shortlink . '</a></div>';
  501. }
  502. return $content;
  503. }
  504. /*
  505. *****************************************
  506. * Append QR Code to content
  507. *****************************************
  508. */
  509. public function urlyar_filter_append_post_qr($content)
  510. {
  511. global $post;
  512. $append = $this->plugin_option->get('appendqr');
  513. if ((is_home() && $append['home'] == 'yes') ||
  514. (is_single() && $append['single'] == 'yes') ||
  515. (is_single() && $append['product'] == 'yes') ||
  516. (is_page() && $append['page'] == 'yes')
  517. ) {
  518. $shortlink = $this->pub_get_shortlink($post->ID);
  519. $content .= '<div class="urlyar-qr">';
  520. $content .= (!empty($append['text'])) ? '<strong>' . $append['text'] . '</strong>' : '';
  521. $content .= $this->get_qrcode($shortlink, 150) . '</div>';
  522. }
  523. return $content;
  524. }
  525. //end class
  526. }
  527. endif;
  528. /*
  529. *****************************************
  530. *
  531. * WordPress Call to
  532. * Initialize and Activate Object
  533. *
  534. *****************************************
  535. */
  536. if (class_exists('URLYAR_URL_Shortener')) :
  537. /*
  538. *****************************************
  539. * Plugin Activation and assignments
  540. *****************************************
  541. */
  542. global $URLYAR_URL_Shortener;
  543. $URLYAR_URL_Shortener = new URLYAR_URL_Shortener(URLYAR_URL_SHORTENER_VERSION, URLYAR_URL_SHORTENER_STATUS);
  544. $URLYAR_URL_Shortener->activate_shortener();
  545. if (isset($URLYAR_URL_Shortener)) {
  546. register_activation_hook(__FILE__, array(&$URLYAR_URL_Shortener, 'install'));
  547. }
  548. /*
  549. *****************************************
  550. * Backward compatibility (template) functions
  551. *****************************************
  552. */
  553. //Show URL
  554. function urlyar_show_shorturl($post, $output = true)
  555. {
  556. global $URLYAR_URL_Shortener;
  557. $post_id = $post->ID;
  558. $shorturl = $URLYAR_URL_Shortener->urlyar_get_shortlink_display($post_id);
  559. if ($output) {
  560. echo $shorturl;
  561. } else {
  562. return $shorturl;
  563. }
  564. }
  565. //On-demand URL Shortener
  566. function urlyar_shorturl($url, $service, $output = true, $key = '', $user = '')
  567. {
  568. global $URLYAR_URL_Shortener;
  569. $shorturl = $URLYAR_URL_Shortener->od_get_shortlink($url, $service, $key, $user);
  570. if ($output) {
  571. echo $shorturl;
  572. } else {
  573. return $shorturl;
  574. }
  575. }
  576. endif;
  577. ?>