PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/redirection/models/redirect.php

https://bitbucket.org/ChendeyY/docklandsmedia
PHP | 453 lines | 340 code | 104 blank | 9 comment | 73 complexity | 057df969821520983cfc7f4b447d2ff0 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. class Red_Item {
  3. private $id = null;
  4. private $created;
  5. private $referrer;
  6. private $url = null;
  7. private $regex = false;
  8. private $action_data = null;
  9. private $action_code = 0;
  10. private $action_type;
  11. private $match_type;
  12. private $title;
  13. private $last_access = null;
  14. private $last_count = 0;
  15. private $tracking = true;
  16. private $status;
  17. private $position;
  18. private $group_id;
  19. function Red_Item( $values, $type = '', $match = '' ) {
  20. if ( is_object( $values ) ) {
  21. foreach ( $values as $key => $value ) {
  22. $this->$key = $value;
  23. }
  24. if ( $this->match_type ) {
  25. $this->match = Red_Match::create( $this->match_type, $this->action_data );
  26. $this->match->id = $this->id;
  27. $this->match->action_code = $this->action_code;
  28. }
  29. $action = false;
  30. if ( $this->action_type ) {
  31. $action = Red_Action::create( $this->action_type, $this->action_code );
  32. }
  33. if ( $action ) {
  34. $this->action = $action;
  35. $this->match->action = $this->action;
  36. }
  37. else
  38. $this->action = Red_Action::create( 'nothing', 0 );
  39. if ( $this->last_access == '0000-00-00 00:00:00' )
  40. $this->last_access = 0;
  41. else
  42. $this->last_access = mysql2date( 'U', $this->last_access );
  43. }
  44. else {
  45. $this->url = $values;
  46. $this->type = $type;
  47. $this->match = $match;
  48. }
  49. }
  50. static function get_all_for_module( $module ) {
  51. global $wpdb;
  52. $sql = $wpdb->prepare( "SELECT @redirection_items.*,@redirection_groups.tracking FROM @redirection_items INNER JOIN @redirection_groups ON @redirection_groups.id=@redirection_items.group_id AND @redirection_groups.status='enabled' AND @redirection_groups.module_id=%d WHERE @redirection_items.status='enabled' ORDER BY @redirection_groups.position,@redirection_items.position", $module );
  53. $sql = str_replace( '@', $wpdb->prefix, $sql );
  54. $rows = $wpdb->get_results( $sql );
  55. $items = array();
  56. if ( count( $rows) > 0 ) {
  57. foreach ( $rows AS $row ) {
  58. $items[] = new Red_Item( $row );
  59. }
  60. }
  61. return $items;
  62. }
  63. static function get_for_url( $url, $type ) {
  64. global $wpdb;
  65. $sql = $wpdb->prepare( "SELECT @redirection_items.*,@redirection_groups.position AS group_pos FROM @redirection_items INNER JOIN @redirection_groups ON @redirection_groups.id=@redirection_items.group_id AND @redirection_groups.status='enabled' AND @redirection_groups.module_id=%d WHERE (@redirection_items.regex=1 OR @redirection_items.url=%s)", WordPress_Module::MODULE_ID, $url );
  66. $sql = str_replace( '@', $wpdb->prefix, $sql);
  67. $rows = $wpdb->get_results( $sql ) ;
  68. $items = array();
  69. if ( count( $rows ) > 0 ) {
  70. foreach ( $rows AS $row ) {
  71. $items[] = array( 'position' => ( $row->group_pos * 1000 ) + $row->position, 'item' => new Red_Item( $row ) );
  72. }
  73. }
  74. usort( $items, array( 'Red_Item', 'sort_urls' ) );
  75. $items = array_map( array( 'Red_Item', 'reduce_sorted_items' ), $items );
  76. // Sort it in PHP
  77. ksort( $items );
  78. $items = array_values( $items );
  79. return $items;
  80. }
  81. static function sort_urls( $first, $second ) {
  82. if ( $first['position'] === $second['position'] )
  83. return 0;
  84. return $first['position'] < $second['position'];
  85. }
  86. static function reduce_sorted_items( $item ) {
  87. return $item['item'];
  88. }
  89. static function get_by_module( $module ) {
  90. global $wpdb;
  91. $sql = "SELECT {$wpdb->prefix}redirection_items.* FROM {$wpdb->prefix}redirection_items INNER JOIN {$wpdb->prefix}redirection_groups ON {$wpdb->prefix}redirection_groups.id={$wpdb->prefix}redirection_items.group_id";
  92. $sql .= $wpdb->prepare( " WHERE {$wpdb->prefix}redirection_groups.module_id=%d", $module );
  93. $rows = $wpdb->get_results( $sql );
  94. $items = array();
  95. foreach( (array)$rows AS $row ) {
  96. $items[] = new Red_Item( $row );
  97. }
  98. return $items;
  99. }
  100. static function get_by_id( $id ) {
  101. global $wpdb;
  102. $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}redirection_items WHERE id=%d", $id ) );
  103. if ( $row )
  104. return new Red_Item( $row );
  105. return false;
  106. }
  107. static function auto_generate() {
  108. $options = red_get_options();
  109. $id = time();
  110. $url = $options['auto_target'];
  111. $url = str_replace( '$dec$', $id, $url );
  112. $url = str_replace( '$hex$', sprintf( '%x', $id), $url );
  113. return $url;
  114. }
  115. static function create( array $details ) {
  116. global $wpdb;
  117. $details = array_map( 'trim', $details );
  118. $details = array_map( 'stripslashes', $details );
  119. // Auto generate URLs
  120. if ( empty( $details['source'] ) )
  121. $details['source'] = self::auto_generate();
  122. if ( empty( $details['target'] ) )
  123. $details['target'] = self::auto_generate();
  124. // Make sure we don't redirect to ourself
  125. if ( $details['source'] == $details['target'] )
  126. return new WP_Error( 'redirect-add', __( 'Source and target URL must be different', 'redirection' ) );
  127. $parsed_url = parse_url( $details['source'] );
  128. $parsed_domain = parse_url( site_url() );
  129. if ( isset( $parsed_url['scheme'] ) && ( $parsed_url['scheme'] === 'http' || $parsed_url['scheme'] === 'https' ) && $parsed_url['host'] !== $parsed_domain['host'] ) {
  130. return new WP_Error( 'redirect-add', sprintf( __( 'You can only redirect from a relative URL (<code>%s</code>) on this domain (<code>%s</code>).', 'redirection' ), $parsed_url['path'], $parsed_domain['host'] ) );
  131. }
  132. $matcher = Red_Match::create( $details['match'] );
  133. $group_id = intval( $details['group_id'] );
  134. $group = Red_Group::get( $group_id );
  135. if ( $group_id <= 0 || !$group )
  136. return new WP_Error( 'redirect-add', __( 'Invalid group when creating redirect', 'redirection' ) );
  137. if ( !$matcher )
  138. return new WP_Error( 'redirect-add', __( 'Invalid source URL when creating redirect for given match type', 'redirection' ) );
  139. $regex = ( isset( $details['regex']) && $details['regex'] != false) ? 1 : 0;
  140. $position = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}redirection_items WHERE group_id=%d", $group_id ) );
  141. $action = $details['red_action'];
  142. $action_code = 0;
  143. if ( $action == 'url' || $action == 'random' )
  144. $action_code = 301;
  145. elseif ( $action == 'error' )
  146. $action_code = 404;
  147. if ( isset( $details['action_code'] ) )
  148. $action_code = intval( $details['action_code'] );
  149. $data = array(
  150. 'url' => self::sanitize_url( $details['source'], $regex),
  151. 'action_type' => $details['red_action'],
  152. 'regex' => $regex,
  153. 'position' => $position,
  154. 'match_type' => $details['match'],
  155. 'action_data' => $matcher->data( $details ),
  156. 'action_code' => $action_code,
  157. 'last_access' => '0000-00-00 00:00:00',
  158. 'group_id' => $group_id
  159. );
  160. $data = apply_filters( 'redirection_create_redirect', $data );
  161. $wpdb->delete( $wpdb->prefix.'redirection_items', array( 'url' => $data['action_data'], 'action_type' => $data['action_type'], 'action_data' => $data['url'] ) );
  162. if ( $wpdb->insert( $wpdb->prefix.'redirection_items', $data ) ) {
  163. Red_Module::flush( $group_id );
  164. return self::get_by_id( $wpdb->insert_id );
  165. }
  166. return new WP_Error( 'redirect-add', __( 'Unable to add new redirect - delete Redirection from the options page and re-install' ) );
  167. }
  168. public function delete() {
  169. global $wpdb;
  170. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}redirection_items WHERE id=%d", $this->id ) );
  171. RE_Log::delete_for_id( $this->id );
  172. // Reorder all elements
  173. $rows = $wpdb->get_results( "SELECT id FROM {$wpdb->prefix}redirection_items ORDER BY position" );
  174. if ( count( $rows) > 0 ) {
  175. foreach ( $rows AS $pos => $row ) {
  176. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'position' => $pos ), array( 'id' => $row->id ) );
  177. }
  178. }
  179. Red_Module::flush( $this->group_id );
  180. }
  181. static function sanitize_url( $url, $regex ) {
  182. // Make sure that the old URL is relative
  183. $url = preg_replace( '@^https?://(.*?)/@', '/', $url );
  184. $url = preg_replace( '@^https?://(.*?)$@', '/', $url );
  185. if ( substr( $url, 0, 1) != '/' && $regex == false )
  186. $url = '/'.$url;
  187. return $url;
  188. }
  189. function update( $details ) {
  190. if ( strlen( $details['old'] ) > 0 ) {
  191. global $wpdb;
  192. $details = array_map( 'stripslashes', $details );
  193. $this->regex = isset( $details['regex'] ) ? 1 : 0;
  194. $this->url = self::sanitize_url( $details['old'], $this->regex );
  195. $this->title = $details['title'];
  196. $data = $this->match->data( $details );
  197. $this->action_code = 0;
  198. if ( isset( $details['action_code'] ) )
  199. $this->action_code = intval( $details['action_code'] );
  200. $old_group = false;
  201. if ( isset( $details['group_id'] ) ) {
  202. $old_group = intval( $this->group_id );
  203. $this->group_id = intval( $details['group_id'] );
  204. }
  205. // Save this
  206. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'url' => $this->url, 'regex' => $this->regex, 'action_code' => $this->action_code, 'action_data' => $data, 'group_id' => $this->group_id, 'title' => $this->title ), array( 'id' => $this->id ) );
  207. if ( $old_group !== $this->group_id ) {
  208. Red_Module::flush( $this->group_id );
  209. Red_Module::flush( $old_group );
  210. }
  211. }
  212. }
  213. static function save_order( $items, $start ) {
  214. global $wpdb;
  215. foreach ( $items AS $pos => $id ) {
  216. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'position' => $pos + $start ), array( 'id' => $id ) );
  217. }
  218. Red_Module::flush( $this->group_id );
  219. }
  220. function matches( $url ) {
  221. $this->url = str_replace( ' ', '%20', $this->url );
  222. $matches = false;
  223. // Check if we match the URL
  224. if ( ( $this->regex == false && ( $this->url == $url || $this->url == rtrim( $url, '/' ) || $this->url == urldecode( $url ) ) ) ||( $this->regex == true && @preg_match( '@'.str_replace( '@', '\\@', $this->url).'@', $url, $matches) > 0) ||( $this->regex == true && @preg_match( '@'.str_replace( '@', '\\@', $this->url).'@', urldecode( $url ), $matches) > 0) ) {
  225. // Check if our match wants this URL
  226. $target = $this->match->get_target( $url, $this->url, $this->regex );
  227. if ( $target ) {
  228. $target = $this->replaceSpecialTags( $target );
  229. $this->visit( $url, $target );
  230. if ( $this->status === 'enabled' )
  231. return $this->action->process_before( $this->action_code, $target );
  232. }
  233. }
  234. return false;
  235. }
  236. function replaceSpecialTags( $target ) {
  237. if ( is_numeric( $target ) )
  238. $target = get_permalink( $target );
  239. else {
  240. $user = wp_get_current_user();
  241. if ( !empty( $user ) ) {
  242. $target = str_replace( '%userid%', $user->ID, $target );
  243. $target = str_replace( '%userlogin%', isset( $user->user_login ) ? $user->user_login : '', $target );
  244. $target = str_replace( '%userurl%', isset( $user->user_url ) ? $user->user_url : '', $target );
  245. }
  246. }
  247. return $target;
  248. }
  249. function visit( $url, $target ) {
  250. if ( $this->tracking && $this->id ) {
  251. global $wpdb, $redirection;
  252. // Update the counters
  253. $count = $this->last_count + 1;
  254. $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}redirection_items SET last_count=%d, last_access=NOW() WHERE id=%d", $count, $this->id ) );
  255. if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
  256. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  257. elseif ( isset( $_SERVER['REMOTE_ADDR'] ) )
  258. $ip = $_SERVER['REMOTE_ADDR'];
  259. $options = red_get_options();
  260. if ( isset( $options['expire_redirect'] ) && $options['expire_redirect'] >= 0 )
  261. $log = RE_Log::create( $url, $target, $_SERVER['HTTP_USER_AGENT'], $ip, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', array( 'redirect_id' => $this->id, 'group_id' => $this->group_id) );
  262. }
  263. }
  264. public function is_enabled() {
  265. return $this->status === 'enabled';
  266. }
  267. function reset() {
  268. global $wpdb;
  269. $this->last_count = 0;
  270. $this->last_access = '0000-00-00 00:00:00';
  271. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'last_count' => 0, 'last_access' => $this->last_access ), array( 'id' => $this->id ) );
  272. RE_Log::delete_for_id( $this->id );
  273. }
  274. function show_url( $url ) {
  275. return implode( '&#8203;/', explode( '/', $url ) );
  276. }
  277. function move_to( $group ) {
  278. global $wpdb;
  279. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'group_id' => $group ), array( 'id' => $this->id ) );
  280. }
  281. public function enable() {
  282. global $wpdb;
  283. $this->status = 'enabled';
  284. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'status' => $this->status ), array( 'id' => $this->id ) );
  285. }
  286. public function disable() {
  287. global $wpdb;
  288. $this->status = 'disabled';
  289. $wpdb->update( $wpdb->prefix.'redirection_items', array( 'status' => $this->status ), array( 'id' => $this->id ) );
  290. }
  291. static function actions( $action = '' ) {
  292. $actions = array(
  293. 'url' => __( 'Redirect to URL', 'redirection' ),
  294. 'random' => __( 'Redirect to random post', 'redirection' ),
  295. 'pass' => __( 'Pass-through', 'redirection' ),
  296. 'error' => __( 'Error (404)', 'redirection' ),
  297. 'nothing' => __( 'Do nothing', 'redirection' ),
  298. );
  299. if ( $action )
  300. return $actions[$action];
  301. return $actions;
  302. }
  303. function match_name() {
  304. return $this->match->match_name();
  305. }
  306. function type() {
  307. if ( ( $this->action_type == 'url' || $this->action_type == 'error' || $this->action_type == 'random' ) && $this->action_code > 0 )
  308. return $this->action_code;
  309. else if ( $this->action_type == 'pass' )
  310. return 'pass';
  311. return '&mdash;';
  312. }
  313. public function get_id() {
  314. return $this->id;
  315. }
  316. public function get_position() {
  317. return $this->position;
  318. }
  319. public function get_group_id() {
  320. return $this->group_id;
  321. }
  322. public function get_url() {
  323. return $this->url;
  324. }
  325. public function get_title() {
  326. return $this->title;
  327. }
  328. public function get_hits() {
  329. return $this->last_count;
  330. }
  331. public function get_last_hit() {
  332. return $this->last_access;
  333. }
  334. public function is_regex() {
  335. return $this->regex ? true : false;
  336. }
  337. public function get_match_type() {
  338. return $this->match_type;
  339. }
  340. public function get_action_type() {
  341. return $this->action_type;
  342. }
  343. public function get_action_code() {
  344. return intval( $this->action_code );
  345. }
  346. public function get_action_data() {
  347. return $this->action_data;
  348. }
  349. }