prefix . "status_date"; } static public function reader_table(){ global $wpdb; return $wpdb->prefix . "reader_posts"; } static public function relationships_table(){ global $wpdb; return $wpdb->prefix . "reader_source_relationships"; } static public function sources_table(){ global $wpdb; return $wpdb->prefix . "reader_sources"; } /** * Templates multi-dimentional directory listing to hashed list. * * Will take a multi-dimentional directory listing array returned from scandir_r, and store it as a * single-dimentional array based upon it's second value that is a hash. * * @param array $list Multi-dimenional array from scandir_r. */ static public function templates_to_hash( &$list ) { foreach ( $list as $key => $value ) { if ( gettype($key) == 'string' ) { self::templates_to_hash( $list[$key] ); } else { self::$templates_by_hash[$value[1]] = array( $value[0], $value[2] ); } } } /** * Flushes rewrite rules in WordPress */ static public function flush_rules() { global $wp_rewrite; $wp_rewrite->flush_rules(); } /** * Logs errors */ static public function error_log( $error = false ) { $errors = get_option( 'awe_errors', array() ); if ( $error ) { $errors[] = $error; update_option( 'awe_errors', $errors ); } return $errors; } /** * Logs messages */ static public function log( $message = false ) { $messages = get_option( 'awe_messages', array() ); if ( $message ) { $messages[] = $message; update_option( 'awe_messages', $messages ); } return $messages; } /** * Returns top-level pages as an array with values to be used as terms for the menu display */ static public function get_pages_as_terms( ) { global $wpdb; $query = "SELECT post_name, post_title FROM $wpdb->posts WHERE post_type = 'page' AND post_parent = 0 AND post_status = 'publish'"; $arcresults = $wpdb->get_results($query); $value = array(); foreach ( $arcresults as $arcresult ) { $item = new stdClass(); $item->slug = $arcresult->post_name; $item->name = $arcresult->post_title; $item->count = false; $value[] = $item; } return $value; } /** * Used to get terms used in a specific post_type */ static public function get_terms_by_post_type( $taxonomy, $post_types ) { global $wpdb; if ( in_array( $taxonomy, array( 'year', 'month', 'day' ) ) ) { // sql query posts $where = apply_filters('getarchives_where', "WHERE post_type IN('".join( "', '", $post_types )."') AND post_status = 'publish'"); $join = apply_filters('getarchives_join', ""); $limit = ' LIMIT 100'; // archives switch ( $taxonomy ) { case 'year': $value = array(); $query = "SELECT YEAR(post_date) AS `year`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date) ORDER BY post_date DESC $limit"; $qkey = md5($query); $cache = wp_cache_get( 'awe_taxonomy' , 'year' ); if ( !isset( $cache[ $qkey ] ) ) { $arcresults = $wpdb->get_results($query); $cache[ $qkey ] = $arcresults; wp_cache_set( 'awe_taxonomy', $cache, 'year' ); } else { $arcresults = $cache[ $qkey ]; } if ($arcresults) { $value = array(); foreach ( $arcresults as $arcresult ) { $item = new stdClass(); $item->slug = $arcresult->year; $item->name = $arcresult->year; $item->count = $arcresult->posts; $value[] = $item; } } else { $value = false; } break; case 'month': $value = array(); $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) AS posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC $limit"; $qkey = md5($query); $cache = wp_cache_get( 'awe_taxonomy' , 'month' ); if ( !isset( $cache[ $qkey ] ) ) { $arcresults = $wpdb->get_results($query); $cache[ $qkey ] = $arcresults; wp_cache_set( 'awe_taxonomy', $cache, 'month' ); } else { $arcresults = $cache[ $qkey ]; } if ($arcresults) { $value = array(); global $month; foreach ( $arcresults as $arcresult ) { $item = new stdClass(); $item->slug = $arcresult->month; $item->name = $month[zeroise($arcresult->month, 2)]; $item->count = $arcresult->posts; $value[$arcresult->year][] = $item; } } else { $value = false; } break; case 'day': $value = array(); break; default: $value = false; } return $value; } else { $query = $wpdb->prepare( "SELECT t.*, COUNT(*) from $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id WHERE p.post_type IN('".join( "', '", $post_types )."') AND tt.taxonomy IN('".$taxonomy."') AND p.post_status = 'publish' GROUP BY t.term_id ORDER BY t.name ASC"); $results = $wpdb->get_results( $query ); return $results; } } static public function db_migrate_data() { global $wpdb; $sources = get_option( 'awe_sources' ); $sql_values = array(); foreach ( $sources as $source ) { $sql_values[] = $wpdb->prepare( "(%s,%s,%s)", $source['slug'], $source['title'], $source['url'] ); } // Copy sources $sql = 'INSERT IGNORE '.self::sources_table().' (source_ID,source_title,source_url) VALUES '.implode(',', $sql_values); $sources_status = $wpdb->query( $sql ); // Copy posts-sources relationships $sql = 'INSERT IGNORE '.self::relationships_table().' (guid,source_ID) SELECT p.guid,s.meta_value FROM '.$wpdb->posts.' p LEFT JOIN '.$wpdb->postmeta.' s ON p.ID = s.post_id AND s.meta_key="source" WHERE p.post_type="update"'; $relationships_status = $wpdb->query( $sql ); // Copy posts $sql = 'INSERT IGNORE '.self::reader_table().' (guid,post_title,post_body,post_date,post_permalink,post_status) SELECT p.guid,p.post_title,p.post_content,p.post_date,m.meta_value,p.post_status FROM '.$wpdb->posts.' p LEFT JOIN '.$wpdb->postmeta.' m ON p.ID = m.post_id AND m.meta_key="source_permalink" WHERE p.post_type="update" AND p.post_status IN ("pending", "publish")'; $updates_status = $wpdb->query( $sql ); // Migrated old data status if ( get_option( 'awe_database_migrated' ) != self::$db_version ) { update_option( 'awe_database_migrated', self::$db_version ); } else { add_option( 'awe_database_migrated', self::$db_version, ' ', 'no' ); } return true; } static public function db_install() { global $wpdb; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); $table = self::sources_table(); $sql = "CREATE TABLE $table ( source_ID VARCHAR(40), source_title TEXT NOT NULL, source_url VARCHAR(255) NOT NULL, source_updated DATETIME NULL, source_description TEXT NULL, source_site_url VARCHAR(255) NULL, source_status VARCHAR(20) DEFAULT 'new' NOT NULL, source_errors LONGTEXT NULL, PRIMARY KEY (source_ID) );"; $table = self::reader_table(); $sql .= "CREATE TABLE $table ( guid VARCHAR(255), post_title TEXT NOT NULL, post_body LONGTEXT NOT NULL, post_author TEXT NULL, post_date DATETIME NOT NULL, post_permalink VARCHAR(255) NOT NULL, post_status VARCHAR(20) DEFAULT 'pending' NOT NULL, PRIMARY KEY (guid), KEY post_status (post_status), KEY post_date (post_date) );"; $table = self::relationships_table(); $sql .= "CREATE TABLE $table ( source_ID VARCHAR(40) NOT NULL, guid VARCHAR(255) NOT NULL, PRIMARY KEY (source_ID,guid) );"; dbDelta( $sql ); add_option( "awe_db_version", self::$db_version ); } /** * HTTP Redirection */ static public function redirect( $uri, $code=301 ) { // Specific URL $location = null; if (substr($uri,0,4)=='http') { $location = $uri; } else { $location = get_bloginfo('url'); // Special Trick, // starts at webserver root / starts at app root if (substr($uri,0,2) == '//') { $location .= '/' . ltrim($uri,'/'); } elseif (substr($uri,0,1) == '/') { $location .= '/' . ltrim($uri,'/'); } } switch ($code) { case 301: // Convert to GET header("301 Moved Permanently HTTP/1.1",true,$code); break; case 302: // Conform re-POST header("302 Found HTTP/1.1",true,$code); break; case 303: // dont cache, always use GET header("303 See Other HTTP/1.1",true,$code); break; case 304: // use cache header("304 Not Modified HTTP/1.1",true,$code); break; case 305: header("305 Use Proxy HTTP/1.1",true,$code); break; case 306: header("306 Not Used HTTP/1.1",true,$code); break; case 307: header("307 Temporary Redirect HTTP/1.1",true,$code); break; } //header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); header("Location: $location"); exit(0); } /** * Runs all of our hooks, filters, actions into WordPress * * @uses AWE::scandir_r() * @uses AWE::templates_to_hash() */ static function initialize() { self::$minify = false; self::$template_basepath = dirname( __FILE__ ).'/templates'; self::$templates = self::scandir_r( self::$template_basepath ); self::templates_to_hash( self::$templates ); // Allow video and audio tags global $allowedposttags; $allowedposttags["audio"] = array( "poster" => array(), "controls" => array(), "height" => array(), "width" => array() ); $allowedposttags["video"] = array( "poster" => array(), "controls" => array(), "height" => array(), "width" => array() ); $allowedposttags["source"] = array( "src" => array(), "type" => array() ); // Localization load_plugin_textdomain('awe', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); // Avoid confusion of features by turning off a few administration tabs. add_action('admin_menu', 'AWE::modify_admin_menus'); // Flush rewrite rules add_action('init', 'AWE::flush_rules'); // Add our new rewrite rules based on our configuration. add_action('generate_rewrite_rules', 'AWE::generate_rewrite_rules'); // Parse the request add_action('parse_request', 'AWE::parse_request'); // Parse the query add_action('parse_query', 'AWE::parse_query'); // Generate our http response add_action('template_redirect', 'AWE::response', 0); // Update hooks into our URI rewriting structure add_filter('query_vars', 'AWE::add_query_vars' ); // Add a widget to broadcast reblogs wp_register_sidebar_widget( 'awe-updates', 'Recent Reblogs', 'AWE::widget_display', array( 'description' => 'Shows latest reblogged posts' ) ); // Add a widget for popular reblogs sources wp_register_sidebar_widget( 'awe-updates-sources', 'Reblog Sources', 'AWE::widget_sources_display', array( 'description' => 'Shows piechart of most popular reblog sources' ) ); // Add widget headers add_action('widgets_init', 'AWE::widgets_init'); // AJAX add_action('wp_ajax_read_template_file', 'AWE::ajax_read_template_file'); add_action('wp_ajax_save_template_file', 'AWE::ajax_save_template_file'); add_action('wp_ajax_new_template_file', 'AWE::ajax_new_template_file'); add_action('wp_ajax_delete_template_file', 'AWE::ajax_delete_template_file'); add_action('wp_ajax_template_options', 'AWE::ajax_template_options'); add_action('wp_ajax_save_rules', 'AWE::ajax_save_rules'); add_action('wp_ajax_save_sources', 'AWE::ajax_save_sources'); add_action('wp_ajax_reader_paged', 'AWE::ajax_reader_paged'); add_action('wp_ajax_request_source', 'AWE::ajax_request_source'); add_action('wp_ajax_save_updates', 'AWE::ajax_save_updates'); } static function ajax_save_updates(){ global $wpdb; $updates = $_REQUEST['updates']; $source_id = $_REQUEST['source_id']; $sql = 'INSERT INTO '.AWE::reader_table().' ( guid, post_title, post_body, post_author, post_date, post_permalink ) VALUES '; $sql_values = array(); $sql_rel = 'INSERT IGNORE '.AWE::relationships_table().' (guid,source_ID) VALUES '; $sql_rel_values = array(); foreach ( $updates as $item ) { $body = stripslashes( $item['description'] ); $title = stripslashes( $item['title'] ); $author = stripslashes( $item['author'] ); // We keep the original GUID $guid = $item['id']; if ( strpos( $guid, 'http://' ) !== 0 && strpos( $guid, 'https://' ) !== 0 ) { // TODO: avoid duplicates.... We previously made the GUID WordPressized $old_guid = apply_filters('post_guid', $item['link'] ); } $sql_values[] = $wpdb->prepare("(%s,%s,%s,%s,%s,%s)", $guid, $title, $body, $author, $item['updated'], $item['link'] ); $sql_rel_values[] = $wpdb->prepare("(%s,%s)", $guid, $source_id ); } $sql .= implode(',', $sql_values).' ON DUPLICATE KEY UPDATE post_title=VALUES(post_title),post_body=VALUES(post_body),post_date=VALUES(post_date),post_permalink=VALUES(post_permalink);'; $sql_rel .= implode(',', $sql_rel_values).';'; $rows_affected = $wpdb->query( $sql ); $rows_rel_affected = $wpdb->query( $sql_rel ); exit(0); } static function ajax_request_source(){ $sources = AWE_Sources::get_sources(); if ( isset( $_REQUEST['source_id'] ) ) { $id = $_REQUEST['source_id']; if ( array_key_exists( $id, $sources ) ) { print wp_remote_retrieve_body( wp_remote_get( $sources[$id]['url'] ) ); } else { print json_encode( array( 'status' => false, 'message' => __("No source available with that id", 'awe') ) ); } } else { print json_encode( array( 'status' => false, 'message' => __("No source id specified", 'awe') ) ); } exit(); } static function ajax_reader_paged(){ if ( isset( $_REQUEST['source'] ) ) { $args['source_id'] = $_REQUEST['source']; } if ( isset( $_REQUEST['paged'] ) ) { $args['paged'] = $_REQUEST['paged']; } if ( isset( $_REQUEST['status'] ) ) { $args['status'] = $_REQUEST['status']; } $items = AWE_Update::query( $args ); foreach ( $items as $item ) { print AWE_Template::render( 'reader_item.php', array( 'item' => $item ) ); } exit(0); } static function widgets_init(){ if ( is_active_widget( false, false, 'awe-updates', true ) ) { wp_enqueue_style( 'recent-reblogs', plugins_url( '/static/awe/recent-reblogs.css', __FILE__ ) ); } } static public function feed_url( $type = 'rss2' ){ global $wp_rewrite; if ( $wp_rewrite->permalink_structure == '' ) { $url = get_bloginfo('url').'/?awefeed='.$type; } else { if ( $type = 'rss2' ) { $url = get_bloginfo('url').'/update/'; } else { $url = get_bloginfo('url').'/update/'.$type.'/'; } } return $url; } static function widget_display(){ print '
'; } static function widget_sources_display(){ wp_enqueue_script('jquery'); wp_enqueue_script('highcharts', plugins_url('/static/highcharts/highcharts.js', __FILE__)); wp_enqueue_script('highcharts', plugins_url('/static/highcharts/modules/exporting.js', __FILE__)); wp_enqueue_script('awe-sources-widget', plugins_url('/static/awe/widget-sources.js', __FILE__)); wp_enqueue_style('awe-sources-widget', plugins_url('/static/awe/widget-sources.css', __FILE__)); $stats = AWE_Sources::get_sources_percentages(); wp_localize_script('awe-sources-widget', 'sources_percentages', $stats); print ''; } /** * Additional action callback for the WordPress parse_request for dealing with 404 not found. */ static function parse_request( &$request ) { if ( isset( $request->query_vars['url'] ) ) { AWE::redirect( $request->query_vars['url'] ); exit(); } if( ( $request->matched_rule === NULL || $request->matched_rule == '' ) && strpos( $request->request, 'wp-admin' ) != 0 ) { header( "Status: 404 Not Found" ); print ''.$error.'
'.$message.'