PageRenderTime 56ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/3pagination.php

https://github.com/wp-plugins/3pagination
PHP | 397 lines | 187 code | 70 blank | 140 comment | 94 complexity | 3ae69a43852d788ef989a70005a36b2c MD5 | raw file
  1. <?php
  2. /**
  3. * Plugin Name: 3pagination
  4. * Description: Reach any page with no more than 3 clicks
  5. * Version: 1.3.3b
  6. * Author: Michael Schrรถder <ms@ts-webdesign.net>
  7. * TextDomain: 3pagination
  8. * DomainPath: /languages
  9. */
  10. if ( !class_exists( 'threepagination' ) ) {
  11. if ( function_exists( 'add_filter' ) ) {
  12. add_filter( 'plugins_loaded', array( 'threepagination', 'get_object' ) );
  13. // Upon deactivation
  14. register_uninstall_hook( __FILE__, array( 'threepagination', 'uninstall' ) );
  15. }
  16. class threepagination {
  17. /**
  18. * Textdomain string
  19. *
  20. * @var string
  21. */
  22. protected $textdomain;
  23. /**
  24. * Class object
  25. *
  26. * @var object
  27. */
  28. static $_object;
  29. /**
  30. * Create class object
  31. *
  32. * @access public
  33. * @return object $_object
  34. * @since 0.1a
  35. */
  36. public static function get_object() {
  37. if ( NULL == self::$_object ) {
  38. self::$_object = new self;
  39. }
  40. return self::$_object;
  41. }
  42. /**
  43. * Class init
  44. *
  45. * @since 1.1
  46. */
  47. public function __construct() {
  48. // Get files
  49. $this->include_files();
  50. // Set textdomain string
  51. add_filter( 'init', array( $this, 'set_textdomain' ), 1 );
  52. add_filter( 'init', array( $this, 'load_plugin_textdomain' ), 2 );
  53. add_filter( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
  54. add_filter( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
  55. }
  56. /**
  57. * Include files
  58. *
  59. * @since 1.2b
  60. */
  61. public function include_files() {
  62. require_once( plugin_dir_path( __FILE__ ) . 'class.settings.php' );
  63. }
  64. /**
  65. * Set plugin's textdomain
  66. *
  67. * @since 1.2b
  68. */
  69. public function set_textdomain() {
  70. $this->textdomain = '3pagination';
  71. }
  72. public function load_plugin_textdomain() {
  73. load_plugin_textdomain( $this->textdomain, FALSE, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
  74. }
  75. /**
  76. * Load admin scripts
  77. *
  78. * @since 1.2b
  79. */
  80. public function admin_scripts() {
  81. wp_enqueue_style( 'threepagination-css', plugins_url( 'examples/style.css', __FILE__ ) );
  82. }
  83. /**
  84. * Load frontend scripts
  85. *
  86. * @since 1.2b
  87. */
  88. public function frontend_scripts() {
  89. wp_enqueue_style( 'threepagination-css', plugins_url( 'examples/style.css', __FILE__ ) );
  90. wp_enqueue_script( '3pagination-js', plugins_url( '/js/3pagination.js', __FILE__ ), array( 'jquery', 'json2' ) );
  91. wp_localize_script( '3pagination-js', 'threepag_vars', $this->frontend_vars() );
  92. }
  93. /**
  94. * Set frontend vars
  95. *
  96. * @TODO: Pages, Custom post types?
  97. *
  98. * @return type
  99. * @since 1.2b
  100. */
  101. private function frontend_vars() {
  102. $vars = array( );
  103. $settings = get_option( '3pagination_settings' );
  104. // Check placement
  105. if ( 'on' == $this->init_var( $settings, 'placement_header_index' ) && is_home() ||
  106. 'on' == $this->init_var( $settings, 'placement_header_archive' ) && is_archive() ||
  107. 'on' == $this->init_var( $settings, 'placement_header_category' ) && is_category() ||
  108. 'on' == $this->init_var( $settings, 'placement_header_search' ) && is_search() )
  109. $vars[ 'placement_header' ] = TRUE;
  110. if ( 'on' == $this->init_var( $settings, 'placement_footer_index' ) && is_home() ||
  111. 'on' == $this->init_var( $settings, 'placement_footer_archive' ) && is_archive() ||
  112. 'on' == $this->init_var( $settings, 'placement_footer_category' ) && is_category() ||
  113. 'on' == $this->init_var( $settings, 'placement_footer_search' ) && is_search() )
  114. $vars[ 'placement_footer' ] = TRUE;
  115. if ( 'on' == $this->init_var( $settings, 'placement_prepend_index' ) && is_home() ||
  116. 'on' == $this->init_var( $settings, 'placement_prepend_archive' ) && is_archive() ||
  117. 'on' == $this->init_var( $settings, 'placement_prepend_category' ) && is_category() ||
  118. 'on' == $this->init_var( $settings, 'placement_prepend_search' ) && is_search() ) {
  119. $vars[ 'placement_prepend' ] = TRUE;
  120. $vars[ 'placement_prepend_id' ] = $settings[ 'placement_prepend_id' ];
  121. }
  122. if ( 'on' == $this->init_var( $settings, 'placement_append_index' ) && is_home() ||
  123. 'on' == $this->init_var( $settings, 'placement_append_archive' ) && is_archive() ||
  124. 'on' == $this->init_var( $settings, 'placement_append_category' ) && is_category() ||
  125. 'on' == $this->init_var( $settings, 'placement_append_search' ) && is_search() ) {
  126. $vars[ 'placement_append' ] = TRUE;
  127. $vars[ 'placement_append_id' ] = $settings[ 'placement_append_id' ];
  128. }
  129. // HTML output
  130. $vars[ 'html' ] = json_encode( self::get() );
  131. return $vars;
  132. }
  133. /**
  134. * Returns a HTML string containing the navigation.
  135. *
  136. * @global object $wp_query | the current query object used to gather pagination information
  137. * @global type $wp
  138. * @param bool $pretty | pretty permalink strukture. TRUE or FALSE
  139. * @param int $max_num_pages | total page count
  140. * @param bool $labels | show labels, TRUE or FALSE
  141. * @param string $css | the css class name appended to the 'threepagination' wrapper div
  142. * @return void
  143. * @since 0.1a
  144. */
  145. public static function get( $pretty = TRUE, $max_num_pages = FALSE, $labels = TRUE, $css = 'classic', $wp_query = FALSE ) {
  146. global $wp;
  147. // Set current query object
  148. if ( FALSE == $wp_query || ! is_object( $wp_query ) )
  149. global $wp_query;
  150. // Get global settings
  151. $settings = get_option( '3pagination_settings' );
  152. // Permalink structure
  153. $pretty = ( 'on' == $settings[ 'other_pretty' ] ) ? TRUE : FALSE;
  154. // Get the page count.
  155. $total_pages = ( FALSE == $max_num_pages ) ? $wp_query->max_num_pages : $max_num_pages;
  156. // No need for navi
  157. if ( 1 == $total_pages )
  158. return;
  159. // For now, 3pagination supports up to 999 pages only
  160. if ( intval( $settings[ 'other_maxnumpages' ] ) < $total_pages )
  161. $total_pages = intval( $settings[ 'other_maxnumpages' ] );
  162. // Get currently visited page
  163. $on_page = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
  164. $digits = strlen( $on_page );
  165. $page_string = '';
  166. // Start some complicated calculations. The benfit should
  167. // be a navigation that lets you navigate to any page between 1 and 999
  168. // without more than 3 mouse clicks. Maximum page number is 999.
  169. switch ( $digits ) {
  170. case 1:
  171. case 2:
  172. for ( $i = 1; $i <= $total_pages; ++$i ) {
  173. if ( $i == 1
  174. OR ($i <= 10 AND $digits == 1)
  175. OR ($i < 100 AND substr( $i, -2, 1 ) == substr( $on_page, -2, 1 ) AND $digits == strlen( $i ))
  176. OR ($i >= 10 AND $i < 100 AND is_int( $i / 10 ))
  177. OR (is_int( $i / 100 ))
  178. OR ($i == $total_pages)
  179. ) {
  180. $url = self::url( $wp, $i, $pretty );
  181. $page_string .= ( $i == $on_page ) ? "<span class='page-numbers current'>" . $i . "</span>" : "<a class='page-numbers' href='" . $url . "'>" . $i . "</a>";
  182. if ( $i < $total_pages ) {
  183. $page_string .= "&nbsp;";
  184. }
  185. }
  186. }
  187. break;
  188. case 3:
  189. for ( $i = 1; $i <= $total_pages; ++$i ) {
  190. if ( $i == 1
  191. OR ($i >= 100 AND substr( $i, -3, 2 ) == substr( $on_page, -3, 2 ))
  192. OR ($i >= 100 AND is_int( $i / 10 ) AND substr( $i, -3, 1 ) == substr( $on_page, -3, 1 ))
  193. OR (is_int( $i / 100 ))
  194. OR ($i == $total_pages)
  195. ) {
  196. $url = self::url( $wp, $i, $pretty );
  197. $page_string .= ( $i == $on_page ) ? "<span class='page-numbers current'>" . $i . "</span>" : "<a href='" . $url . "'>" . $i . "</a>";
  198. if ( $i < $total_pages ) {
  199. $page_string .= "&nbsp;";
  200. }
  201. }
  202. }
  203. break;
  204. default:
  205. for ( $i = 1; $i <= 999; ++$i ) {
  206. if ( $i == 1
  207. OR ($i >= 100 AND substr( $i, -3, 2 ) == substr( $on_page, -3, 2 ))
  208. OR ($i >= 100 AND is_int( $i / 10 ) AND substr( $i, -3, 1 ) == substr( $on_page, -3, 1 ))
  209. OR (is_int( $i / 100 ))
  210. OR ($i == $total_pages)
  211. ) {
  212. $url = self::url( $wp, $i, $pretty );
  213. $page_string .= ( $i == $on_page ) ? "<span class='page-numbers current'>" . $i . "</span>" : "<a href='" . $url . "'>" . $i . "</a>";
  214. if ( $i < $total_pages ) {
  215. $page_string .= "&nbsp;";
  216. }
  217. }
  218. }
  219. break;
  220. }
  221. $css = isset( $settings[ 'css_class' ] ) ? $settings[ 'css_class' ] : $css;
  222. // Navigation labels
  223. if ( FALSE !== $labels && 'on' == $settings[ 'labels_show' ] ) {
  224. if ( $on_page > 1 ) {
  225. $i = $on_page - 1;
  226. $page_string = "<a class='page-numbers label-first' href='" . self::url( $wp, 1, $pretty ) . "'>" . self::init_var( $settings, 'labels_first', '&laquo;', TRUE ) . "</a>&nbsp;" . $page_string;
  227. $page_string = "<a class='page-numbers label-previous' href='" . self::url( $wp, $i, $pretty ) . "'>" . self::init_var( $settings, 'labels_previous', '&lsaquo;', TRUE ) . "</a>&nbsp;" . $page_string;
  228. }
  229. if ( $on_page < $total_pages ) {
  230. $i = $on_page + 1;
  231. $page_string .= "&nbsp;<a class='page-numbers label-last' href='" . self::url( $wp, $total_pages, $pretty ) . "'>" . self::init_var( $settings, 'labels_last', '&raquo;', TRUE ) . "</a>";
  232. $page_string .= "&nbsp;<a class='page-numbers label-next' href='" . self::url( $wp, $i, $pretty ) . "'>" . self::init_var( $settings, 'labels_next', '&rsaquo;', TRUE ) . "</a>";
  233. }
  234. }
  235. // Glue together the HTML string
  236. $page_string = "<div class='threepagination $css'><div class='threepagination-pages'>" . $page_string . "</div></div>";
  237. // Return string
  238. return $page_string;
  239. }
  240. /**
  241. * Main display function. Should be called in a static fashion:
  242. * threepagination::draw();
  243. *
  244. * @global object $wp_query | the current query object used to gather pagination information
  245. * @global type $wp
  246. * @param bool $pretty | pretty permalink structure. TRUE or FALSE, defaults to TRUE
  247. * @param int $num_items | can be used to override the global number of items
  248. * @param int $per_page | can be used to override the global posts per page
  249. * @param bool $labels | show labels, TRUE or FALSE
  250. * @return void
  251. *
  252. * @since 0.1a
  253. */
  254. public static function draw( $pretty = TRUE, $max_num_pages = FALSE, $labels = TRUE, $css = 'classic', $wp_query = FALSE ) {
  255. echo self::get( $pretty, $max_num_pages, $labels, $css, $wp_query );
  256. }
  257. /**
  258. * Create link href
  259. *
  260. * @TODO: _always_ append possibly existing URL parameters
  261. *
  262. * @param object $wp | WP object
  263. * @param int $i | current element
  264. * @param bool $pretty | pretty permalink structure. TRUE or FALSE, defaults to TRUE
  265. * @return string $url | the href attribute of our pagination element link
  266. */
  267. private static function url( $wp, $i, $pretty ) {
  268. // Pretty URLs
  269. if ( TRUE == $pretty ) {
  270. if ( get_query_var( 'paged' ) )
  271. $url = preg_replace( '!(/page/\d+)/?$!', '/page/' . $i, home_url( $wp->request ) );
  272. else
  273. $url = home_url( $wp->request ) . '/page/' . $i;
  274. }
  275. // Default URLs
  276. else
  277. $url = home_url( $wp->request ) . '?paged=' . $i;
  278. // Does the current URL have any parameters? If so,
  279. // we will always append them to the new link url, even
  280. // if pretty URLs = on
  281. $base_url = 'http://' . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ];
  282. if ( strpos( $base_url, '=' ) ) {
  283. // has at least one param
  284. $params = parse_url( $base_url );
  285. $params_default = preg_replace( '!&?paged=\d{1,3}&?!', '', $params[ 'query' ] );
  286. if ( TRUE == $pretty )
  287. $url.= '?' . $params[ 'query' ];
  288. else if ( '' == $params_default )
  289. $url.= '';
  290. else
  291. $url.= '&' . $params_default;
  292. }
  293. return $url;
  294. }
  295. /**
  296. * For not getting pissed of too much by PHP notices. This function should
  297. * help to keep the "flow" of the code, i.e. limiting the amount of conditional
  298. * statements in HTML blocks, etc.
  299. *
  300. * Example use: selected( $this->init_var( $var2, $index ), $var )
  301. * Instead of: if( !empty( $var2[ $index ] ) ) : selected( $var2[ $index ], $var ); endif;
  302. *
  303. * @access public
  304. * @param var $var | the variable to check
  305. * @param string $index | the index of the variable
  306. * @param string, boolean $default | var default value
  307. * @param bool $override_set_empty | Set var to default if it is emtpy
  308. * @return var $var[ $index ] | the value of $var[ $index ]
  309. * @since 0.1a
  310. */
  311. public function init_var( $var, $index, $default = FALSE, $override_set_empty = FALSE ) {
  312. // is the $index of $var not yet set or (optional) set but empty?
  313. if ( !isset( $var[ $index ] ) || ( TRUE == $override_set_empty && empty( $var[ $index ] ) ) )
  314. $var[ $index ] = ( FALSE == $default ) ? FALSE : $default;
  315. return $var[ $index ];
  316. }
  317. /**
  318. * Cleanup
  319. *
  320. * @since 1.3b
  321. */
  322. public static function uninstall() {
  323. delete_option( '3pagination_settings' );
  324. }
  325. }
  326. }
  327. ?>