├── msreader-files ├── views │ ├── dashboard-reader │ │ ├── content-page.php │ │ ├── 404.php │ │ ├── index.php │ │ ├── content-post.php │ │ ├── sidebar.php │ │ ├── content-single.php │ │ └── comments.php │ └── page-settings-network.php ├── languages │ └── default.mo ├── includes │ ├── modules │ │ ├── shortcode-recent-posts-grid │ │ │ ├── img │ │ │ │ └── controls.png │ │ │ ├── css │ │ │ │ ├── ajax-loader.gif │ │ │ │ ├── fonts │ │ │ │ │ ├── slick.eot │ │ │ │ │ ├── slick.ttf │ │ │ │ │ ├── slick.woff │ │ │ │ │ └── slick.svg │ │ │ │ ├── slick.css │ │ │ │ ├── slick-theme.css │ │ │ │ └── lightslider.min.css │ │ │ └── js │ │ │ │ └── lightslider.min.js │ │ ├── recent-posts.php │ │ ├── popular-posts.php │ │ ├── my-posts.php │ │ ├── my-sites.php │ │ ├── filter-blog-author.php │ │ ├── trending-tags.php │ │ ├── user-widget.php │ │ ├── search.php │ │ ├── widget-recent-posts.php │ │ ├── rss-feeds.php │ │ ├── featured-posts.php │ │ └── shortcode-recent-posts-grid.php │ ├── helpers.php │ ├── query.php │ └── modules.php ├── css │ ├── network-admin.css │ └── admin.css └── js │ └── network-admin.js ├── .gitmodules ├── changelog.txt └── README.md /msreader-files/views/dashboard-reader/content-page.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /msreader-files/languages/default.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/msreader/master/msreader-files/languages/default.mo -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dash-notice"] 2 | path = dash-notice 3 | url = git@bitbucket.org:incsub/wpmudev-dashboard-notification.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /msreader-files/views/dashboard-reader/404.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/img/controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/msreader/master/msreader-files/includes/modules/shortcode-recent-posts-grid/img/controls.png -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/msreader/master/msreader-files/includes/modules/shortcode-recent-posts-grid/css/ajax-loader.gif -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/msreader/master/msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.eot -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/msreader/master/msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.ttf -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wpmudev/msreader/master/msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.woff -------------------------------------------------------------------------------- /msreader-files/css/network-admin.css: -------------------------------------------------------------------------------- 1 | #msreader-control-modules label { 2 | line-height: 28px; 3 | } 4 | #msreader-control-modules .sub-options { 5 | display: none; 6 | } 7 | .msreader-control-module { 8 | margin: 5px 0; 9 | } 10 | #msreader-control-modules .sub-options .postbox { 11 | cursor: default; 12 | padding: 12px; 13 | margin: 0 0 5px 0; 14 | display: inline-block; 15 | } 16 | #msreader-control-modules button { 17 | outline: none; 18 | margin-bottom: 0 !important; 19 | } 20 | #msreader-control-modules button.active { 21 | -webkit-border-radius: 3px 3px 0 0; 22 | border-radius: 3px 3px 0 0; 23 | border-color:#e5e5e5; 24 | box-shadow: none; 25 | border-bottom: none; 26 | background: #fff; 27 | } -------------------------------------------------------------------------------- /msreader-files/js/network-admin.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | $(document).ready(function() { 3 | $('#msreader-page-name').on('input', function() { 4 | $('.reader-menu-page').text($(this).val()); 5 | }); 6 | 7 | $('#msreader-control-modules .open-module-options').click(function(event) { 8 | event.preventDefault(); 9 | 10 | var target = $(this).attr('data-module'); 11 | var position = $(this).position(); 12 | 13 | if($(this).hasClass('active')) { 14 | $('#msreader-control-modules .sub-options[data-module="'+target+'"]').hide(); 15 | $(this).removeClass('active'); 16 | } 17 | else { 18 | $('#msreader-control-modules .sub-options[data-module="'+target+'"]').show(); 19 | console.log(position); 20 | $('#msreader-control-modules .sub-options[data-module="'+target+'"] .postbox').css('min-width', position.left -150); 21 | $(this).addClass('active'); 22 | } 23 | }); 24 | }); 25 | })(jQuery); -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | Plugin Name: Reader 2 | Author: WPMUDEV 3 | Lead developer: Maniu 4 | 5 | == Changelog == 6 | 7 | = 1.2.6 = 8 | * Fixed list manager page not loading 9 | * Other small improvements 10 | 11 | = 1.2.5 = 12 | * Added new [reader-posts-grid] shortcode 13 | * Improved shortcode handling in reader posts 14 | * Other small improvements 15 | 16 | = 1.2 = 17 | * Added lists to easily group followed sites 18 | * Added user's private sites to post lists even when blocked 19 | * Improved cache system 20 | * Fixed comment moderation issue 21 | * Fixed translation issues 22 | 23 | = 1.1 = 24 | * Added widget to display reader content in sidebars 25 | * Added option for users to overwrite default Reader localization 26 | * Fixed problems related to media being in post excerpt 27 | * Other small improvements 28 | 29 | = 1.0.1 = 30 | * Added missing translation strings 31 | * Improved security 32 | 33 | = 1.0.0 = 34 | * Initial Release -------------------------------------------------------------------------------- /msreader-files/views/dashboard-reader/index.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |

5 | 6 | 7 | main_query->module->message) { 9 | $notification_class = $this->main_query->module->message_type ? 'updated' : 'error'; 10 | ?> 11 | 12 |
13 |

main_query->module->message; ?>

14 | 15 | 18 | 19 |
20 |
21 | 22 |
23 | 24 |
25 | 26 |
27 | 28 | 29 |
30 | <?php _e( 'Loading...', 'wmd_msreader' ); ?> 31 |
32 |
33 | 34 |
35 |
36 |
37 | 38 | -------------------------------------------------------------------------------- /msreader-files/includes/modules/recent-posts.php: -------------------------------------------------------------------------------- 1 | __( 'Recent Posts', 'wmd_msreader' ), 4 | 'description' => __( 'Displays recently added posts', 'wmd_msreader' ), 5 | 'slug' => 'recent_posts', 6 | 'class' => 'WMD_MSReader_Module_RecentPost', 7 | 'global_cache' => true, 8 | 'type' => 'query' 9 | ); 10 | 11 | class WMD_MSReader_Module_RecentPost extends WMD_MSReader_Modules { 12 | function init() { 13 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_link_to_widget'), 30 ); 14 | } 15 | 16 | function add_link_to_widget($widgets) { 17 | $widgets['reader']['data']['list'][$this->details['slug']] = $this->create_link_for_main_widget(); 18 | 19 | return $widgets; 20 | } 21 | 22 | function query() { 23 | global $wpdb; 24 | 25 | $limit = $this->get_limit(); 26 | $public = $this->get_public(); 27 | 28 | $query = " 29 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title 30 | FROM $this->db_network_posts AS posts 31 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 32 | WHERE $public blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 33 | AND post_status = 'publish' 34 | AND post_password = '' 35 | ORDER BY post_date_gmt DESC 36 | $limit 37 | "; 38 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $public); 39 | $posts = $wpdb->get_results($query); 40 | 41 | return $posts; 42 | } 43 | } -------------------------------------------------------------------------------- /msreader-files/views/dashboard-reader/content-post.php: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |

8 | featured_media_html) 10 | echo ''; 11 | ?> 12 |
13 | post_excerpt; ?> 14 |
15 |
16 | '. __( 'Read More', 'wmd_msreader' ) .'', 19 | $post); 20 | ?> 21 |
22 |
23 |
24 | 25 |
26 |
27 | post_author_avatar_html; ?> 28 | 29 |
30 | post_date_relative; ?> 31 | 32 | 33 | post_author_display_name, $post); ?> 34 |
35 | 36 | blog_details->blogname, 10), $post); ?> 37 |
38 |
39 |
40 |
-------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/fonts/slick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/slick.css: -------------------------------------------------------------------------------- 1 | /* Slider */ 2 | .slick-slider 3 | { 4 | position: relative; 5 | 6 | display: block; 7 | box-sizing: border-box; 8 | 9 | -webkit-user-select: none; 10 | -moz-user-select: none; 11 | -ms-user-select: none; 12 | user-select: none; 13 | 14 | -webkit-touch-callout: none; 15 | -khtml-user-select: none; 16 | -ms-touch-action: pan-y; 17 | touch-action: pan-y; 18 | -webkit-tap-highlight-color: transparent; 19 | } 20 | 21 | .slick-list 22 | { 23 | position: relative; 24 | 25 | display: block; 26 | overflow: hidden; 27 | 28 | margin: 0; 29 | padding: 0; 30 | } 31 | .slick-list:focus 32 | { 33 | outline: none; 34 | } 35 | .slick-list.dragging 36 | { 37 | cursor: pointer; 38 | cursor: hand; 39 | } 40 | 41 | .slick-slider .slick-track, 42 | .slick-slider .slick-list 43 | { 44 | -webkit-transform: translate3d(0, 0, 0); 45 | -moz-transform: translate3d(0, 0, 0); 46 | -ms-transform: translate3d(0, 0, 0); 47 | -o-transform: translate3d(0, 0, 0); 48 | transform: translate3d(0, 0, 0); 49 | } 50 | 51 | .slick-track 52 | { 53 | position: relative; 54 | top: 0; 55 | left: 0; 56 | 57 | display: block; 58 | } 59 | .slick-track:before, 60 | .slick-track:after 61 | { 62 | display: table; 63 | 64 | content: ''; 65 | } 66 | .slick-track:after 67 | { 68 | clear: both; 69 | } 70 | .slick-loading .slick-track 71 | { 72 | visibility: hidden; 73 | } 74 | 75 | .slick-slide 76 | { 77 | display: none; 78 | float: left; 79 | 80 | height: 100%; 81 | min-height: 1px; 82 | } 83 | [dir='rtl'] .slick-slide 84 | { 85 | float: right; 86 | } 87 | .slick-slide img 88 | { 89 | display: block; 90 | } 91 | .slick-slide.slick-loading img 92 | { 93 | display: none; 94 | } 95 | .slick-slide.dragging img 96 | { 97 | pointer-events: none; 98 | } 99 | .slick-initialized .slick-slide 100 | { 101 | display: block; 102 | } 103 | .slick-loading .slick-slide 104 | { 105 | visibility: hidden; 106 | } 107 | .slick-vertical .slick-slide 108 | { 109 | display: block; 110 | 111 | height: auto; 112 | 113 | border: 1px solid transparent; 114 | } 115 | .slick-arrow.slick-hidden { 116 | display: none; 117 | } 118 | -------------------------------------------------------------------------------- /msreader-files/includes/modules/popular-posts.php: -------------------------------------------------------------------------------- 1 | __( 'Popular Posts', 'wmd_msreader' ), 4 | 'description' => __( 'Displays popular posts', 'wmd_msreader' ), 5 | 'slug' => 'popular_posts', 6 | 'class' => 'WMD_MSReader_Module_PopularPost', 7 | 'global_cache' => true, 8 | 'default_options' => array( 9 | 'minimum_comment_count' => 5 10 | ), 11 | 'type' => 'query' 12 | ); 13 | 14 | class WMD_MSReader_Module_PopularPost extends WMD_MSReader_Modules { 15 | function init() { 16 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_link_to_widget'), 20 ); 17 | 18 | add_filter( 'msreader_module_options_'.$this->details['slug'], array($this,'add_options_html'), 10, 2 ); 19 | } 20 | 21 | function add_link_to_widget($widgets) { 22 | $widgets['reader']['data']['list'][$this->details['slug']] = $this->create_link_for_main_widget(); 23 | 24 | return $widgets; 25 | } 26 | 27 | function query() { 28 | global $wpdb; 29 | 30 | $limit = $this->get_limit(); 31 | $limit_sample = $this->get_limit($this->limit_sample,1); 32 | $public = $this->get_public(); 33 | 34 | $minimum_comment_count = $this->options['minimum_comment_count'] > 0 ? $this->options['minimum_comment_count']-1 : 0; 35 | 36 | $query = " 37 | SELECT BLOG_ID, ID, post_author, post_date_gmt, post_date, post_content, post_title, comment_count 38 | FROM ( 39 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title, comment_count 40 | FROM $this->db_network_posts AS posts 41 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 42 | WHERE $public blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 43 | AND post_status = 'publish' 44 | AND post_password = '' 45 | ORDER BY post_date_gmt DESC 46 | $limit_sample 47 | ) a 48 | WHERE comment_count > $minimum_comment_count 49 | ORDER BY post_date_gmt DESC 50 | $limit 51 | "; 52 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $public, $limit_sample, $minimum_comment_count); 53 | $posts = $wpdb->get_results($query); 54 | 55 | return $posts; 56 | } 57 | 58 | function add_options_html($blank, $options) { 59 | return ' 60 |
61 | 62 | '; 63 | } 64 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/my-posts.php: -------------------------------------------------------------------------------- 1 | __( 'My Posts', 'wmd_msreader' ), 4 | 'description' => __( 'Displays current users posts', 'wmd_msreader' ), 5 | 'slug' => 'my_posts', 6 | 'class' => 'WMD_MSReader_Module_MyPosts', 7 | 'type' => array('query', 'query-private') 8 | ); 9 | 10 | class WMD_MSReader_Module_MyPosts extends WMD_MSReader_Modules { 11 | function init() { 12 | if(!$this->helpers->is_module_enabled('user_widget')) 13 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_link_to_widget'), 40 ); 14 | else 15 | add_filter( 'msreader_user_widget_user_info', array($this,'add_my_posts_link_user_widget'),20,1); 16 | } 17 | 18 | function add_my_posts_link_user_widget($user_info) { 19 | $link = $this->get_module_dashboard_url('my_posts'); 20 | $active = ($this->helpers->is_page_link_active($link)) ? ' active' : ''; 21 | 22 | $current_user_id = get_current_user_id(); 23 | $user_info['main'] = array_slice($user_info['main'], 0, 1, true) + 24 | array("my_posts" => '
'.__( 'My Posts', 'wmd_msreader' ).'
') + 25 | array_slice($user_info['main'], 1, count($user_info['main'])-1, true); 26 | 27 | return $user_info; 28 | } 29 | 30 | function add_link_to_widget($widgets) { 31 | $widgets['reader']['data']['list'][$this->details['slug']] = $this->create_link_for_main_widget(); 32 | 33 | return $widgets; 34 | } 35 | 36 | function query() { 37 | global $wpdb; 38 | 39 | $current_user_id = $this->get_user(); 40 | $limit = $this->get_limit(); 41 | 42 | //get sites of current user 43 | $user_sites = get_blogs_of_user( $current_user_id ); 44 | $user_sites_ids = array(); 45 | foreach ($user_sites as $user_site) 46 | $user_sites_ids[] = $user_site->userblog_id; 47 | $user_sites_ids = implode(',', $user_sites_ids); 48 | 49 | $query = " 50 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title 51 | FROM $this->db_network_posts AS posts 52 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 53 | WHERE blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 54 | AND posts.BLOG_ID IN($user_sites_ids) 55 | AND post_author = $current_user_id 56 | AND post_status = 'publish' 57 | ORDER BY post_date_gmt DESC 58 | $limit 59 | "; 60 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $current_user_id, $user_sites_ids); 61 | $posts = $wpdb->get_results($query); 62 | 63 | return $posts; 64 | } 65 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/my-sites.php: -------------------------------------------------------------------------------- 1 | __( 'My Sites', 'wmd_msreader' ), 4 | 'description' => __( 'Displays posts from current users sites', 'wmd_msreader' ), 5 | 'slug' => 'my_sites', 6 | 'class' => 'WMD_MSReader_Module_MySites', 7 | 'type' => array('query', 'query-private') 8 | ); 9 | 10 | class WMD_MSReader_Module_MySites extends WMD_MSReader_Modules { 11 | function init() { 12 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_link_to_widget'), 50 ); 13 | add_filter( 'msreader_allowed_sites', array($this,'allowed_sites'), 10, 3 ); 14 | } 15 | 16 | function add_link_to_widget($widgets) { 17 | $widgets['reader']['data']['list'][$this->details['slug']] = $this->create_link_for_main_widget(); 18 | 19 | return $widgets; 20 | } 21 | 22 | function get_user_sites_ids() { 23 | $current_user_id = $this->get_user(); 24 | 25 | $user_sites = get_blogs_of_user($current_user_id); 26 | $user_sites_ids = array(); 27 | foreach ($user_sites as $user_site) 28 | $user_sites_ids[] = $user_site->userblog_id; 29 | 30 | return $user_sites_ids; 31 | } 32 | 33 | function query() { 34 | global $wpdb; 35 | 36 | $limit = $this->get_limit(); 37 | 38 | //get sites of current user 39 | $user_sites_ids = $this->get_user_sites_ids(); //results are safe for query 40 | 41 | if($user_sites_ids) { 42 | $user_sites_ids = implode(',', $user_sites_ids); 43 | 44 | $query = " 45 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title 46 | FROM $this->db_network_posts AS posts 47 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 48 | WHERE blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 49 | AND post_status = 'publish' 50 | AND post_password = '' 51 | AND posts.BLOG_ID IN($user_sites_ids) 52 | ORDER BY post_date_gmt DESC 53 | $limit 54 | "; 55 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $user_sites_ids); 56 | $posts = $wpdb->get_results($query); 57 | } 58 | else 59 | $posts = array(); 60 | 61 | return $posts; 62 | } 63 | function allowed_sites($filter, $args, $module) { 64 | if($this->helpers->is_public_only()) { 65 | //if something else already allowed all 66 | if($filter == 'all') 67 | return $filter; 68 | 69 | $user_sites_ids = $this->get_user_sites_ids(); 70 | 71 | if($module == 'filter_blog_author' && isset($args['blog_id']) && is_numeric($args['blog_id']) && in_array($args['blog_id'], $user_sites_ids)) 72 | $filter = 'all'; 73 | elseif( 74 | ($module == 'filter_blog_author' && isset($args['author_id']) && is_numeric($args['author_id'])) || 75 | $module == 'follow' || 76 | $module == 'private_comments' || 77 | $module == 'search' 78 | ) 79 | $filter = (is_array($filter)) ? array_merge($filter, $user_sites_ids) : $user_sites_ids; 80 | } 81 | 82 | return $filter; 83 | } 84 | } -------------------------------------------------------------------------------- /msreader-files/views/dashboard-reader/sidebar.php: -------------------------------------------------------------------------------- 1 | array( 7 | 'title' => apply_filters('msreader_dashboard_reader_sidebar_widget_reader_title', __('Reader', 'wmd_prettyplugins')), 8 | 'data' => array( 9 | 'links' => array() 10 | ) 11 | ) 12 | ) 13 | ); 14 | 15 | foreach ($sidebar_widgets as $slug => $details) { 16 | //open default styling 17 | $default_style = (!isset($details['default_style']) || (isset($details['default_style']) && $details['default_style'])) ? 1 : 0; 18 | if($default_style) { 19 | ?> 20 |
21 | '.$details['title'].'' : ''; ?> 22 | 26 |
27 | $content) { 33 | //echo as links if links 34 | if($type == 'list' && isset($content) && count($content) > 0) { 35 | echo '
    '; 36 | foreach ($content as $priority => $value) { 37 | if(!isset($value['title'])) 38 | continue; 39 | 40 | //check for active url so class can be added 41 | if(isset($value['link'])){ 42 | $link_query = parse_url($value['link']); 43 | $link_query = isset($link_query['query']) ? $link_query['query'] : ''; 44 | $link_args = array(); 45 | parse_str($link_query, $link_args); 46 | $default_module = apply_filters('msreader_default_module', $this->plugin['site_options']['default_module']); 47 | 48 | if(isset($_POST['current_url']) && !isset($_GET['module'])) { 49 | $parts = parse_url($_POST['current_url']); 50 | parse_str($parts['query'], $query); 51 | $current_module = isset($query['module']) ? $query['module'] : 0; 52 | } 53 | else 54 | $current_module = isset($_GET['module']) ? $_GET['module'] : 0; 55 | 56 | $link_classes = isset($value['link_classes']) ? ' class="'.(is_array($value['link_classes']) ? implode(' ', $value['link_classes']) : $value['link_classes']).'"' : ''; 57 | 58 | $active = ($this->helpers->is_page_link_active($value['link']) || ($link_args['module'] == $default_module && !$current_module)) ? ' class="active"' : ''; 59 | echo ''.(isset($value['before']) ? $value['before'] : '').''.$value['title'].''.(isset($value['after']) ? $value['after'] : '').''; 60 | } 61 | else 62 | echo '
  • '.(isset($value['before']) ? $value['before'] : '').$value['title'].(isset($value['after']) ? $value['after'] : '').'
  • '; 63 | } 64 | echo '
'; 65 | } 66 | //echo as html by default 67 | else 68 | echo $type == 'html' ? $content : ''; 69 | } 70 | elseif(isset($details['data'])) 71 | echo $details['data']; 72 | 73 | 74 | //close default styling 75 | if($default_style) { ?> 76 |
77 | 81 |
82 | '.sprintf(__('Change Reader settings', 'wmd_prettyplugins'), admin_url('network/settings.php?page=msreader.php')).'

'; 89 | -------------------------------------------------------------------------------- /msreader-files/includes/modules/filter-blog-author.php: -------------------------------------------------------------------------------- 1 | __( 'Filter by author or site', 'wmd_msreader' ), 4 | 'description' => __( 'Displays posts by selected author or site', 'wmd_msreader' ), 5 | 'slug' => 'filter_blog_author', 6 | 'class' => 'WMD_MSReader_Module_FilterBlogAuthor', 7 | 'can_be_default' => false, 8 | 'global_cache' => true, 9 | 'type' => array('query', 'query_args_required') 10 | ); 11 | 12 | class WMD_MSReader_Module_FilterBlogAuthor extends WMD_MSReader_Modules { 13 | function init() { 14 | add_filter('msreader_post_author', array($this,'add_author_link'),10,2); 15 | add_filter('msreader_post_blog', array($this,'add_blog_link'),10,2); 16 | 17 | add_filter('msreader_rss_feeds_extra_enable_feed', array($this,'add_module_slug_to_array'),10,1); 18 | add_filter('msreader_rss_feeds_enable_args', array($this,'add_module_slug_to_array'),10,1); 19 | } 20 | 21 | function add_author_link($name, $post) { 22 | return ''.$name.''; 23 | } 24 | 25 | function add_blog_link($name, $post) { 26 | return ''.$name.''; 27 | } 28 | 29 | function get_page_title() { 30 | $title = ''; 31 | if(isset($this->args['blog_id']) && is_numeric($this->args['blog_id'])) { 32 | $blog_details = get_blog_details($this->args['blog_id']); 33 | return __('Posts from:', 'wmd_msreader').' '.$blog_details->blogname.' '.__('Visit site', 'wmd_msreader').''; 34 | } 35 | elseif(isset($this->args['author_id']) && is_numeric($this->args['author_id'])) { 36 | $user_details = get_userdata( $this->args['author_id'] ); 37 | return __('Posts by:', 'wmd_msreader').' '.$user_details->display_name.''; 38 | } 39 | else 40 | return ''; 41 | } 42 | 43 | function query() { 44 | global $wpdb; 45 | 46 | $limit = $this->get_limit(); 47 | $public = $this->get_public(); 48 | 49 | $query = " 50 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title 51 | FROM $this->db_network_posts AS posts 52 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 53 | WHERE $public blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 54 | AND post_status = 'publish' 55 | AND post_password = '' 56 | "; 57 | 58 | if(!isset($this->args['blog_id']) && !isset($this->args['author_id'])) 59 | $query = ""; 60 | 61 | if(isset($this->args['blog_id']) && is_numeric($this->args['blog_id'])) 62 | $query .= $wpdb->prepare(" 63 | AND posts.BLOG_ID = %d 64 | ", $this->args['blog_id']); 65 | 66 | if(isset($this->args['author_id']) && is_numeric($this->args['author_id'])) 67 | $query .= $wpdb->prepare(" 68 | AND post_author = %d 69 | ", $this->args['author_id']); 70 | 71 | $query .= " 72 | ORDER BY post_date_gmt DESC 73 | $limit 74 | "; 75 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $public); 76 | $posts = $wpdb->get_results($query); 77 | 78 | return $posts; 79 | } 80 | } -------------------------------------------------------------------------------- /msreader-files/views/dashboard-reader/content-single.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 13 | 14 | 15 |
16 |
17 |
18 |

blog_details->blogname, $post); ?>

19 |

20 | 21 | 22 | 23 | 24 |

25 | 26 |
27 | 28 |
29 |
30 |
31 | $comments_limit) { ?> 32 |
33 | 34 | 35 |
36 | 37 |
38 | 39 |
40 |
41 | 42 |
43 | ID )) { ?> 44 |
45 |
46 |

47 | 48 | 49 |

50 |
51 |

52 | 53 |

54 |

55 | 56 | 57 | 58 | 59 | 60 |

61 |
62 | 63 |
64 | 65 |
66 | 67 |
68 |
-------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/slick-theme.css: -------------------------------------------------------------------------------- 1 | @charset 'UTF-8'; 2 | /* Slider */ 3 | .slick-loading .slick-list 4 | { 5 | background: #fff url('./ajax-loader.gif') center center no-repeat; 6 | } 7 | 8 | /* Icons */ 9 | @font-face 10 | { 11 | font-family: 'slick'; 12 | font-weight: normal; 13 | font-style: normal; 14 | 15 | src: url('./fonts/slick.eot'); 16 | src: url('./fonts/slick.eot?#iefix') format('embedded-opentype'), url('./fonts/slick.woff') format('woff'), url('./fonts/slick.ttf') format('truetype'), url('./fonts/slick.svg#slick') format('svg'); 17 | } 18 | /* Arrows */ 19 | .slick-prev, 20 | .slick-next 21 | { 22 | font-size: 0; 23 | line-height: 0; 24 | 25 | position: absolute; 26 | top: 50%; 27 | 28 | display: block; 29 | 30 | width: 20px; 31 | height: 20px; 32 | padding: 0; 33 | -webkit-transform: translate(0, -50%); 34 | -ms-transform: translate(0, -50%); 35 | transform: translate(0, -50%); 36 | 37 | cursor: pointer; 38 | 39 | color: transparent; 40 | border: none; 41 | outline: none; 42 | background: transparent; 43 | } 44 | .slick-prev:hover, 45 | .slick-prev:focus, 46 | .slick-next:hover, 47 | .slick-next:focus 48 | { 49 | color: transparent; 50 | outline: none; 51 | background: transparent; 52 | } 53 | .slick-prev:hover:before, 54 | .slick-prev:focus:before, 55 | .slick-next:hover:before, 56 | .slick-next:focus:before 57 | { 58 | opacity: 1; 59 | } 60 | .slick-prev.slick-disabled:before, 61 | .slick-next.slick-disabled:before 62 | { 63 | opacity: .25; 64 | } 65 | 66 | .slick-prev:before, 67 | .slick-next:before 68 | { 69 | font-family: 'slick'; 70 | font-size: 20px; 71 | line-height: 1; 72 | 73 | opacity: .75; 74 | color: white; 75 | 76 | -webkit-font-smoothing: antialiased; 77 | -moz-osx-font-smoothing: grayscale; 78 | } 79 | 80 | .slick-prev 81 | { 82 | left: -25px; 83 | } 84 | [dir='rtl'] .slick-prev 85 | { 86 | right: -25px; 87 | left: auto; 88 | } 89 | .slick-prev:before 90 | { 91 | content: '←'; 92 | } 93 | [dir='rtl'] .slick-prev:before 94 | { 95 | content: '→'; 96 | } 97 | 98 | .slick-next 99 | { 100 | right: -25px; 101 | } 102 | [dir='rtl'] .slick-next 103 | { 104 | right: auto; 105 | left: -25px; 106 | } 107 | .slick-next:before 108 | { 109 | content: '→'; 110 | } 111 | [dir='rtl'] .slick-next:before 112 | { 113 | content: '←'; 114 | } 115 | 116 | /* Dots */ 117 | .slick-dotted.slick-slider 118 | { 119 | margin-bottom: 30px; 120 | } 121 | 122 | .slick-dots 123 | { 124 | position: absolute; 125 | bottom: -25px; 126 | 127 | display: block; 128 | 129 | width: 100%; 130 | padding: 0; 131 | margin: 0; 132 | 133 | list-style: none; 134 | 135 | text-align: center; 136 | } 137 | .slick-dots li 138 | { 139 | position: relative; 140 | 141 | display: inline-block; 142 | 143 | width: 20px; 144 | height: 20px; 145 | margin: 0 5px; 146 | padding: 0; 147 | 148 | cursor: pointer; 149 | } 150 | .slick-dots li button 151 | { 152 | font-size: 0; 153 | line-height: 0; 154 | 155 | display: block; 156 | 157 | width: 20px; 158 | height: 20px; 159 | padding: 5px; 160 | 161 | cursor: pointer; 162 | 163 | color: transparent; 164 | border: 0; 165 | outline: none; 166 | background: transparent; 167 | } 168 | .slick-dots li button:hover, 169 | .slick-dots li button:focus 170 | { 171 | outline: none; 172 | } 173 | .slick-dots li button:hover:before, 174 | .slick-dots li button:focus:before 175 | { 176 | opacity: 1; 177 | } 178 | .slick-dots li button:before 179 | { 180 | font-family: 'slick'; 181 | font-size: 6px; 182 | line-height: 20px; 183 | 184 | position: absolute; 185 | top: 0; 186 | left: 0; 187 | 188 | width: 20px; 189 | height: 20px; 190 | 191 | content: '•'; 192 | text-align: center; 193 | 194 | opacity: .25; 195 | color: black; 196 | 197 | -webkit-font-smoothing: antialiased; 198 | -moz-osx-font-smoothing: grayscale; 199 | } 200 | .slick-dots li.slick-active button:before 201 | { 202 | opacity: .75; 203 | color: black; 204 | } 205 | -------------------------------------------------------------------------------- /msreader-files/views/dashboard-reader/comments.php: -------------------------------------------------------------------------------- 1 | "; 13 | else 14 | $output .= ""; 15 | } 16 | 17 | protected function html5_comment( $comment, $depth, $args ) { 18 | global $msreader_comment_level; 19 | 20 | $tag = ( 'div' === $args['style'] ) ? 'div' : 'li'; ?> 21 | < id="comment-" class="comment"> 22 |
23 | 36 | 37 |
38 | 39 |
40 |
41 | comment_post_ID)) { 43 | ?> 44 |
45 | 46 | comment_type ) { ?> 47 | 48 | comment_approved ) { ?> 49 | 50 | 51 | 52 | 53 | comment_type ) { ?> 54 | | 55 | | 56 | 57 | | 58 | 59 |
60 | $depth) ? $msreader_comment_level : $depth; 63 | if(comments_open( $comment->comment_post_ID ) && $depth < $args['max_depth'] && !('0' == $comment->comment_approved && !current_user_can('moderate_comments'))) { ?> 64 |
comment_approved) ? ' style="display:none"' : ''; ?>> 65 | 66 |
67 | 70 |
71 |
72 | 0) 80 | wp_list_comments( 81 | array( 82 | 'max_depth' => $depth, 83 | 'page' => $comments_page, 84 | 'per_page' => $comments_limit, 85 | 'reverse_top_level' => true, 86 | 'reverse_children' => true, 87 | 'format' => 'html5', 88 | 'walker' => new MSReader_Dashboard_Walker_Comment() 89 | ), 90 | $comments 91 | ); 92 | else { 93 | ?> 94 |
95 | 96 |
97 | -------------------------------------------------------------------------------- /msreader-files/includes/helpers.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 8 | } 9 | 10 | //plugin specific 11 | function is_module_enabled($slug, $options = 0) { 12 | $options = $options ? $options : $this->plugin['site_options']; 13 | return (isset($this->plugin['site_options']['modules']) && is_array($options['modules']) && array_key_exists($slug, $options['modules'])) || in_array($slug, apply_filters('msreader_activate_modules', array())) ? true : false; 14 | } 15 | 16 | //is public only 17 | function is_public_only() { 18 | return $this->plugin['site_options']['posts_from'] == 'public' ? true : false; 19 | } 20 | 21 | function get_default_module() { 22 | return apply_filters('msreader_default_module', $this->plugin['site_options']['default_module']); 23 | } 24 | 25 | //general 26 | function is_page_link_active($link, $soft = 0) { 27 | $link_query = parse_url($link); 28 | $link_query = isset($link_query['query']) ? $link_query['query'] : ''; 29 | if(isset($_POST['current_url'])) { 30 | $current_query = parse_url($_POST['current_url']); 31 | $current_query = isset($current_query['query']) ? $current_query['query'] : ''; 32 | } 33 | else 34 | $current_query = $_SERVER['QUERY_STRING']; 35 | if($soft && strpos($current_query, $link_query) !== false) 36 | return true; 37 | elseif($current_query == $link_query) 38 | return true; 39 | else 40 | return false; 41 | } 42 | function get_user_roles_per_blog($user_id) { 43 | global $wpdb; 44 | $msreader_edublogs_db_user_meta = $wpdb->base_prefix.'usermeta'; 45 | 46 | $query = $wpdb->prepare(" 47 | SELECT meta_key, meta_value 48 | FROM $msreader_edublogs_db_user_meta 49 | WHERE user_id = %d 50 | AND meta_key LIKE %s 51 | ", $user_id, 'wp%_capabilities'); 52 | $user_roles_prepare = $wpdb->get_results($query, ARRAY_A); 53 | 54 | $user_roles = array(); 55 | 56 | foreach ($user_roles_prepare as $user_role_prepare) { 57 | $blog_id = explode('_', $user_role_prepare['meta_key']); 58 | $blog_id = count($blog_id) > 2 ? $blog_id[1] : 1; 59 | 60 | $meta_value = maybe_unserialize($user_role_prepare['meta_value']); 61 | foreach ($meta_value as $role => $status) 62 | if($status == true) 63 | $user_roles[$blog_id][] = $role; 64 | }; 65 | 66 | return $user_roles; 67 | } 68 | 69 | function array_sort_by_sub_title($a, $b) { 70 | return strcmp($a['title'], $b['title']); 71 | } 72 | 73 | function the_select_options($array, $current, $echo = 1) { 74 | if(empty($array)) 75 | $array = array( 1 => __('True', 'wmd_msreader'), 0 => __('False', 'wmd_msreader') ); 76 | 77 | $return = ''; 78 | foreach( $array as $name => $label ) { 79 | $selected = selected( $current, $name, false ); 80 | $return .= ''; 81 | } 82 | 83 | if($echo) 84 | echo $return; 85 | else 86 | return $return; 87 | } 88 | 89 | function ensure_boolen($array) { 90 | $return = array(); 91 | 92 | foreach ( $array as $name => $element ) { 93 | if( $element == '1' || $element == '0' ) 94 | $return[$name] = (bool)$element; 95 | else 96 | $return[$name] = $element; 97 | } 98 | 99 | return $return; 100 | } 101 | 102 | function get_db_prefix() { 103 | global $wpdb; 104 | 105 | if ( !empty($wpdb->base_prefix) ) { 106 | $db_prefix = $wpdb->base_prefix; 107 | } else { 108 | $db_prefix = $wpdb->prefix; 109 | } 110 | 111 | return $db_prefix; 112 | } 113 | 114 | function write_log($message) { 115 | global $wmd_msreader; 116 | 117 | if(!$this->plugin['debug']) 118 | return false; 119 | 120 | $file = $this->plugin['dir'] . "/debug.log"; 121 | 122 | $handle = fopen( $file, 'ab' ); 123 | $data = date( "[Y-m-d H:i:s]" ) . $message . "\r\n"; 124 | @fwrite($handle, $data); 125 | @fclose($handle); 126 | } 127 | } 128 | 129 | //Compatibility with older PHP 130 | if (!function_exists('array_replace_recursive')) { 131 | function array_replace_recursive() { 132 | $arrays = func_get_args(); 133 | 134 | $original = array_shift($arrays); 135 | 136 | foreach ($arrays as $array) { 137 | foreach ($array as $key => $value) { 138 | if (is_array($value)) { 139 | $original[$key] = array_replace_recursive($original[$key], $array[$key]); 140 | } 141 | 142 | else { 143 | $original[$key] = $value; 144 | } 145 | } 146 | } 147 | 148 | return $original; 149 | } 150 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/css/lightslider.min.css: -------------------------------------------------------------------------------- 1 | /*! lightslider - v1.1.3 - 2015-04-14 2 | * https://github.com/sachinchoolur/lightslider 3 | * Copyright (c) 2015 Sachin N; Licensed MIT */.lSSlideWrapper,.lSSlideWrapper .lSFade{position:relative}.lSSlideWrapper .lSSlide,.lSSlideWrapper.usingCss .lSFade>*{-webkit-transition-timing-function:inherit!important;transition-timing-function:inherit!important;-webkit-transition-duration:inherit!important;transition-duration:inherit!important}.lSSlideOuter,.lSSlideOuter .lSPager.lSGallery{-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-user-select:none}.lSSlideOuter .lSPager.lSGallery:after,.lSSlideWrapper>.lightSlider:after{clear:both}.lSSlideOuter{overflow:hidden;user-select:none}.lightSlider:after,.lightSlider:before{content:" ";display:table}.lightSlider{overflow:hidden;margin:0}.lSSlideWrapper{max-width:100%;overflow:hidden}.lSSlideWrapper .lSSlide{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0);-webkit-transition:all 1s;-webkit-transition-property:-webkit-transform,height;-moz-transition-property:-moz-transform,height;transition-property:transform,height}.lSSlideWrapper .lSFade>*{position:absolute!important;top:0;left:0;z-index:9;margin-right:0;width:100%}.lSSlideWrapper.usingCss .lSFade>*{opacity:0;-webkit-transition-delay:0s;transition-delay:0s;-webkit-transition-property:opacity;transition-property:opacity}.lSSlideWrapper .lSFade>.active{z-index:10}.lSSlideWrapper.usingCss .lSFade>.active{opacity:1}.lSSlideOuter .lSPager.lSpg{margin:10px 0 0;padding:0;text-align:center}.lSSlideOuter .lSPager.lSpg>li{cursor:pointer;display:inline-block;padding:0 5px}.lSSlideOuter .lSPager.lSpg>li a{background-color:#222;border-radius:30px;display:inline-block;height:8px;overflow:hidden;text-indent:-999em;width:8px;position:relative;z-index:99;-webkit-transition:all .5s linear 0s;transition:all .5s linear 0s}.lSSlideOuter .lSPager.lSpg>li.active a,.lSSlideOuter .lSPager.lSpg>li:hover a{background-color:#428bca}.lSSlideOuter .media{opacity:.8}.lSSlideOuter .media.active{opacity:1}.lSSlideOuter .lSPager.lSGallery{list-style:none;padding-left:0;margin:0;overflow:hidden;transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;user-select:none}.lSSlideOuter .lSPager.lSGallery li{overflow:hidden;-webkit-transition:border-radius .12s linear 0s .35s linear 0s;transition:border-radius .12s linear 0s .35s linear 0s}.lSSlideOuter .lSPager.lSGallery li.active,.lSSlideOuter .lSPager.lSGallery li:hover{border-radius:5px}.lSSlideOuter .lSPager.lSGallery img{display:block;height:auto;max-width:100%}.lSSlideOuter .lSPager.lSGallery:after,.lSSlideOuter .lSPager.lSGallery:before{content:" ";display:table}.lSAction>a{width:32px;display:block;top:50%;height:32px;background-image:url(../img/controls.png);cursor:pointer;position:absolute;z-index:99;margin-top:-16px;opacity:.5;-webkit-transition:opacity .35s linear 0s;transition:opacity .35s linear 0s}.lSAction>a:hover{opacity:1}.lSAction>.lSPrev{background-position:0 0;left:10px}.lSAction>.lSNext{background-position:-32px 0;right:10px}.lSAction>a.disabled{pointer-events:none}.cS-hidden{height:1px;opacity:0;filter:alpha(opacity=0);overflow:hidden}.lSSlideOuter.vertical{position:relative}.lSSlideOuter.vertical.noPager{padding-right:0!important}.lSSlideOuter.vertical .lSGallery{position:absolute!important;right:0;top:0}.lSSlideOuter.vertical .lightSlider>*{width:100%!important;max-width:none!important}.lSSlideOuter.vertical .lSAction>a{left:50%;margin-left:-14px;margin-top:0}.lSSlideOuter.vertical .lSAction>.lSNext{background-position:31px -31px;bottom:10px;top:auto}.lSSlideOuter.vertical .lSAction>.lSPrev{background-position:0 -31px;bottom:auto;top:10px}.lSSlideOuter.lSrtl{direction:rtl}.lSSlideOuter .lSPager,.lSSlideOuter .lightSlider{padding-left:0;list-style:none}.lSSlideOuter.lSrtl .lSPager,.lSSlideOuter.lSrtl .lightSlider{padding-right:0}.lSSlideOuter .lSGallery li,.lSSlideOuter .lightSlider>*{float:left}.lSSlideOuter.lSrtl .lSGallery li,.lSSlideOuter.lSrtl .lightSlider>*{float:right!important}@-webkit-keyframes rightEnd{0%,100%{left:0}50%{left:-15px}}@keyframes rightEnd{0%,100%{left:0}50%{left:-15px}}@-webkit-keyframes topEnd{0%,100%{top:0}50%{top:-15px}}@keyframes topEnd{0%,100%{top:0}50%{top:-15px}}@-webkit-keyframes leftEnd{0%,100%{left:0}50%{left:15px}}@keyframes leftEnd{0%,100%{left:0}50%{left:15px}}@-webkit-keyframes bottomEnd{0%,100%{bottom:0}50%{bottom:-15px}}@keyframes bottomEnd{0%,100%{bottom:0}50%{bottom:-15px}}.lSSlideOuter .rightEnd{-webkit-animation:rightEnd .3s;animation:rightEnd .3s;position:relative}.lSSlideOuter .leftEnd{-webkit-animation:leftEnd .3s;animation:leftEnd .3s;position:relative}.lSSlideOuter.vertical .rightEnd{-webkit-animation:topEnd .3s;animation:topEnd .3s;position:relative}.lSSlideOuter.vertical .leftEnd{-webkit-animation:bottomEnd .3s;animation:bottomEnd .3s;position:relative}.lSSlideOuter.lSrtl .rightEnd{-webkit-animation:leftEnd .3s;animation:leftEnd .3s;position:relative}.lSSlideOuter.lSrtl .leftEnd{-webkit-animation:rightEnd .3s;animation:rightEnd .3s;position:relative}.lightSlider.lsGrab>*{cursor:-webkit-grab;cursor:-moz-grab;cursor:-o-grab;cursor:-ms-grab;cursor:grab}.lightSlider.lsGrabbing>*{cursor:move;cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:-o-grabbing;cursor:-ms-grabbing;cursor:grabbing} -------------------------------------------------------------------------------- /msreader-files/includes/modules/trending-tags.php: -------------------------------------------------------------------------------- 1 | __( 'Trending Tags', 'wmd_msreader' ), 4 | 'description' => __( 'Displays trending tags', 'wmd_msreader' ), 5 | 'slug' => 'trending_tags', 6 | 'class' => 'WMD_MSReader_Module_TrendingTags', 7 | 'can_be_default' => false, 8 | 'global_cache' => true, 9 | 'default_options' => array( 10 | 'widget_links_limit' => 5, 11 | 'widget_sample_limit' => 100 12 | ), 13 | 'type' => array('query', 'query_args_required') 14 | ); 15 | 16 | class WMD_MSReader_Module_TrendingTags extends WMD_MSReader_Modules { 17 | 18 | function init() { 19 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_widget'), 20 ); 20 | 21 | add_filter( 'msreader_module_options_'.$this->details['slug'], array($this,'add_options_html'), 10, 2 ); 22 | } 23 | 24 | function add_widget($widgets) { 25 | global $wpdb; 26 | 27 | $limit_sample = $this->get_limit($this->options['widget_sample_limit'], 1); 28 | $limit_links = $this->options['widget_links_limit']; 29 | $limit = $this->get_limit($limit_links, 1); 30 | 31 | $query_hash = md5($this->cache_init.$this->details['slug'].$limit_sample.$limit_links); 32 | $cache_group = 'msreader_global'; 33 | $top_tags = wp_cache_get('widget_'.$query_hash, $cache_group); 34 | 35 | if(!$top_tags) { 36 | $query = " 37 | SELECT id, slug, name, count(id) AS count 38 | FROM ( 39 | SELECT a.term_taxonomy_id AS id, c.slug AS slug, c.name AS name 40 | FROM $this->db_network_term_rel AS a 41 | INNER JOIN $this->db_network_term_tax AS b ON b.term_taxonomy_id = a.term_taxonomy_id 42 | INNER JOIN $this->db_network_terms AS c ON c.term_id = a.term_taxonomy_id 43 | INNER JOIN $this->db_network_posts AS d ON (a.blog_id = d.BLOG_ID AND a.object_id = d.ID) 44 | WHERE b.taxonomy = 'post_tag' 45 | ORDER BY d.post_date_gmt DESC 46 | $limit_sample 47 | ) a 48 | GROUP BY id 49 | ORDER BY count DESC 50 | $limit 51 | "; 52 | $query = apply_filters('msreader_'.$this->details['slug'].'_widget', $query, $this->args, $limit, $limit_sample); 53 | $top_tags = $wpdb->get_results($query, ARRAY_A); 54 | 55 | wp_cache_set('widget_'.$query_hash, $top_tags, $cache_group, 3600); 56 | } 57 | 58 | //prepare trending tags links 59 | $top_tags_ready = array(); 60 | foreach ($top_tags as $tag) 61 | $top_tags_ready[] = array('args' => $tag['id'],'title' => $tag['name']); 62 | 63 | if($top_tags_ready) 64 | $widgets['trending-tags'] = $this->create_list_widget($top_tags_ready); 65 | 66 | return $widgets; 67 | } 68 | 69 | function get_page_title() { 70 | global $wpdb; 71 | 72 | $tax_id = $this->args[0]; 73 | 74 | $query = $wpdb->prepare(" 75 | SELECT name 76 | FROM $this->db_network_terms 77 | WHERE term_id = %d 78 | LIMIT 1 79 | ", $tax_id); 80 | $query = apply_filters('msreader_'.$this->details['slug'].'_page_title', $query, $this->args, $tax_id); 81 | $tag = $wpdb->get_row($query, ARRAY_A); 82 | 83 | return $this->details['page_title'].': '.$tag['name'].''; 84 | } 85 | 86 | function query() { 87 | global $wpdb; 88 | 89 | $limit = $this->get_limit(); 90 | $public = $this->get_public(); 91 | $tax_id = $this->args[0]; 92 | 93 | $query = $wpdb->prepare(" 94 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title 95 | FROM $this->db_network_posts AS posts 96 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 97 | INNER JOIN $this->db_network_term_rel AS b ON (b.object_id = posts.ID AND b.blog_id = posts.BLOG_ID) 98 | WHERE $public blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 99 | AND post_status = 'publish' 100 | AND post_password = '' 101 | AND b.term_taxonomy_id = %d 102 | ORDER BY post_date_gmt DESC 103 | $limit 104 | ", $tax_id); 105 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $public, $tax_id); 106 | $posts = $wpdb->get_results($query); 107 | 108 | return $posts; 109 | } 110 | 111 | function add_options_html($blank, $options) { 112 | return ' 113 |
114 |
115 |
116 | 117 | '; 118 | } 119 | } -------------------------------------------------------------------------------- /msreader-files/views/page-settings-network.php: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |

5 |

6 |
7 | 8 | plugin['site_options']; 11 | 12 | do_settings_sections('wmd_msreader_options_general'); 13 | ?> 14 | 15 | 16 | 17 | 20 | 21 | 25 | 26 | 27 | 28 | 31 | 32 | 36 | 37 | 38 | 39 | 42 | 43 | 60 | 61 | 62 | 63 | 66 | 67 | 71 | 72 | 73 | 74 | 77 | 78 | 94 | 95 |
18 | 19 | 22 |
23 |
24 |
29 | 30 | 33 | 34 |

35 |
40 | 41 | 44 | available_modules as $slug => $module) { 46 | $current = $this->helpers->is_module_enabled($module['slug'], $this->plugin['site_options']) ? 'true' : 0; 47 | echo '
'; 48 | $module_options = isset($this->plugin['site_options']['modules_options'][$slug]) ? $this->plugin['site_options']['modules_options'][$slug] : array(); 49 | $module_options = apply_filters('msreader_module_options_'.$module['slug'], '', $module_options); 50 | if($module_options && count($this->plugin['site_options']['modules_options'][$slug])) { 51 | echo '
'; 52 | echo '
'.$module_options.'
'; 53 | } 54 | else 55 | echo '
'; 56 | echo '
'; 57 | } 58 | ?> 59 |
64 | 65 | 68 |
69 |
70 |
75 | 76 | 79 | '; 82 | foreach ($this->available_modules as $slug => $module) { 83 | if(isset($this->available_modules[$module['slug']]['can_be_default']) && $this->available_modules[$module['slug']]['can_be_default'] == false) 84 | continue; 85 | 86 | $display = !$this->helpers->is_module_enabled($module['slug']) ? ' style="display: none;"' : ''; 87 | echo ''; 88 | } 89 | echo ''; 90 | } 91 | ?> 92 |

93 |
96 | 97 |

98 | 99 |

100 |
101 | 102 |
-------------------------------------------------------------------------------- /msreader-files/includes/modules/user-widget.php: -------------------------------------------------------------------------------- 1 | __( 'User Info', 'wmd_msreader' ), 4 | 'description' => __( 'Displays additional information about current user in main reader page widget', 'wmd_msreader' ), 5 | 'slug' => 'user_widget', 6 | 'class' => 'WMD_MSReader_Module_UserWidget', 7 | 'can_be_default' => false, 8 | 'type' => 'reader-widget' 9 | ); 10 | 11 | class WMD_MSReader_Module_UserWidget extends WMD_MSReader_Modules { 12 | 13 | function init() { 14 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_widget'), 20 ); 15 | 16 | //add_action('save_post', array($this,'flush_user_post_count')); 17 | //add_action('delete_post', array($this,'flush_user_post_count')); 18 | 19 | add_action('admin_head', array( $this, "add_css" )); 20 | } 21 | 22 | function add_css() { 23 | if(is_admin()) { 24 | echo 25 | ''; 38 | } 39 | } 40 | 41 | function add_widget($widgets) { 42 | $current_user = wp_get_current_user(); 43 | $current_blog_id = get_current_blog_id(); 44 | $user_sites = get_blogs_of_user( $current_user->ID ); 45 | $primary_site = get_user_meta($current_user->ID, 'primary_blog', true); 46 | 47 | unset($widgets['reader']['title']); 48 | 49 | $user_site_url = isset($user_sites[$primary_site]) ? $user_sites[$primary_site]->siteurl : reset($user_sites)->siteurl; 50 | 51 | $user_info = array(); 52 | 53 | if(function_exists('avatars_page_edit_blog_avatar')) 54 | $user_info['main']['avatar'] = '
'.__( 'Change Avatar', 'wmd_msreader' ).'
'.get_avatar($current_user->ID, 48).'
'; 55 | else 56 | $user_info['main']['avatar'] = '
'.get_avatar($current_user->ID, 48).'
'; 57 | $user_info['main']['name'] = '

'.$current_user->display_name.'

'; 58 | 59 | //$user_info['main']['url'] = '
'.str_replace('https://', '', str_replace('http://', '', $user_site_url)).'
'; 60 | 61 | $user_info['stats']['my-sites'] = 62 | '

'.__( 'My Sites', 'wmd_msreader' ).'

63 |

'.count($user_sites).'

'; 64 | 65 | /* 66 | $user_info['stats']['my-posts'] = 67 | '

'.__( 'My Posts', 'wmd_msreader' ).'

68 |

'. $this->get_user_post_count($current_user->ID).'

'; 69 | */ 70 | 71 | $user_info = apply_filters('msreader_user_widget_user_info', $user_info); 72 | 73 | $content = '
'.implode('', $user_info['main']).'
'; 74 | 75 | $widgets['reader']['data'] = array_merge(array('html' => $content), $widgets['reader']['data']); 76 | 77 | return $widgets; 78 | } 79 | 80 | function get_user_post_count($user_id = 0) { 81 | global $wpdb; 82 | 83 | if(!$user_id) 84 | $user_id = get_current_user_id(); 85 | 86 | $user_post_count = wp_cache_get('user_post_count_'.$user_id, 'msreader_global'); 87 | 88 | if(!$user_post_count) { 89 | $query = " 90 | SELECT count(*) 91 | FROM $this->db_network_posts AS posts 92 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 93 | WHERE blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 94 | AND post_status = 'publish' 95 | AND post_password = '' 96 | AND post_author = $user_id 97 | "; 98 | $query = apply_filters('msreader_'.$this->details['slug'].'_user_post_count', $query, $this->args, $user_id); 99 | $user_post_count = $wpdb->get_var($query); 100 | 101 | wp_cache_set('user_post_count_'.$user_id, $user_post_count, 'msreader_global', 14400); 102 | } 103 | 104 | return $user_post_count; 105 | } 106 | function flush_user_post_count() { 107 | $user_id = get_current_user_id(); 108 | 109 | wp_cache_delete('user_post_count_'.$user_id, 'msreader_global'); 110 | } 111 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/search.php: -------------------------------------------------------------------------------- 1 | __( 'Search', 'wmd_msreader' ), 4 | 'description' => __( 'Allows to search posts by title, author or tag', 'wmd_msreader' ), 5 | 'slug' => 'search', 6 | 'class' => 'WMD_MSReader_Module_Search', 7 | 'can_be_default' => false, 8 | 'global_cache' => true, 9 | 'type' => array('query', 'query_args_required') 10 | ); 11 | 12 | class WMD_MSReader_Module_Search extends WMD_MSReader_Modules { 13 | 14 | function init() { 15 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_widget'), 5 ); 16 | add_action( 'admin_print_styles', array($this,'add_css')); 17 | 18 | add_filter('msreader_rss_feeds_extra_enable_feed', array($this,'add_module_slug_to_array'),10,1); 19 | add_filter('msreader_rss_feeds_enable_args', array($this,'add_module_slug_to_array'),10,1); 20 | } 21 | 22 | function add_css() { 23 | ?> 24 | 35 | args['search_author']) && !isset($this->args['search_tag']) && !isset($this->args['search_title'])) 40 | $this->args['search_title'] = 1; 41 | 42 | $search_value = isset($this->args['search_value']) ? esc_attr($this->args['search_value']) : ''; 43 | $search_html = ' 44 |
45 |

46 | 49 | 52 | 55 | 56 |

57 | '; 58 | 59 | $widget = array('search' => array( 60 | 'title' => $this->details['menu_title'], 61 | 'default_style' => 0, 62 | 'data' => array( 63 | 'html' => $search_html 64 | ) 65 | )); 66 | 67 | $widgets = array_merge($widget, $widgets); 68 | 69 | return $widgets; 70 | } 71 | 72 | function get_page_title() { 73 | return $this->details['page_title'].': '.esc_attr($this->args['search_value']).''; 74 | } 75 | 76 | function query() { 77 | global $wpdb; 78 | 79 | $blocked_words = apply_filters('msreader_'.$this->details['slug'].'_blocked_words', array()); 80 | $search_words = explode(' ', $this->args['search_value']); 81 | $blocked = 0; 82 | foreach ($search_words as $search_word) 83 | if(in_array(trim($search_word), $blocked_words)) { 84 | $blocked = 1; 85 | break; 86 | } 87 | 88 | if(!$blocked) { 89 | $limit = $this->get_limit(); 90 | $public = $this->get_public(); 91 | 92 | //set title search as default 93 | if(!isset($this->args['search_author']) && !isset($this->args['search_tag']) && !isset($this->args['search_title'])) 94 | $this->args['search_title'] = 1; 95 | 96 | $query = " 97 | SELECT posts.BLOG_ID AS BLOG_ID, posts.ID AS ID, post_author, post_date, post_date_gmt, post_content, post_title 98 | FROM $this->db_network_posts AS posts 99 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID"; 100 | if(isset($this->args['search_tag']) && $this->args['search_tag']) 101 | $query .= " 102 | LEFT JOIN $this->db_network_term_rel AS b ON (b.object_id = posts.ID AND b.blog_id = posts.BLOG_ID) 103 | LEFT JOIN $this->db_network_terms AS c ON (c.term_id = b.term_taxonomy_id)"; 104 | if(isset($this->args['search_author']) && $this->args['search_author']) 105 | $query .= " 106 | LEFT JOIN $this->db_users AS d ON (d.ID = posts.post_author)"; 107 | $query .= " 108 | WHERE $public blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 109 | AND post_status = 'publish' 110 | AND post_password = '' 111 | "; 112 | 113 | $where_search = array(); 114 | if(isset($this->args['search_title']) && $this->args['search_title']) { 115 | $where_search[] = $wpdb->prepare("posts.post_title LIKE %s", $this->args['search_value'].'%'); 116 | $where_search[] = $wpdb->prepare("posts.post_title LIKE %s", '% '.$this->args['search_value'].'%'); 117 | } 118 | if(isset($this->args['search_tag']) && $this->args['search_tag']) { 119 | $where_search[] = $wpdb->prepare("c.name LIKE %s", $this->args['search_value'].'%'); 120 | $where_search[] = $wpdb->prepare("c.name LIKE %s", '% '.$this->args['search_value'].'%'); 121 | } 122 | if(isset($this->args['search_author']) && $this->args['search_author']) { 123 | $where_search[] = $wpdb->prepare("d.display_name LIKE %s", $this->args['search_value'].'%'); 124 | $where_search[] = $wpdb->prepare("d.display_name LIKE %s", '% '.$this->args['search_value'].'%'); 125 | } 126 | 127 | $where_search = count($where_search) > 0 ? 'AND ('.implode(' OR ', $where_search).')' : ''; 128 | $query .= " 129 | $where_search 130 | ORDER BY post_date_gmt DESC 131 | $limit 132 | "; 133 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $public); 134 | $posts = $wpdb->get_results($query); 135 | } 136 | else 137 | $posts = 'error'; 138 | 139 | return $posts; 140 | } 141 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/widget-recent-posts.php: -------------------------------------------------------------------------------- 1 | __( 'Widget - Post List', 'wmd_msreader' ), 4 | 'description' => __( 'Allows usage of WordPress sidebar widget that displays latest posts', 'wmd_msreader' ), 5 | 'slug' => 'widget_recent_posts', 6 | 'class' => 'WMD_MSReader_Module_WidgetRecentPosts', 7 | 'can_be_default' => false, 8 | 'type' => 'wp-widget' 9 | ); 10 | 11 | class WMD_MSReader_Module_WidgetRecentPosts extends WMD_MSReader_Modules { 12 | 13 | function init() { 14 | add_action( 'widgets_init', create_function( '', 'return register_widget("wmd_msreader_post_list");' ) ); 15 | add_action('admin_footer-widgets.php', array($this,'add_js')); 16 | } 17 | 18 | function add_js() { 19 | ?> 20 | 34 | plugin['dir'].'includes/query.php'); 40 | 41 | extract( $args ); 42 | 43 | $title = isset($instance['title']) ? apply_filters( 'widget_title', $instance['title'] ) : ''; 44 | $number = (is_numeric($instance['number']) ) ? $instance['number'] : 7; 45 | $show_date = $instance['show_date'] == 'on' ? true : false; 46 | $show_excerpt = (isset($instance['show_excerpt']) && $instance['show_excerpt'] == 'on') ? true : false; 47 | $show_author = (isset($instance['show_author']) && $instance['show_author'] == 'on') ? true : false; 48 | 49 | $query = new WMD_MSReader_Query(); 50 | 51 | $arg_module = explode('|', $instance['module']); 52 | if(isset($arg_module[1])) { 53 | $instance['module'] = $arg_module[0]; 54 | $instance['args'] = array($arg_module[1]); 55 | } 56 | else 57 | $instance['args'] = array(); 58 | 59 | if(isset($wmd_msreader->modules[$instance['module']]) && isset($instance['user_id']) && $instance['user_id']) { 60 | $query->limit = $number; 61 | $query->user = $instance['user_id']; 62 | $query->args = $instance['args']; 63 | $query->load_module($wmd_msreader->modules[$instance['module']]); 64 | 65 | $posts = $query->get_posts(); 66 | 67 | if(is_array($posts) && count($posts) > 0) { 68 | if(isset($before_widget)) 69 | echo $before_widget; 70 | 71 | if(isset($title) && isset($before_title)) 72 | echo $before_title; 73 | 74 | if ( $title ) 75 | echo $title; 76 | if(isset($title) && isset($after_title)) 77 | echo $after_title; 78 | 79 | if(!isset($instance['remove_widget_class']) || !$instance['remove_widget_class']) 80 | echo '
'; 81 | echo ''; 107 | if(!isset($instance['remove_widget_class']) || !$instance['remove_widget_class']) 108 | echo '
'; 109 | if(isset($after_widget)) 110 | echo $after_widget; 111 | } 112 | } 113 | } 114 | } 115 | 116 | // Widget for Subscribe 117 | class wmd_msreader_post_list extends WP_Widget { 118 | //constructor 119 | function __construct() { 120 | $widget_ops = array( 'description' => __( 'List of most recent Reader related Posts', 'wmd_msreader') ); 121 | parent::__construct( false, __( 'Reader: Recent Posts', 'wmd_msreader' ), $widget_ops ); 122 | } 123 | 124 | /** @see WP_Widget::widget */ 125 | function widget( $args, $instance ) { 126 | global $msreader_modules; 127 | 128 | $msreader_modules['widget_recent_posts']->widget( $args, $instance ); 129 | } 130 | 131 | /** @see WP_Widget::update */ 132 | function update( $new_instance, $old_instance ) { 133 | $instance = $old_instance; 134 | $instance['title'] = strip_tags($new_instance['title']); 135 | $instance['number'] = strip_tags($new_instance['number']); 136 | $instance['number'] = $instance['number'] > 20 ? 20 : ($instance['number'] < 1 ? 1 : $instance['number']); 137 | $instance['show_date'] = strip_tags($new_instance['show_date']); 138 | $instance['show_excerpt'] = strip_tags($new_instance['show_excerpt']); 139 | $instance['show_author'] = strip_tags($new_instance['show_author']); 140 | $instance['module'] = strip_tags($new_instance['module']); 141 | if(!$instance['user_id']) 142 | $instance['user_id'] = get_current_user_id(); 143 | 144 | return $instance; 145 | } 146 | 147 | /** @see WP_Widget::form */ 148 | function form( $instance ) { 149 | global $msreader_helpers, $wmd_msreader; 150 | $options = $wmd_msreader->plugin['site_options']; 151 | 152 | $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : ''; 153 | $number = (isset( $instance['number'] ) && is_numeric($instance['number'])) ? esc_attr( $instance['number'] ) : 7; 154 | $show_date = isset( $instance['show_date'] ) ? esc_attr( $instance['show_date'] ) : ''; 155 | $show_excerpt = isset( $instance['show_excerpt'] ) ? esc_attr( $instance['show_excerpt'] ) : ''; 156 | $show_author = isset( $instance['show_author'] ) ? esc_attr( $instance['show_author'] ) : ''; 157 | $current_module = isset( $instance['module'] ) ? esc_attr( $instance['module'] ) : ''; 158 | 159 | $user_id = (isset($instance['user_id']) && $instance['user_id']) ? $instance['user_id'] : get_current_user_id(); 160 | $user_name = get_userdata($user_id); 161 | $user_name = $user_name->user_login; 162 | ?> 163 |
164 |

165 | 166 | 167 |

168 |

169 | 170 | 171 |

172 |

173 | > 174 | 175 |

176 |

177 | > 178 | 179 |

180 |

181 | > 182 | 183 |

184 |

185 | 186 | get_field_id( 'module' ).'" class="msreader_widget_recent_posts_select" name="'.$this->get_field_name( 'module' ).'">'; 191 | foreach ($wmd_msreader->modules as $slug => $module) { 192 | if(in_array('query', $module->details['type']) && !in_array('query_args_required', $module->details['type']) && !in_array($module->details['slug'], $blocked_modules)) { 193 | $module_title = isset($module->details['menu_title']) ? $module->details['menu_title'] : $module->details['name']; 194 | 195 | echo ''; 196 | } 197 | } 198 | 199 | $arg_modules = apply_filters('msreader_widget_recent_posts_arg_modules', array()); 200 | foreach ($arg_modules as $key => $arg_module_details) { 201 | echo ''; 202 | } 203 | echo ''; 204 | } 205 | ?> 206 |
207 | . 208 |

209 |

210 | 211 |

212 |
213 | ul, 510 | .comment-content li > ol { 511 | margin-bottom: 0; 512 | } 513 | 514 | .comment-content > :last-child { 515 | margin-bottom: 0; 516 | } 517 | 518 | .comments .children { 519 | list-style: none; 520 | margin: 0 0 0 35px; 521 | } 522 | 523 | .comment-respond { 524 | margin-bottom: 24px; 525 | padding: 0; 526 | } 527 | 528 | .comment .comment-respond { 529 | margin-top: 24px; 530 | } 531 | 532 | .comment-respond h3 { 533 | margin-top: 0; 534 | margin-bottom: 24px; 535 | } 536 | 537 | .comment-notes, 538 | .comment-awaiting-moderation, 539 | .logged-in-as { 540 | font-size: 14px; 541 | line-height: 1.7142857142; 542 | } 543 | 544 | .msreader-add-comment h4 { 545 | font-size: 1.1em; 546 | margin: 0; 547 | min-height: 42px; 548 | } 549 | .msreader-add-comment h4 small { 550 | font-weight: normal; 551 | margin-left: 5px; 552 | } 553 | .msreader-add-comment h4 small.disabled { 554 | color: #727272; 555 | } 556 | .msreader-add-comment h4 small.disabled label { 557 | cursor: default; 558 | } 559 | 560 | .msreader-add-comment .reply-info a { 561 | text-decoration: none; 562 | } 563 | 564 | /*EASY BLOGGING COMPATIBILITY*/ 565 | #wdeb-mode .msreader-rss-feeds-link, #wdeb-mode .msreader-rss-feeds-box, #wdeb-mode .msreader-follow-icon, #wdeb-mode #msreader-dashboard .current-text, #wdeb-mode .msreader-post-overlay .current-text, #wdeb-mode #msreader-dashboard .user-info { 566 | display: none; 567 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/rss-feeds.php: -------------------------------------------------------------------------------- 1 | __( 'RSS Feeds', 'wmd_msreader' ), 4 | 'description' => __( 'Allows users to get links for all post lists available in Reader', 'wmd_msreader' ), 5 | 'slug' => 'rss_feeds', 6 | 'class' => 'WMD_MSReader_Module_RssFeeds', 7 | 'can_be_default' => false, 8 | 'type' => 'other' 9 | ); 10 | 11 | class WMD_MSReader_Module_RssFeeds extends WMD_MSReader_Modules { 12 | 13 | function init() { 14 | if(isset($_GET['msreader_'.$this->details['slug']]) && $_GET['msreader_'.$this->details['slug']] == 'view' && isset($_GET['key']) && isset($_GET['module'])) { 15 | add_action('msreader_before_main_query_load_module', array( $this, "set_current_user" ), 15); 16 | add_filter('msreader_requested', '__return_true'); 17 | add_filter('msreader_query_limit_default', array( $this, "msreader_query_limit_default")); 18 | add_action('init', array( $this, "display_rss" ), 15); 19 | } 20 | 21 | add_filter('msreader_dashboard_page_title', array( $this, "add_rss_icon" ), 50, 1 ); 22 | add_action( 'admin_head', array( $this, "add_css_js" ) ); 23 | add_action('msreader_dashboard_after_page_title', array( $this, "add_rss_info_box" ), 5); 24 | 25 | add_action( 'wp_ajax_dashboard_get_rss_feed_link', array($this, 'get_rss_feed_link'), 20 ); 26 | } 27 | 28 | function msreader_query_limit_default($current) { 29 | return 25; 30 | } 31 | 32 | function add_rss_icon($current_title) { 33 | global $msreader_main_query; 34 | 35 | $blocked_modules = apply_filters('msreader_rss_feeds_blocked_modules', array()); 36 | 37 | if(in_array('query', $msreader_main_query->module->details['type']) && !in_array($msreader_main_query->module->details['slug'], $blocked_modules)) 38 | $current_title = $current_title.''; 39 | 40 | return $current_title; 41 | } 42 | 43 | function add_rss_info_box() { 44 | global $msreader_main_query; 45 | 46 | $blocked_modules = apply_filters('msreader_rss_feeds_blocked_modules', array()); 47 | 48 | if(in_array('query', $msreader_main_query->module->details['type']) && !in_array($msreader_main_query->module->details['slug'], $blocked_modules)) { 49 | $feed_url = $this->get_rss_feed_link(0); 50 | ?> 51 | 52 |
53 | 54 | 55 | 56 |
57 |

module->get_page_title(); ?>

58 |

59 | 60 |

61 |

62 | 63 | here.', 'wmd_msreader'); ?> 64 |

65 |
66 |
67 | 68 | 75 | .msreader-rss-feeds-link {background: #FE9900; color: #fff; padding: 1px; margin: 4px 0 0 15px; box-shadow: 0 1px 1px rgba(0,0,0,.04); border: 1px solid #e5e5e5; width: auto; height: auto;} 76 | .msreader-rss-feeds-link:hover, .msreader-rss-feeds-link.active {background: #ffbf00; color: #fff;} 77 | .msreader-rss-feeds-box {background: #fffaf2; display: none;} 78 | .msreader-rss-feeds-box input {width:92%;} 79 | .msreader-rss-feeds-box-close {position: absolute; right: 10px; top: 10px; z-index: 10;} 80 | '; 81 | ?> 82 | 83 | 161 | 162 | get_var($wpdb->prepare("SELECT user_id FROM $wpdb->usermeta where meta_key = 'msreader_rss_feeds_key' AND meta_value = %s", $_GET['key'])); 169 | 170 | if($user_id) 171 | $msreader_main_query->user = $user_id; 172 | else 173 | exit(); 174 | } 175 | 176 | function display_rss() { 177 | error_reporting(0); 178 | global $msreader_main_query; 179 | 180 | $posts = $msreader_main_query->get_posts(); 181 | 182 | header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true); 183 | echo ''; ?> 184 | 185 | 200 | > 201 | 202 | 203 | <?php echo __('Reader','wmd_msreader'); echo ': '.$msreader_main_query->module->details['name'].' - '; bloginfo_rss('name'); ?> 204 | module->details['name'].' - '; bloginfo_rss('name'); ?> 205 | 206 | get_user(), 'primary_blog', true), 'index.php?page=msreader.php'); ?> 207 | post_date) ? $posts[0]->post_date : '', false); ?> 208 | 209 | 210 | 218 | 219 | <?php the_title_rss() ?> 220 | get_site_post_link($post->BLOG_ID, $post->ID); ?> 221 | 222 | ]]> 223 | 224 | 225 | 226 | ', ']]>', $post->post_excerpt); ?>]]> 227 | 235 | 236 | 237 | 238 | 239 | 240 | args['module'])) 250 | $module = $this->args['module']; 251 | else { 252 | global $msreader_main_query; 253 | $module = $msreader_main_query->module->details['slug']; 254 | } 255 | 256 | $generate = (isset($this->args['generate']) && $this->args['generate']) ? 1 : $generate; 257 | $regenerate = (isset($this->args['regenerate']) && $this->args['regenerate']) ? 1 : $regenerate; 258 | 259 | $user_id = get_current_user_id(); 260 | 261 | $user_feed_key = get_user_meta($user_id, 'msreader_rss_feeds_key', true); 262 | if((empty($user_feed_key) && $generate) || $regenerate) { 263 | $user_id = get_current_user_id(); 264 | $user_data = get_userdata($user_id); 265 | 266 | $user_feed_key = md5(uniqid().$user_data->user_email); 267 | 268 | update_user_meta( $user_id, 'msreader_rss_feeds_key', $user_feed_key ); 269 | } 270 | 271 | if($user_feed_key) { 272 | if($regenerate) { 273 | $feed_link_args = array('key' => $user_feed_key); 274 | 275 | $initial_url = $this->args['initial_url']; 276 | } 277 | else { 278 | if(isset($this->args['args']) && count($this->args['args'])) 279 | $module_args = $this->args['args']; 280 | elseif(isset($msreader_main_query->module->args) && count($msreader_main_query->module->args)) 281 | $module_args = $msreader_main_query->module->args; 282 | 283 | $feed_link_args = array( 284 | 'module' => $module, 285 | 'key' => $user_feed_key, 286 | 'msreader_rss_feeds' => 'view' 287 | ); 288 | if(isset($module_args)) 289 | $feed_link_args['args'] = $module_args; 290 | 291 | $initial_url = site_url(); 292 | } 293 | 294 | $feed_link = add_query_arg($feed_link_args, $initial_url); 295 | } 296 | else 297 | $feed_link = ''; 298 | 299 | if(defined('DOING_AJAX')) { 300 | echo $feed_link; 301 | die(); 302 | } 303 | else 304 | return $feed_link; 305 | } 306 | } -------------------------------------------------------------------------------- /msreader-files/includes/query.php: -------------------------------------------------------------------------------- 1 | limit = apply_filters('msreader_query_limit_default', $this->limit); 27 | $this->limit_sample = apply_filters('msreader_query_limit_sample_default', $this->limit_sample); 28 | 29 | //set initial last date as right now 30 | $this->last_date = time(); 31 | } 32 | 33 | function load_module($module, $is_main_query = 0) { 34 | //load module 35 | $this->module = $module; 36 | 37 | //pass parameters to module 38 | $this->module->main = $is_main_query ? 1 : 0; 39 | $this->module->page = $this->page; 40 | $this->module->limit = $this->limit; 41 | $this->module->limit_sample = $this->limit_sample; 42 | $this->module->args = $this->args; 43 | $this->module->last_date = $this->last_date; 44 | $this->module->user = ($this->user && is_numeric($this->user)) ? $this->user : get_current_user_id(); 45 | $this->module->blog = ($this->blog && is_numeric($this->blog)) ? $this->blog : get_current_blog_id(); 46 | 47 | $this->module->load_module(); 48 | 49 | //check if its a query used by everybody 50 | $store_user_id = !$this->module->details['global_cache'] ? $this->module->user : ''; 51 | //check if its a query related to currently displayed blog 52 | $store_blog_id = $this->module->details['blog_specific_cache'] ? $this->module->blog : ''; 53 | //set up secret code for query 54 | $this->module->query_hashes['get_posts'] = md5($this->module->cache_init.$this->module->details['slug'].$this->page.$this->limit.http_build_query($this->args).$store_user_id.$store_blog_id); 55 | } 56 | 57 | function get_query_details() { 58 | return array( 59 | 'page_title' => $this->module->get_page_title() 60 | ); 61 | } 62 | 63 | function get_posts() { 64 | $posts = array(); 65 | 66 | if($this->module) { 67 | 68 | $query_prefix = apply_filters('msreader_query_prefix', 'query'); 69 | 70 | //lets load 71 | $posts = (!$this->module->details['disable_cache']) ? wp_cache_get($query_prefix.'_'.$this->module->query_hashes['get_posts'], 'msreader_global') : 0; 72 | if(!$posts) { 73 | $blog_details = array(); 74 | 75 | $posts = $this->module->query(); 76 | 77 | //get some additional details for posts 78 | $posts = $this->set_additional_posts_data($posts, $blog_details); 79 | 80 | if(!$this->module->details['disable_cache']) 81 | wp_cache_set($query_prefix.'_'.$this->module->query_hashes['get_posts'], $posts, 'msreader_global', $this->module->details['cache_time'] ? $this->module->details['cache_time'] : 900); 82 | } 83 | 84 | $posts = $this->set_additional_posts_data_dynamic($posts); 85 | } 86 | 87 | return $posts; 88 | } 89 | 90 | function get_posts_count() { 91 | $count = 0; 92 | 93 | if($this->module) { 94 | if(!$this->module->details['allow_count']) 95 | return false; 96 | 97 | $query_prefix = apply_filters('msreader_query_count_prefix', 'query_count'); 98 | 99 | //lets load 100 | $count = (!$this->module->details['disable_cache']) ? wp_cache_get($query_prefix.'_'.$this->module->query_hashes['get_posts'], 'msreader_global') : 0; 101 | 102 | if(!$count) { 103 | $count = $this->module->query(true); 104 | 105 | if(!$this->module->details['disable_cache']) 106 | wp_cache_set($query_prefix.'_'.$this->module->query_hashes['get_posts'], $count, 'msreader_global', $this->module->details['cache_time'] ? $this->module->details['cache_time'] : 900); 107 | } 108 | } 109 | 110 | return $count; 111 | } 112 | 113 | function get_post() { 114 | if($this->blog_id && $this->post_id) { 115 | if(get_current_blog_id() != $this->blog_id) { 116 | $restore = 1; 117 | switch_to_blog($this->blog_id); 118 | } 119 | 120 | $post = get_post($this->post_id); 121 | $post = array($post); 122 | $post = $this->set_additional_posts_data($post); 123 | $post = $this->set_additional_posts_data_dynamic($post); 124 | 125 | return $post[0]; 126 | 127 | if(isset($restore)) 128 | restore_current_blog(); 129 | } 130 | } 131 | 132 | function publish_post() { 133 | if($this->blog_id && $this->post_id) { 134 | if(get_current_blog_id() != $this->blog_id) { 135 | $restore = 1; 136 | switch_to_blog($this->blog_id); 137 | } 138 | 139 | if(current_user_can('publish_posts')) { 140 | //i changed it to update but it is not triggering functions then i changed it back to wp publish but now it may cause title issue 141 | wp_update_post( array('ID' => $this->post_id, 'post_status' => 'publish') ); 142 | //wp_publish_post( $this->post_id ); 143 | $status = true; 144 | do_action('msreader_publish_post'); 145 | } 146 | else 147 | $status = false; 148 | 149 | 150 | if(isset($restore)) 151 | restore_current_blog(); 152 | 153 | return $status; 154 | } 155 | } 156 | 157 | function get_comments() { 158 | if($this->blog_id && $this->post_id) { 159 | if(get_current_blog_id() != $this->blog_id) { 160 | $restore = 1; 161 | switch_to_blog($this->blog_id); 162 | } 163 | 164 | $default_args = array( 165 | 'order' => 'DESC', 166 | 'post_id' => $this->post_id, 167 | 'number' => 999 168 | ); 169 | 170 | if(!isset($this->comments_args['number']) && isset($this->comments_args['ID'])) 171 | $this->comments_args['number'] = 1; 172 | 173 | $args = apply_filters('msreader_query_get_comments_args', array_merge($default_args, $this->comments_args)); 174 | 175 | $comments = get_comments($args); 176 | 177 | //add fake comments if we removed some for pagination to be correct - we should fix it by searching by date 178 | if(isset($this->comments_args['comments_removed']) && $this->comments_args['comments_removed'] > 0) { 179 | for($i =0; $i < $this->comments_args['comments_removed']; $i++){ 180 | $comments = array_merge(array($comments[0]), $comments); 181 | } 182 | } 183 | 184 | if(isset($restore)) 185 | restore_current_blog(); 186 | 187 | return $comments; 188 | } 189 | } 190 | 191 | function add_comment() { 192 | if($this->blog_id && $this->post_id) { 193 | if(get_current_blog_id() != $this->blog_id) { 194 | $restore = 1; 195 | switch_to_blog($this->blog_id); 196 | } 197 | 198 | $comment_post_ID = $this->post_id; 199 | 200 | $post = get_post($comment_post_ID); 201 | 202 | if ( empty( $post->comment_status ) ) { 203 | do_action( 'comment_id_not_found', $comment_post_ID ); 204 | return false; 205 | } 206 | 207 | $status = get_post_status($post); 208 | 209 | $status_obj = get_post_status_object($status); 210 | 211 | $comments_closed = ( ! comments_open( $comment_post_ID ) || 'trash' == $status || (! $status_obj->public && ! $status_obj->private) || post_password_required( $comment_post_ID ) ) ? true : false; 212 | if($comments_closed && !current_user_can('edit_post', $post->ID)) 213 | return false; 214 | 215 | do_action( 'pre_comment_on_post', $comment_post_ID ); 216 | 217 | $comment_content = isset($this->comment_add_data['comment']) ? trim($this->comment_add_data['comment']) : null; 218 | if ( '' == $comment_content ) 219 | return false; 220 | 221 | $comment_parent = isset($this->comment_add_data['comment_parent']) ? absint($this->comment_add_data['comment_parent']) : 0; 222 | $comment_type = (isset($this->comment_add_data['private']) && !empty($this->comment_add_data['private'])) ? 'private' : ''; 223 | if($comment_parent) { 224 | $comment_parent_comment = get_comment($comment_parent); 225 | if($comment_parent_comment->comment_approved == 'private') 226 | $comment_type = 'private'; 227 | } 228 | 229 | 230 | 231 | // If the user is logged in 232 | $user = wp_get_current_user(); 233 | if ( $user->exists() ) { 234 | $user_id = $user->ID; 235 | if ( empty( $user->display_name ) ) 236 | $user->display_name = $user->user_login; 237 | $comment_author = wp_slash( $user->display_name ); 238 | $comment_author_email = wp_slash( $user->user_email ); 239 | $comment_author_url = wp_slash( $user->user_url ); 240 | } 241 | 242 | $commentdata = compact('comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'comment_parent', 'user_id'); 243 | if($comment_type != 'private' && !$comments_closed) 244 | $comment_id = wp_new_comment( $commentdata ); 245 | else { 246 | $commentdata['comment_approved'] = 'private'; 247 | $comment_id = wp_insert_comment( $commentdata ); 248 | do_action( 'comment_post', $comment_id, $commentdata['comment_approved'] ); 249 | } 250 | 251 | 252 | if(isset($restore)) 253 | restore_current_blog(); 254 | 255 | return $comment_id; 256 | } 257 | } 258 | 259 | function moderate_comment() { 260 | if($this->blog_id && $this->post_id) { 261 | if(get_current_blog_id() != $this->blog_id) { 262 | $restore = 1; 263 | switch_to_blog($this->blog_id); 264 | } 265 | 266 | $status = $this->moderate_comment_action($this->comment_moderate_data['action'], $this->comment_moderate_data['comment_id'], $this->post_id); 267 | 268 | if(isset($restore)) 269 | restore_current_blog(); 270 | 271 | return $status; 272 | } 273 | 274 | return 0; 275 | } 276 | 277 | //Helpers 278 | 279 | //set additional details for post 280 | function set_additional_posts_data($posts, $blog_details = array()) { 281 | if(is_array($posts)) { 282 | $posts = apply_filters('msreader_set_additional_posts_data_before', $posts, $this->module); 283 | 284 | foreach ($posts as $key => $post) { 285 | if($post) { 286 | $posts[$key] = apply_filters('msreader_set_additional_post_data_before', $post, $this->module); 287 | 288 | $posts[$key]->post_title = stripslashes($post->post_title); 289 | $posts[$key]->post_content = stripslashes($post->post_content); 290 | 291 | //get blog details 292 | if(!isset($post->BLOG_ID)) 293 | $posts[$key]->BLOG_ID = get_current_blog_id(); 294 | if(!isset($blog_details[$post->BLOG_ID])) 295 | $blog_details[$post->BLOG_ID] = get_blog_details($post->BLOG_ID); 296 | $posts[$key]->blog_details = $blog_details[$post->BLOG_ID]; 297 | 298 | //set featured image 299 | $posts[$key]->featured_media_html = $this->module->get_featured_media_html($post); 300 | 301 | //change excerpt 302 | $posts[$key]->post_excerpt = $this->module->get_excerpt($post); 303 | 304 | //user details 305 | $posts[$key]->post_author_display_name = get_the_author_meta( 'display_name', $post->post_author ); 306 | $posts[$key]->post_author_avatar_html = get_avatar($post->post_author, 48); 307 | 308 | $posts = apply_filters('msreader_set_additional_post_data_after', $posts, $this->module); 309 | } 310 | } 311 | 312 | $posts = apply_filters('msreader_set_additional_posts_data_after', $posts, $this->module); 313 | } 314 | 315 | return $posts; 316 | } 317 | 318 | //set additional details for post that cant be cached 319 | function set_additional_posts_data_dynamic($posts) { 320 | if(is_array($posts)) { 321 | $posts = apply_filters('msreader_set_additional_posts_data_dynamic_before', $posts, $this->module); 322 | 323 | foreach ($posts as $key => $post) { 324 | if($post) { 325 | $posts[$key] = apply_filters('msreader_set_additional_post_data_dynamic_before', $post, $this->module); 326 | 327 | $time = strtotime($post->post_date_gmt) ? $post->post_date_gmt : $post->post_date; 328 | $posts[$key]->post_date_relative = human_time_diff( strtotime($time), time() ); 329 | $posts[$key]->post_date_stamp = strtotime($post->post_date_gmt); 330 | 331 | $posts[$key] = apply_filters('msreader_set_additional_post_data_dynamic_after', $post, $this->module); 332 | } 333 | } 334 | 335 | $posts = apply_filters('msreader_set_additional_posts_data_dynamic_after', $posts, $this->module); 336 | } 337 | 338 | return $posts; 339 | } 340 | 341 | //helper that applies moderation action on comments to replies 342 | function moderate_comment_action($action, $comment_id = 0, $post_id = 0) { 343 | global $wpdb; 344 | 345 | $status = false; 346 | if(current_user_can('moderate_comment') || current_user_can('edit_post', $post_id)) { 347 | $replies = $wpdb->get_results( $wpdb->prepare("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent = %d", $comment_id) ); 348 | 349 | //lets delete permanently private comments to not leave junk behind 350 | if($action == 'trash') { 351 | $comment = get_comment($comment_id); 352 | if($comment->comment_approved == 'private') 353 | $action = 'delete'; 354 | } 355 | 356 | foreach ($replies as $reply) { 357 | $status = $this->moderate_comment_action($action, $reply->comment_ID, $post_id); 358 | } 359 | 360 | switch ($action) { 361 | case 'delete': 362 | $status = wp_delete_comment($comment_id, 1); 363 | break; 364 | case 'trash': 365 | $status = wp_delete_comment($comment_id); 366 | break; 367 | case 'spam': 368 | $status = wp_spam_comment($comment_id); 369 | break; 370 | case 'unapprove': 371 | $status = wp_set_comment_status($comment_id, 0); 372 | $status = $status ? 'approve' : 'unapprove'; 373 | break; 374 | case 'approve': 375 | $status = wp_set_comment_status($comment_id, 1); 376 | $status = $status ? 'unapprove' : 'approve'; 377 | break; 378 | } 379 | } 380 | 381 | return $status; 382 | } 383 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid/js/lightslider.min.js: -------------------------------------------------------------------------------- 1 | /*! lightslider - v1.1.5 - 2015-10-31 2 | * https://github.com/sachinchoolur/lightslider 3 | * Copyright (c) 2015 Sachin N; Licensed MIT */ 4 | !function(a,b){"use strict";var c={item:3,autoWidth:!1,slideMove:1,slideMargin:10,addClass:"",mode:"slide",useCSS:!0,cssEasing:"ease",easing:"linear",speed:400,auto:!1,pauseOnHover:!1,loop:!1,slideEndAnimation:!0,pause:2e3,keyPress:!1,controls:!0,prevHtml:"",nextHtml:"",rtl:!1,adaptiveHeight:!1,vertical:!1,verticalHeight:500,vThumbWidth:100,thumbItem:10,pager:!0,gallery:!1,galleryMargin:5,thumbMargin:5,currentPagerPosition:"middle",enableTouch:!0,enableDrag:!0,freeMove:!0,swipeThreshold:40,responsive:[],onBeforeStart:function(a){},onSliderLoad:function(a){},onBeforeSlide:function(a,b){},onAfterSlide:function(a,b){},onBeforeNextSlide:function(a,b){},onBeforePrevSlide:function(a,b){}};a.fn.lightSlider=function(b){if(0===this.length)return this;if(this.length>1)return this.each(function(){a(this).lightSlider(b)}),this;var d={},e=a.extend(!0,{},c,b),f={},g=this;d.$el=this,"fade"===e.mode&&(e.vertical=!1);var h=g.children(),i=a(window).width(),j=null,k=null,l=0,m=0,n=!1,o=0,p="",q=0,r=e.vertical===!0?"height":"width",s=e.vertical===!0?"margin-bottom":"margin-right",t=0,u=0,v=0,w=0,x=null,y="ontouchstart"in document.documentElement,z={};return z.chbreakpoint=function(){if(i=a(window).width(),e.responsive.length){var b;if(e.autoWidth===!1&&(b=e.item),ie.responsive[0].breakpoint)for(var g in f)f.hasOwnProperty(g)&&(e[g]=f[g]);e.autoWidth===!1&&t>0&&v>0&&b!==e.item&&(q=Math.round(t/((v+e.slideMargin)*e.slideMove)))}},z.calSW=function(){e.autoWidth===!1&&(v=(o-(e.item*e.slideMargin-e.slideMargin))/e.item)},z.calWidth=function(a){var b=a===!0?p.find(".lslide").length:h.length;if(e.autoWidth===!1)m=b*(v+e.slideMargin);else{m=0;for(var c=0;b>c;c++)m+=parseInt(h.eq(c).width())+e.slideMargin}return m},d={doCss:function(){var a=function(){for(var a=["transition","MozTransition","WebkitTransition","OTransition","msTransition","KhtmlTransition"],b=document.documentElement,c=0;c'+e.prevHtml+''+e.nextHtml+""),e.autoWidth?z.calWidth(!1)
'),p=g.parent(".lSSlideWrapper"),e.rtl===!0&&p.parent().addClass("lSrtl"),e.vertical?(p.parent().addClass("vertical"),o=e.verticalHeight,p.css("height",o+"px")):o=g.outerWidth(),h.addClass("lslide"),e.loop===!0&&"slide"===e.mode&&(z.calSW(),z.clone=function(){if(z.calWidth(!0)>o){for(var b=0,c=0,d=0;d=o+e.slideMargin));d++);var f=e.autoWidth===!0?c:e.item;if(fh.length-1-g.find(".clone.right").length;j--)q--,h.eq(j).remove();for(var k=g.find(".clone.right").length;f>k;k++)g.find(".lslide").eq(k).clone().removeClass("lslide").addClass("clone right").appendTo(g),q++;for(var l=g.find(".lslide").length-g.find(".clone.left").length;l>g.find(".lslide").length-f;l--)g.find(".lslide").eq(l-1).clone().removeClass("lslide").addClass("clone left").prependTo(g);h=g.children()}else h.hasClass("clone")&&(g.find(".clone").remove(),a.move(g,0))},z.clone()),z.sSW=function(){l=h.length,e.rtl===!0&&e.vertical===!1&&(s="margin-left"),e.autoWidth===!1&&h.css(r,v+"px"),h.css(s,e.slideMargin+"px"),m=z.calWidth(!1),g.css(r,m+"px"),e.loop===!0&&"slide"===e.mode&&n===!1&&(q=g.find(".clone.left").length)},z.calL=function(){h=g.children(),l=h.length},this.doCss()&&p.addClass("usingCss"),z.calL(),"slide"===e.mode?(z.calSW(),z.sSW(),e.loop===!0&&(t=a.slideValue(),this.move(g,t)),e.vertical===!1&&this.setHeight(g,!1)):(this.setHeight(g,!0),g.addClass("lSFade"),this.doCss()||(h.fadeOut(0),h.eq(q).fadeIn(0))),e.loop===!0&&"slide"===e.mode?h.eq(q).addClass("active"):h.first().addClass("active")},pager:function(){var a=this;if(z.createPager=function(){w=(o-(e.thumbItem*e.thumbMargin-e.thumbMargin))/e.thumbItem;var b=p.find(".lslide"),c=p.find(".lslide").length,d=0,f="",h=0;for(d=0;c>d;d++){"slide"===e.mode&&(e.autoWidth?h+=(parseInt(b.eq(d).width())+e.slideMargin)*e.slideMove:h=d*(v+e.slideMargin)*e.slideMove);var i=b.eq(d*e.slideMove).attr("data-thumb");if(f+=e.gallery===!0?'
  • ':'
  • '+(d+1)+"
  • ","slide"===e.mode&&h>=m-o-e.slideMargin){d+=1;var j=2;e.autoWidth&&(f+='
  • '+(d+1)+"
  • ",j=1),j>d?(f=null,p.parent().addClass("noPager")):p.parent().removeClass("noPager");break}}var k=p.parent();k.find(".lSPager").html(f),e.gallery===!0&&(e.vertical===!0&&k.find(".lSPager").css("width",e.vThumbWidth+"px"),u=d*(e.thumbMargin+w)+.5,k.find(".lSPager").css({property:u+"px","transition-duration":e.speed+"ms"}),e.vertical===!0&&p.parent().css("padding-right",e.vThumbWidth+e.galleryMargin+"px"),k.find(".lSPager").css(r,u+"px"));var l=k.find(".lSPager").find("li");l.first().addClass("active"),l.on("click",function(){return e.loop===!0&&"slide"===e.mode?q+=l.index(this)-k.find(".lSPager").find("li.active").index():q=l.index(this),g.mode(!1),e.gallery===!0&&a.slideThumb(),!1})},e.pager){var b="lSpg";e.gallery&&(b="lSGallery"),p.after('
      ');var c=e.vertical?"margin-left":"margin-top";p.parent().find(".lSPager").css(c,e.galleryMargin+"px"),z.createPager()}setTimeout(function(){z.init()},0)},setHeight:function(a,b){var c=null,d=this;c=e.loop?a.children(".lslide ").first():a.children().first();var f=function(){var d=c.outerHeight(),e=0,f=d;b&&(d=0,e=100*f/o),a.css({height:d+"px","padding-bottom":e+"%"})};f(),c.find("img").length?c.find("img")[0].complete?(f(),x||d.auto()):c.find("img").load(function(){setTimeout(function(){f(),x||d.auto()},100)}):x||d.auto()},active:function(a,b){this.doCss()&&"fade"===e.mode&&p.addClass("on");var c=0;if(q*e.slideMove=d&&(c=f)),e.loop===!0&&"slide"===e.mode&&(c=b===!0?q-g.find(".clone.left").length:q*e.slideMove,b===!0&&(d=a.length,f=d-1,c+1===d?c=f:c+1>d&&(c=0))),this.doCss()||"fade"!==e.mode||b!==!1||a.eq(c).fadeIn(e.speed),a.eq(c).addClass("active")}else a.removeClass("active"),a.eq(a.length-1).addClass("active"),this.doCss()||"fade"!==e.mode||b!==!1||(a.fadeOut(e.speed),a.eq(c).fadeIn(e.speed))},move:function(a,b){e.rtl===!0&&(b=-b),this.doCss()?a.css(e.vertical===!0?{transform:"translate3d(0px, "+-b+"px, 0px)","-webkit-transform":"translate3d(0px, "+-b+"px, 0px)"}:{transform:"translate3d("+-b+"px, 0px, 0px)","-webkit-transform":"translate3d("+-b+"px, 0px, 0px)"}):e.vertical===!0?a.css("position","relative").animate({top:-b+"px"},e.speed,e.easing):a.css("position","relative").animate({left:-b+"px"},e.speed,e.easing);var c=p.parent().find(".lSPager").find("li");this.active(c,!0)},fade:function(){this.active(h,!1);var a=p.parent().find(".lSPager").find("li");this.active(a,!0)},slide:function(){var a=this;z.calSlide=function(){m>o&&(t=a.slideValue(),a.active(h,!1),t>m-o-e.slideMargin?t=m-o-e.slideMargin:0>t&&(t=0),a.move(g,t),e.loop===!0&&"slide"===e.mode&&(q>=l-g.find(".clone.left").length/e.slideMove&&a.resetSlide(g.find(".clone.left").length),0===q&&a.resetSlide(p.find(".lslide").length)))},z.calSlide()},resetSlide:function(a){var b=this;p.find(".lSAction a").addClass("disabled"),setTimeout(function(){q=a,p.css("transition-duration","0ms"),t=b.slideValue(),b.active(h,!1),d.move(g,t),setTimeout(function(){p.css("transition-duration",e.speed+"ms"),p.find(".lSAction a").removeClass("disabled")},50)},e.speed+100)},slideValue:function(){var a=0;if(e.autoWidth===!1)a=q*(v+e.slideMargin)*e.slideMove;else{a=0;for(var b=0;q>b;b++)a+=parseInt(h.eq(b).width())+e.slideMargin}return a},slideThumb:function(){var a;switch(e.currentPagerPosition){case"left":a=0;break;case"middle":a=o/2-w/2;break;case"right":a=o-w}var b=q-g.find(".clone.left").length,c=p.parent().find(".lSPager");"slide"===e.mode&&e.loop===!0&&(b>=c.children().length?b=0:0>b&&(b=c.children().length));var d=b*(w+e.thumbMargin)-a;d+o>u&&(d=u-o-e.thumbMargin),0>d&&(d=0),this.move(c,d)},auto:function(){e.auto&&(clearInterval(x),x=setInterval(function(){g.goToNextSlide()},e.pause))},pauseOnHover:function(){var b=this;e.auto&&e.pauseOnHover&&(p.on("mouseenter",function(){a(this).addClass("ls-hover"),g.pause(),e.auto=!0}),p.on("mouseleave",function(){a(this).removeClass("ls-hover"),p.find(".lightSlider").hasClass("lsGrabbing")||b.auto()}))},touchMove:function(a,b){if(p.css("transition-duration","0ms"),"slide"===e.mode){var c=a-b,d=t-c;if(d>=m-o-e.slideMargin)if(e.freeMove===!1)d=m-o-e.slideMargin;else{var f=m-o-e.slideMargin;d=f+(d-f)/5}else 0>d&&(e.freeMove===!1?d=0:d/=5);this.move(g,d)}},touchEnd:function(a){if(p.css("transition-duration",e.speed+"ms"),"slide"===e.mode){var b=!1,c=!0;t-=a,t>m-o-e.slideMargin?(t=m-o-e.slideMargin,e.autoWidth===!1&&(b=!0)):0>t&&(t=0);var d=function(a){var c=0;if(b||a&&(c=1),e.autoWidth)for(var d=0,f=0;f=t));f++);else{var g=t/((v+e.slideMargin)*e.slideMove);q=parseInt(g)+c,t>=m-o-e.slideMargin&&g%1!==0&&q++}};a>=e.swipeThreshold?(d(!1),c=!1):a<=-e.swipeThreshold&&(d(!0),c=!1),g.mode(c),this.slideThumb()}else a>=e.swipeThreshold?g.goToPrevSlide():a<=-e.swipeThreshold&&g.goToNextSlide()},enableDrag:function(){var b=this;if(!y){var c=0,d=0,f=!1;p.find(".lightSlider").addClass("lsGrab"),p.on("mousedown",function(b){return o>m&&0!==m?!1:void("lSPrev"!==a(b.target).attr("class")&&"lSNext"!==a(b.target).attr("class")&&(c=e.vertical===!0?b.pageY:b.pageX,f=!0,b.preventDefault?b.preventDefault():b.returnValue=!1,p.scrollLeft+=1,p.scrollLeft-=1,p.find(".lightSlider").removeClass("lsGrab").addClass("lsGrabbing"),clearInterval(x)))}),a(window).on("mousemove",function(a){f&&(d=e.vertical===!0?a.pageY:a.pageX,b.touchMove(d,c))}),a(window).on("mouseup",function(g){if(f){p.find(".lightSlider").removeClass("lsGrabbing").addClass("lsGrab"),f=!1,d=e.vertical===!0?g.pageY:g.pageX;var h=d-c;Math.abs(h)>=e.swipeThreshold&&a(window).on("click.ls",function(b){b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopImmediatePropagation(),b.stopPropagation(),a(window).off("click.ls")}),b.touchEnd(h)}})}},enableTouch:function(){var a=this;if(y){var b={},c={};p.on("touchstart",function(a){c=a.originalEvent.targetTouches[0],b.pageX=a.originalEvent.targetTouches[0].pageX,b.pageY=a.originalEvent.targetTouches[0].pageY,clearInterval(x)}),p.on("touchmove",function(d){if(o>m&&0!==m)return!1;var f=d.originalEvent;c=f.targetTouches[0];var g=Math.abs(c.pageX-b.pageX),h=Math.abs(c.pageY-b.pageY);e.vertical===!0?(3*h>g&&d.preventDefault(),a.touchMove(c.pageY,b.pageY)):(3*g>h&&d.preventDefault(),a.touchMove(c.pageX,b.pageX))}),p.on("touchend",function(){if(o>m&&0!==m)return!1;var d;d=e.vertical===!0?c.pageY-b.pageY:c.pageX-b.pageX,a.touchEnd(d)})}},build:function(){var b=this;b.initialStyle(),this.doCss()&&(e.enableTouch===!0&&b.enableTouch(),e.enableDrag===!0&&b.enableDrag()),a(window).on("focus",function(){b.auto()}),a(window).on("blur",function(){clearInterval(x)}),b.pager(),b.pauseOnHover(),b.controls(),b.keyPress()}},d.build(),z.init=function(){z.chbreakpoint(),e.vertical===!0?(o=e.item>1?e.verticalHeight:h.outerHeight(),p.css("height",o+"px")):o=p.outerWidth(),e.loop===!0&&"slide"===e.mode&&z.clone(),z.calL(),"slide"===e.mode&&g.removeClass("lSSlide"),"slide"===e.mode&&(z.calSW(),z.sSW()),setTimeout(function(){"slide"===e.mode&&g.addClass("lSSlide")},1e3),e.pager&&z.createPager(),e.adaptiveHeight===!0&&e.vertical===!1&&g.css("height",h.eq(q).outerHeight(!0)),e.adaptiveHeight===!1&&("slide"===e.mode?e.vertical===!1?d.setHeight(g,!1):d.auto():d.setHeight(g,!0)),e.gallery===!0&&d.slideThumb(),"slide"===e.mode&&d.slide(),e.autoWidth===!1?h.length<=e.item?p.find(".lSAction").hide():p.find(".lSAction").show():z.calWidth(!1)0)e.onBeforePrevSlide.call(this,g,q),q--,g.mode(!1),e.gallery===!0&&d.slideThumb();else if(e.loop===!0){if(e.onBeforePrevSlide.call(this,g,q),"fade"===e.mode){var a=l-1;q=parseInt(a/e.slideMove)}g.mode(!1),e.gallery===!0&&d.slideThumb()}else e.slideEndAnimation===!0&&(g.addClass("leftEnd"),setTimeout(function(){g.removeClass("leftEnd")},400))},g.goToNextSlide=function(){var a=!0;if("slide"===e.mode){var b=d.slideValue();a=b=q?b+(q-c):q>=b+c?q-b-c:q-c}return a+1},g.getTotalSlideCount=function(){return p.find(".lslide").length},g.goToSlide=function(a){q=e.loop?a+g.find(".clone.left").length-1:a,g.mode(!1),e.gallery===!0&&d.slideThumb()},g.destroy=function(){g.lightSlider&&(g.goToPrevSlide=function(){},g.goToNextSlide=function(){},g.mode=function(){},g.play=function(){},g.pause=function(){},g.refresh=function(){},g.getCurrentSlideCount=function(){},g.getTotalSlideCount=function(){},g.goToSlide=function(){},g.lightSlider=null,z={init:function(){}},g.parent().parent().find(".lSAction, .lSPager").remove(),g.removeClass("lightSlider lSFade lSSlide lsGrab lsGrabbing leftEnd right").removeAttr("style").unwrap().unwrap(),g.children().removeAttr("style"),h.removeClass("lslide active"),g.find(".clone").remove(),h=null,x=null,n=!1,q=0)},setTimeout(function(){e.onSliderLoad.call(this,g)},10),a(window).on("resize orientationchange",function(a){setTimeout(function(){a.preventDefault?a.preventDefault():a.returnValue=!1,z.init()},200)}),this}}(jQuery); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reader 2 | 3 | **INACTIVE NOTICE: This plugin is unsupported by WPMUDEV, we've published it here for those technical types who might want to fork and maintain it for their needs.** 4 | 5 | ## Translations 6 | 7 | Translation files can be found at https://github.com/wpmudev/translations 8 | 9 | 10 | ## Usage 11 | 12 | Reader turns your Multisite into a community by adding Tumblr, WordPress.com and Edublogs style "follow" features. 13 | 14 | Complete with a beautiful and fully-featured dashboard reader experience that allows comments, RSS feeds and significant customization. 15 | 16 | ### Follow Your Favorites 17 | 18 | Reader adds a nifty "Follow" button to the admin bar on every site in your Multisite network. Users can click on the Follow button to add their favorite blogs to their Reader. Browse, search and engage with posts from the dashboard. 19 | 20 | ### High-End Reader 21 | 22 | We've combined the greatest features from Feedly, Tumblr and WordPress.com to give you a premium reader experience. Users can engage with sites across your network, without ever leaving their site. 23 | 24 | ### Simple Configuration 25 | 26 | Setup can be completed in just a couple of seconds complete with a custom name a site exclusion. Tell reader what to include in your feed. Get a reader that runs the way you like it with powerful features and simple settings. 27 | 28 | ### Stronger Sense of Community 29 | 30 | You will be surprised by the impact this has on your users – receiving email notifications is great, but being able to browse and interact with comments can really set your network on fire. 31 | 32 | ### To Get Started 33 | 34 | _Important: Reader must be network-activated and requires the Post Indexer plugin to fetch your network content._ 35 | 36 | * If you have not already installed & configured Post Indexer, and indexed your network, please do that first. 37 | 38 | Once Reader is installed and network-activated, you'll see a new sub-menu item in your Network Settings menu: Reader. 39 | 40 | ### General Overview 41 | 42 | Using the Reader is quite intuitive for the end-user, with tooltips for just about everything. But to help us understand all the features of Reader available to the network admin, let's first take a quick look at what your users see with all of them enabled. Then we'll explore all of the options & modules in greater detail, as well as what your users can do with them. 43 | 44 | 1\. RSS Feed for selected display. 45 | 46 | 2\. Post display area. 47 | 48 | 3\. Search widget. 49 | 50 | 4\. Main widget with filtering options. 51 | 52 | 5\. Trending tags widget. 53 | 54 | 1\. _An RSS feed URL_ is generated for every display type. There are several ways to filter the display, and they're all discussed below... keep reading. :) 55 | 56 | 2\. _The post display area_. This is where all the network posts display according to what post-types you have indexed with the [Post Indexer](https://premium.wpmudev.org/project/post-indexer/ "Post Indexer") plugin, and what filtering option has been selected. 57 | 58 | 3\. _The search widget_ enables you and your users to search within all available content by title, author or tag, or any combination. 59 | 60 | 4\. _The main widget_ contains a bunch of display filtering options, as well as a couple of handy links to stuff in your admin. 61 | 62 | 5\. _The Trending Tags widget_ displays tags recently used in your network to make filtering for the hottest new content just too easy! Pretty cool, huh? We'll look into all that in more detail below. Oh, and be sure to read all the way through as some of the greatest interactive features of this plugin are detailed at the end! Now, let's take a closer look at the options available to you in the network admin, and see what effect they have on the Reader that appears on each site in your network. 63 | 64 | ### Brand the Reader for your network 65 | 66 | The options panel in the network admin enables you to control the features and behavior of the Reader on all sites in your network. The first thing we want to do is decide where the Reader should appear in the admin menu of every site, and what it should be called in your network. 67 | 68 | 1\. _Where should the Reader be?_ gives you 2 options. You can select to either: 69 | 70 | * add Reader as a new item under the Dashboard menu 71 | * replace the default Dashboard screen with Reader 72 | 73 | Adding Reader as a new item does what it says on the tin: it adds a new Dashboard menu item that links to the Reader page in the admin. 74 | However, if you set it to replace the default Dashboard screen, your network users will instead be welcomed by your sexy new Reader when they log into their sites. Woot! 75 | 76 | 2\. _Whats The Reader page name?_ enables you to customize the label that appears in the menu, so you can brand it to better fit your niche. 77 | Now let's get to all those cool features! 78 | 79 | ### Enable/Disable Features 80 | 81 | Getting Reader up and running on your network couldn't be easier! All you really need to do is decide which features you want enabled. They are all enabled by default when you first install the plugin, but you can set 'em up the way you want 'em. ! 82 | 83 | 84 | ##### Featured Posts 85 | 86 | The _Featured Posts_ module enables you, as the network admin, to add any posts to a featured list. To do so, visit the Reader in the admin of your main site, and click the "Feature" button in any post that appears in the main content area. ![ Reader Feature Post Any post that has been featured will have a little green star in the upper-right corner as a reminder, and the button will change to "Unfeature" so you can remove it from the featured list later if you want. Reader Featured Post Users on every site in your network can now filter what appears in the main content area of their Reader to show only featured posts by clicking the "Featured Posts" link in the main widget. Note that the "Feature/Unfeature" button is only available to you as the network admin user, but will be visible to you on all sites in your network. Site admins and other users cannot add or remove posts from the featured list. 87 | 88 | ##### Filter by author or site 89 | 90 | The _Filter by author or site_ module enables your users to filter the post list in the main content area of their Reader to show only posts from a specific site, or those from a specific author. To filter by author or site, simply click the author or site link that appears at the bottom of every post in the main content area of the Reader. If the display is filtered to show only posts from a specific site, a "Visit site" button will also appear next to the title in the main content area. 91 | 92 | ##### Follow 93 | 94 | The _Follow_ module enables your users to follow sites in your network and create a customized list of those that interest them. Before we look at how it works, there are some additional configuration settings that you can set in your network admin for this module. 95 | 96 | 1\. Click to open the settings panel. 97 | 98 | 2\. Default followed sites. 99 | 100 | 3\. Show/hide toolbar button. 101 | 102 | 1\. Click the _Configure_ button next to the module to access the settings. 103 | 104 | 2\. Enter the _IDs of sites followed by default_ in the Reader on all sites in your network. 105 | 106 | * For example, if you want the main site to be followed, enter the ID of your main site (usually _1_). 107 | * If you want multiple sites to be followed by default, enter a comma-separated list of IDs like so: _1,16,37_ 108 | * If you don't want any sites to followed by default, simply leave the field blank. 109 | 110 | 3\. Select where to _Display follow button on_ the toolbar of all sites in your network. You can select to show the "Follow" button on 111 | 112 | * Both the frontend and backend (wp-admin) of all sites. 113 | * Only the frontend. 114 | * Only the backend. 115 | 116 | Now your users can follow sites that interest them simply by clicking the "Follow" button at the bottom of any post in their Reader. When a site is followed, the button will change to "Following" with a nice little red heart. Also, depending on what you have set in the network configuration for the module, the toolbar will show the site is followed when the user visits the site. The main display can be filtered to show only posts from sites that the user is currently following simply by clicking the link in the main widget. The "Following" link at the top of the main widget will also indicate the number of sites the user is following. When that link is clicked, the main content area will display a list of all the sites the user is currently following. 117 | 118 | * Clicking the site name on the left will display all posts from that site in the main content area. 119 | * Clicking the site URL will redirect the user to that site. 120 | * Clicking the "x" at the far right of any row will remove that site from all displays of followed sites. 121 | 122 | ##### My Posts 123 | 124 | The _My Posts_ module enables your users to instantly view all posts that they have authored in your network. Enabling this module creates a "My Posts" link in the main widget. When this link is clicked, the display in the main content area will be filtered to show only posts authored by the logged-in user viewing the Reader. Note that this will display all posts from the same author on all sites, regardless of which site the user is viewing. In other words, if the logged-in user has authored posts on multiple sites, they will all display. 125 | 126 | ##### My Sites 127 | 128 | The _My Sites_ module creates a link in the main widget of the Reader enabling your users to filter the display to show only posts from sites where they are listed as users. Note that this is a site filter, and it will display posts from all sites where the user is actually a user, regardless of the role they have on each site. Also note that the "My Sites" link which appears above the filter list and next to the "Following" link simply redirects to the standard _My Sites_ screen in the admin, and does not affect the Reader display. 129 | 130 | ##### Popular Posts 131 | 132 | The _Popular Posts_ module also has an additional configuration option that you can set in your network admin. 133 | 134 | 135 | 1\. Click to open the settings panel. 136 | 137 | 2\. Set minimum number of comments for filter. 138 | 139 | 1\. Click the _Configure_ button next to the module to access the settings. 140 | 141 | 2\. Enter the _Minimum number of comments to the post to treat it as popular_ to determine which posts will display when the "Popular Posts" filter is used. When this module is enabled, it creates a link in the main widget that your users can click to filter the post display and view only those posts that have the minimum number of comments you just set. 142 | 143 | ##### Recent Posts 144 | 145 | The Recent Posts module simply adds another filter to the main widget that, when clicked, displays the most recent posts from across your entire network. 146 | 147 | ##### RSS Feeds 148 | 149 | The _RSS Feeds_ module creates a special RSS feed for each of the above filters that you have enabled. 150 | 151 | * To get the RSS Feed URL for the currently selected filter, click the RSS icon next to the title. 152 | * As an example, if the user is currently filtering & viewing only Featured Posts, the RSS Feed URL that appears can be used to display your network's featured posts. 153 | * You can use these RSS feeds in widgets on your site, on any other site, or even in your favorite feed reader on your mobile device to get instant notification of new stuff in your network! 154 | 155 | Each feed URL also contains a private key. This can be very handy if, for example, someone unauthorized or unscrupulous gets hold of the URL and uses it to scrape content from your network. 156 | 157 | * You can reset ALL private keys for your feeds by clicking the link at the bottom of the RSS feed box. 158 | 159 | ##### Search 160 | 161 | The _Search_ module enables a search box above the main widget so that your users can easily find the content they want. 162 | 163 | * You can search for any network content by title, tag or author, or any combination. 164 | 165 | 166 | ##### Trending Tags 167 | 168 | The _Trending Tags_ module is another that has a few configuration options. 169 | 170 | 1\. Click to open the settings panel. 171 | 172 | 2\. Set the number of links to display. 173 | 174 | 3\. Select how many network tags to check. 175 | 176 | 1\. Click the _Configure_ button next to the module to access the settings. 177 | 178 | 2\. The _Number of links in "Trending Tags" widget_ is just that. Simply select how many you want displayed in the widget. 179 | 180 | 3\. The _Number of recently added tags to check_ setting enables you to select how many tags should be checked throughout your network to find those that are truly trending. Once enabled, this module creates a new widget in the Reader on each site. Users need only click any tag in the widget to filter the display and show only posts containing that tag. 181 | 182 | * Please note that there is currently no dedicated RSS feed for tags. 183 | 184 | ##### User Info 185 | 186 | The _User Info_ module is what displays data for the user currently viewing the Reader at the top of the main widget. 187 | 188 | * The username link next to the avatar redirects to the user's profile in the admin. 189 | * The "My Posts" link, as detailed above, filters the post display. 190 | * The "My Sites" link, as mentioned above, redirects the user to their "My Sites" screen in the admin. 191 | * The "Following" link, as detailed above, will replace the content in the main post area with a display of all sites being followed. 192 | 193 | If this module is disabled, the user can still view and manage the list of sites being followed by clicking the little gear icon that appears at the top-right of the widget. The "My Posts" link is also added to the filter list if that module is enabled. 194 | 195 | ##### Default Feature 196 | 197 | The final option in the network settings is the default feature. You can select which of the features you have enabled above that should be the default display when users visit their Reader. For example, if you have enabled the "Recent Posts" module, you can set it as the default so your network's most recent content is shown to users first. 198 | 199 | ### The Reader 200 | 201 | Oh yeah, the Reader has a reader, and this final feature is just too cool! You surely noticed a "Read More" button in previous images. That button does not redirect to the post in the site where it was published. Rather, it launches a modal window where your users can read the whole post & comment on it right in their dashboard! 202 | 203 | 1\. Navigation & editor features. 204 | 205 | 2\. Post display area. 206 | 207 | 3\. Comments area. 208 | 209 | 1\. The _navigation bar_ of the Reader modal contains several features: 210 | 211 | * Easy navigation between posts in the currently selected filter. 212 | * Click "View Original" to be redirected to the post on the site where it is published. 213 | * The network admin, and users with the required capabilities, will see an "Edit" link so they can go directly to the post and edit it if required. 214 | * The network admin will also see a "Feature" link on all posts that are not currently featured. If the post is already featured, that link will show "Unfeature" instead. 215 | 216 | 2\. The _post display area_ enables your users to scroll through the entire post they're viewing so they don't even need to leave their own site! 217 | 218 | * The post meta at the top of each post shows the site where it is published and the author's name. Clicking either will close the modal reader and filter the main display to show all posts from that site or author. 219 | * Users can follow or unfollow the site right there too. 220 | 221 | 3\. The _comments area_ works just as if the user were commenting on the author's site. 222 | 223 | * Your users can comment on posts right in their reader, and even reply to other comments. 224 | * The network admin, site admins and users with the required capabilities can approve/unapprove, spam & trash comments. 225 | 226 | ### Responsiveness & Mobile Devices 227 | 228 | On a final note, it's worth mentioning that the whole thing is fully responsive. It looks fabulous & works perfectly on mobile devices. 229 | -------------------------------------------------------------------------------- /msreader-files/includes/modules/featured-posts.php: -------------------------------------------------------------------------------- 1 | __( 'Featured Posts', 'wmd_msreader' ), 4 | 'description' => __( 'Enables posts featuring', 'wmd_msreader' ), 5 | 'slug' => 'featured_posts', 6 | 'class' => 'WMD_MSReader_Module_FeaturedPosts', 7 | 'type' => 'query' 8 | ); 9 | 10 | class WMD_MSReader_Module_FeaturedPosts extends WMD_MSReader_Modules { 11 | 12 | function init() { 13 | add_filter( 'msreader_dashboard_reader_sidebar_widgets', array($this,'add_link_to_widget'), 10 ); 14 | 15 | //add_action( 'admin_bar_menu', array( $this, "feature_link" ), 600 ); 16 | add_action( 'wp_footer', array( $this, "add_css_js" ) ); 17 | add_action( 'admin_head', array( $this, "add_css_js" ) ); 18 | 19 | add_filter( 'msreader_read_more_button', array($this,'add_featuring_button'),20,2); 20 | add_filter( 'msreader_list_post_title', array($this,'add_featured_indicator'), 20, 2 ); 21 | add_filter( 'msreader_dashboard_single_links', array($this, 'dashboard_single_add_featuring_button'), 20, 2 ); 22 | 23 | add_filter( 'msreader_set_additional_post_data_dynamic_before', array($this,'additional_post_data'),20,2 ); 24 | 25 | add_filter( 'the_content', array($this,'add_featuring_button_in_content'), 20, 1 ); 26 | 27 | add_action( 'wp_enqueue_scripts', array($this, 'enqueue_scripts'), 20, 1 ); 28 | add_action( 'admin_enqueue_scripts', array($this, 'enqueue_scripts'), 20, 1 ); 29 | add_action( 'wp_ajax_dashboard_feature_post', array($this, 'featured_posts_control'), 20 ); 30 | add_action( 'wp_ajax_nopriv_dashboard_feature_post', array($this, 'featured_posts_control'), 20 ); 31 | } 32 | 33 | function add_link_to_widget($widgets) { 34 | $featured_posts = get_site_option('msreader_featured_posts', array()); 35 | 36 | if(!empty($featured_posts) || is_super_admin()) 37 | $widgets['reader']['data']['list'][$this->details['slug']] = $this->create_link_for_main_widget(); 38 | 39 | return $widgets; 40 | } 41 | 42 | function add_featured_indicator($title, $post) { 43 | if(isset($post->featured) && $post->featured) 44 | $title = '
      '.$title; 45 | 46 | return $title; 47 | } 48 | 49 | function add_featuring_button($button, $post) { 50 | if(is_super_admin() && $post->post_date != '0000-00-00 00:00:00') { 51 | $text = (isset($post->featured) && $post->featured) ? __( 'Unfeature', 'wmd_msreader' ): __( 'Feature', 'wmd_msreader' ); 52 | 53 | $button .= ''; 54 | } 55 | 56 | return $button; 57 | } 58 | 59 | function dashboard_single_add_featuring_button($links, $post) { 60 | if(is_super_admin() && $post->post_status == 'publish') { 61 | $text = (isset($post->featured) && $post->featured) ? __( 'Unfeature', 'wmd_msreader' ): __( 'Feature', 'wmd_msreader' ); 62 | 63 | $links .= ''; 64 | } 65 | 66 | return $links; 67 | } 68 | 69 | function add_featuring_button_in_content($content) { 70 | global $post; 71 | 72 | if(is_super_admin() && !is_admin() && $post->post_type == 'post' && $post->post_status == 'publish' && is_main_query() && (is_archive() || is_single() || is_home())) { 73 | $post->BLOG_ID = get_current_blog_id(); 74 | $post = $this->additional_post_data($post); 75 | 76 | $text = (isset($post->featured) && $post->featured) ? __( 'Unfeature', 'wmd_msreader' ): __( 'Feature', 'wmd_msreader' ); 77 | 78 | $content = $content.'

      '.$text.'

      '; 79 | } 80 | 81 | return $content; 82 | } 83 | 84 | function enqueue_scripts() { 85 | wp_enqueue_script('jquery'); 86 | 87 | wp_localize_script('jquery', 'ajaxurl', admin_url( 'admin-ajax.php' )); 88 | wp_localize_script('jquery', 'msreader_featured_posts', array( 89 | 'saving' => __( 'Saving...', 'wmd_msreader' ), 90 | 'post_featured' => __( "This post is featured", "wmd_msreader" ), 91 | 'feature' => __( "Feature", "wmd_msreader" ), 92 | 'unfeature' => __( "Unfeature", "wmd_msreader" ) 93 | )); 94 | } 95 | 96 | function add_css_js() { 97 | echo 98 | ''; 115 | 116 | ?> 117 | 118 | 203 | 204 | args['blog_id']) && isset($this->args['post_id']) && is_super_admin()) { 209 | $post_details = get_blog_post($this->args['blog_id'], $this->args['post_id']); 210 | if($post_details){ 211 | $featured_posts = get_site_option('msreader_featured_posts', array()); 212 | 213 | $post_blog_key = $this->args['blog_id'].'-'.$this->args['post_id']; 214 | $key_exists = array_search($post_blog_key, $featured_posts); 215 | 216 | if($key_exists !== false) { 217 | unset($featured_posts[$key_exists]); 218 | update_site_option('msreader_featured_posts', $featured_posts); 219 | 220 | echo 'feature'; 221 | } 222 | else { 223 | $featured_posts[] = $post_blog_key; 224 | update_site_option('msreader_featured_posts', $featured_posts); 225 | 226 | echo 'unfeature'; 227 | } 228 | 229 | $this->increase_cache_init(); 230 | } 231 | } 232 | 233 | die(); 234 | } 235 | 236 | //UNUSED 237 | function feature_link() { 238 | if(is_super_admin() && is_single()) { 239 | global $wp_admin_bar; 240 | 241 | $current_blog_id = get_current_blog_id(); 242 | 243 | $followed_by_user = $this->get_featured_posts(); 244 | 245 | if(in_array($current_blog_id, $followed_by_user)) { 246 | $text = __( 'Featured', 'wmd_msreader' ); 247 | $hover_text = __( 'Unfeature', 'wmd_msreader' ); 248 | $url = $this->get_module_dashboard_url(array('action' => 'unfollow', 'blog_id' => $current_blog_id)); 249 | $class = 'following'; 250 | } 251 | else { 252 | $text = __( 'Feature', 'wmd_msreader' ); 253 | $hover_text = __( 'Follow', 'wmd_msreader' ); 254 | $url = $this->get_module_dashboard_url(array('action' => 'follow', 'blog_id' => $current_blog_id)); 255 | $class = 'follow'; 256 | } 257 | 258 | $wp_admin_bar->add_menu( 259 | array( 260 | 'id' => 'msreader-feature', 261 | //'parent' => 'top-secondary', 262 | 'title' => ''.$text.'', 263 | 'href' => $url, 264 | 'meta' => array( 265 | 'class' => $class, 266 | 'title' => $hover_text.' '.__( 'this site', 'wmd_msreader' ) 267 | ), 268 | ) 269 | ); 270 | } 271 | } 272 | 273 | function additional_post_data($post) { 274 | $featured_posts = get_site_option('msreader_featured_posts', array()); 275 | $post_blog_key = $post->BLOG_ID.'-'.$post->ID; 276 | 277 | $post->featured = in_array($post_blog_key, $featured_posts) ? true : false; 278 | 279 | return $post; 280 | } 281 | 282 | function query() { 283 | global $wpdb; 284 | 285 | $limit = $this->get_limit(); 286 | $public = $this->get_public(); 287 | 288 | $featured_posts = get_site_option('msreader_featured_posts', array()); 289 | $featured_posts_where = array(); 290 | foreach ($featured_posts as $key) { 291 | $key = explode('-', $key); 292 | if(is_numeric($key[0]) && is_numeric($key[1])) 293 | $featured_posts_where[] = '(posts.BLOG_ID = '.$key[0].' AND posts.ID = '.$key[1].')'; 294 | } 295 | $featured_posts_where = count($featured_posts_where) ? 'AND ('.implode(' OR ', $featured_posts_where).')' : ''; 296 | 297 | if($featured_posts_where) { 298 | $query = " 299 | SELECT posts.BLOG_ID AS BLOG_ID, ID, post_author, post_date, post_date_gmt, post_content, post_title 300 | FROM $this->db_network_posts AS posts 301 | INNER JOIN $this->db_blogs AS blogs ON blogs.blog_id = posts.BLOG_ID 302 | WHERE $public blogs.archived = 0 AND blogs.spam = 0 AND blogs.deleted = 0 303 | AND post_status = 'publish' 304 | AND post_password = '' 305 | $featured_posts_where 306 | ORDER BY post_date_gmt DESC 307 | $limit 308 | "; 309 | $query = apply_filters('msreader_'.$this->details['slug'].'_query', $query, $this->args, $limit, $public, $featured_posts); 310 | 311 | $posts = $wpdb->get_results($query); 312 | } 313 | else 314 | $posts = array(); 315 | 316 | return $posts; 317 | } 318 | 319 | function get_empty_message() { 320 | $return = __( 'Nothing here yet!', 'wmd_msreader' ); 321 | if(is_super_admin()) 322 | $return .= __( '...But it looks like you are super admin which means you can feature posts by clicking "Feature" button.', 'wmd_msreader' ); 323 | if($this->helpers->is_module_enabled('recent_posts')) 324 | $return .= '
      '.__( 'Look for something interesting.', 'wmd_msreader' ).''; 325 | 326 | return $return; 327 | } 328 | } -------------------------------------------------------------------------------- /msreader-files/includes/modules/shortcode-recent-posts-grid.php: -------------------------------------------------------------------------------- 1 | __( 'Shortcode - Post Grid', 'wmd_msreader' ), 4 | 'description' => __( 'Allows usage of [reader-posts-grid] shorcode to display posts grid from various reader modules.', 'wmd_msreader' ), 5 | 'slug' => 'shortcode_recent_posts_grid', 6 | 'class' => 'WMD_MSReader_Module_ShortcodePostsGrid', 7 | 'can_be_default' => false, 8 | 'type' => 'wp-shortcode' 9 | ); 10 | 11 | class WMD_MSReader_Module_ShortcodePostsGrid extends WMD_MSReader_Modules { 12 | 13 | function init() { 14 | add_shortcode('reader-posts-grid', array($this, 'posts_grid')); 15 | 16 | add_action('wp_enqueue_scripts', array($this,'shortcode_register_scripts_styles')); 17 | } 18 | 19 | function shortcode_register_scripts_styles() { 20 | wp_register_script('jquery-slick', plugins_url( 'shortcode-recent-posts-grid/js/slick.min.js', __FILE__ ), array('jquery'), 1 ); 21 | wp_register_style('jquery-slick', plugins_url( 'shortcode-recent-posts-grid/css/slick.css', __FILE__ ), array(), 1 ); 22 | wp_register_style('jquery-slick-reader-theme', plugins_url( 'shortcode-recent-posts-grid/css/slick-theme.css', __FILE__ ), array('jquery-slick'), 1 ); 23 | } 24 | 25 | function posts_grid($attrs, $content) { 26 | 27 | global $wmd_msreader; 28 | include_once($wmd_msreader->plugin['dir'].'includes/query.php'); 29 | 30 | $args = array(); 31 | //sometimes we can have arg in module name 32 | 33 | $attr_module = isset($attrs['module']) ? explode('|', $attrs['module']) : array(); 34 | 35 | if(isset($attr_module[1])) { 36 | $attrs['module'] = $attr_module[0]; 37 | $args = array($attr_module[1]); 38 | } 39 | 40 | //lets dig out args data as it works bit differently than other attributes 41 | if(isset($attrs['args']) && $attrs['args']) { 42 | //str_replace fixes wp editor auto & conversion to & 43 | parse_str(str_replace('&', '&', $attrs['args']), $parsed_args); 44 | if(isset($parsed_args['args'])) 45 | $args = $parsed_args['args']; 46 | else 47 | $args = array($attrs['args']); 48 | } 49 | 50 | if(isset($attrs) && is_array($attrs)) 51 | foreach ($attrs as $attr_key => $attr_value){ 52 | if(substr($attr_key, 0,4) == 'arg-') 53 | $args[substr($attr_key, 4)] = $attr_value; 54 | } 55 | 56 | $default_attrs = array( 57 | 'number' => 20, 58 | 'module' => 'recent_posts', 59 | 'hide_image' => false, 60 | 'hide_excerpt' => false, 61 | 'hide_author' => false, 62 | 'hide_date' => false, 63 | 'posts_per_row' => 2, 64 | 'image_height' => '150px', 65 | 'background_color' => '#f9f9f9', 66 | 'text_color' => '#003b4e', 67 | 'hover_background_color' => '#003b4e', 68 | 'hover_link_color' => '#fbaf40', 69 | 'hover_link_content' => '»', 70 | 'target' => '_self', 71 | 'theme' => 'grid', 72 | 'slider_hide_dots' => false, 73 | 'slider_hide_arrows' => false, 74 | 'slider_disable_autoplay' => false, 75 | 'slider_disable_infinite' => false, 76 | 'slider_ui_color' => '#003b4e', 77 | 'slider_animation' => false, 78 | 'slider_height' => false 79 | ); 80 | $attrs = shortcode_atts($default_attrs, $attrs, 'reader-posts-grid'); 81 | 82 | if($attrs['theme'] == 'slider') 83 | if($attrs['slider_animation'] || $attrs['slider_height']) 84 | $attrs['posts_per_row'] = 1; 85 | 86 | extract( $attrs ); 87 | 88 | $number = (is_numeric($attrs['number']) && $attrs['number'] < 50) ? $attrs['number'] : 50; 89 | $posts_per_row = (is_numeric($attrs['posts_per_row']) && $attrs['posts_per_row'] > 0) ? $attrs['posts_per_row'] : 3; 90 | 91 | $user_id = get_the_author_id(); 92 | if(!$user_id && is_user_logged_in()) 93 | $user_id = get_current_user_id(); 94 | 95 | $return = ''; 96 | 97 | $query = new WMD_MSReader_Query(); 98 | 99 | if(isset($wmd_msreader->modules[$attrs['module']]) && $user_id) { 100 | $query->limit = $number; 101 | $query->user = $user_id; 102 | $query->args = $args; 103 | $query->load_module($wmd_msreader->modules[$attrs['module']]); 104 | 105 | $posts = $query->get_posts(); 106 | 107 | if(is_array($posts) && count($posts) > 0) { 108 | $sc_id = uniqid(); 109 | 110 | ob_start(); 111 | $this->shortcode_css_js($posts_per_row, $attrs, $sc_id); 112 | ?> 113 |
      114 |
        115 | featured_media_html, '')); 122 | $image_url = $this->get_img_src($image); 123 | } 124 | else 125 | $image_url = false; 126 | 127 | if(!$attrs['hide_author']) 128 | $avatar_url = $this->get_img_src(get_avatar($post->post_author, 48)); 129 | else 130 | $avatar_url = false; 131 | 132 | $post_excerpt = strip_tags($post->post_excerpt); 133 | ?> 134 | 135 |
      • 136 | 137 |
      '; 140 | ?> 141 |
      142 |
      post_title; ?>
      143 | 144 |
      145 | 146 | 147 | '; 151 | ?> 152 | 153 | 154 | post_date_relative; ?> 155 | 156 | 157 | 158 | 159 |
      160 | 161 | 162 |
      163 | 164 | 165 |
      166 | 167 | 170 | 171 | 172 | 187 | 300 | 349 | 355 | 367 | 371 | 386 | 396 | 402 | 439 | 440 | 466 | 467 | details = $msreader_available_modules[$slug]; 32 | 33 | //set options for module 34 | $this->options = $options; 35 | 36 | $this->message = isset($_GET['msg']) ? urldecode($_GET['msg']) : $this->message; 37 | $this->message_type = isset($_GET['msg_type']) ? $_GET['msg_type'] : $this->message_type; 38 | 39 | //fix translation issues 40 | $this->details['name'] = __($this->details['name'], 'wmd_msreader'); 41 | //sets default unnecessary data 42 | if(!isset($this->details['page_title'])) 43 | $this->details['page_title'] = $this->details['name']; 44 | else 45 | $this->details['page_title'] = __($this->details['page_title'], 'wmd_msreader'); 46 | if(!isset($this->details['menu_title'])) 47 | $this->details['menu_title'] = $this->details['name']; 48 | else 49 | $this->details['menu_title'] = __($this->details['menu_title'], 'wmd_msreader'); 50 | 51 | if(!isset($this->details['can_be_default'])) 52 | $this->details['can_be_default'] = true; 53 | if(!isset($this->details['global_cache'])) 54 | $this->details['global_cache'] = false; 55 | if(!isset($this->details['blog_specific_cache'])) 56 | $this->details['blog_specific_cache'] = false; 57 | if(!isset($this->details['disable_cache'])) 58 | $this->details['disable_cache'] = false; 59 | if(!isset($this->details['cache_time'])) 60 | $this->details['cache_time'] = 900; 61 | if(!isset($this->details['type'])) 62 | $this->details['default'] = 'other'; 63 | if(!is_array($this->details['type'])) 64 | $this->details['type'] = array($this->details['type']); 65 | if(!isset($this->details['allow_count'])) 66 | $this->details['allow_count'] = false; 67 | 68 | //set DB details 69 | $this->db_network_posts = apply_filters('msreader_db_network_posts', $wpdb->base_prefix.'network_posts'); 70 | $this->db_network_terms = apply_filters('msreader_db_network_terms', $wpdb->base_prefix.'network_terms'); 71 | $this->db_network_term_rel = apply_filters('msreader_db_network_relationships', $wpdb->base_prefix.'network_term_relationships'); 72 | $this->db_network_term_tax = apply_filters('msreader_db_network_taxonomy', $wpdb->base_prefix.'network_term_taxonomy'); 73 | $this->db_blogs = $wpdb->base_prefix.'blogs'; 74 | $this->db_users = $wpdb->base_prefix.'users'; 75 | 76 | //enable easy use of helpers functions 77 | $this->helpers = $msreader_helpers; 78 | 79 | //do the custom init by module 80 | $this->init(); 81 | 82 | //enable blog post linking without switch to blog 83 | if(isset($_GET['msreader_'.$this->details['slug']]) && $_GET['msreader_'.$this->details['slug']] == 'open_post' && isset($_GET['post_id']) && isset($_GET['blog_id'])) { 84 | add_action('init', array( $this, "open_site_post" ), 20); 85 | } 86 | } 87 | abstract function init(); 88 | 89 | function load_module() { 90 | $this->cache_init = $this->details['global_cache'] ? get_site_option('msreader_cache_init_'.$this->details['slug'], 1) : get_user_option('msreader_cache_init_'.$this->details['slug'], $this->get_user()); 91 | $this->cache_init = $this->cache_init == false ? 1 : $this->cache_init; 92 | } 93 | 94 | //This function needs to be replaced to display proper data - data is automatically cached for this one 95 | function query() { 96 | return 'error'; 97 | } 98 | 99 | //by default page title is module title 100 | function get_page_title() { 101 | return $this->details['page_title']; 102 | } 103 | 104 | //by default page title is module title 105 | function get_empty_message() { 106 | return __('Nothing here yet!', 'wmd_msreader' ); 107 | } 108 | 109 | function get_featured_media_html($post) { 110 | $post_content = preg_replace_callback( '|^\s*(https?://[^\s"]+)\s*$|im', array( $this, 'get_excerpt_media' ), $post->post_content ); 111 | 112 | $content_images_starts = explode('', $content_images_starts[1]); 116 | if(isset($content_image_ends[0]) && $content_image_ends[0]) 117 | $content_media = ''; 118 | } 119 | $content_iframe_starts = explode('', $content_iframe_starts[1]); 123 | if($content_iframe_ends[0]) 124 | $content_media = ''; 125 | } 126 | 127 | if(isset($content_media)) 128 | return $content_media; 129 | 130 | return ''; 131 | } 132 | 133 | function get_excerpt($post) { 134 | $max_sentences = 5; 135 | $max_paragraphs = 3; 136 | 137 | $post_content = preg_replace("~(?:\[/?)[^/\]]+/?\]~s", '', $post->post_content); 138 | 139 | if(class_exists('DOMDocument')) { 140 | $allowed_tags = array('','
      ','','

      ', '', ''); 141 | 142 | $post_content = wpautop(strip_tags($post_content, implode('', $allowed_tags))); 143 | 144 | $dom = new DOMDocument(); 145 | $dom->loadHTML(''.$post_content.''); 146 | $elements = $dom->documentElement; 147 | $all_elements = $elements->getElementsByTagName('*'); 148 | 149 | $current_paragraphs = 0; 150 | $current_sentences = 0; 151 | $limit_reached = 0; 152 | $remove_childs = array(); 153 | foreach($all_elements as $key => $child) { 154 | if($child->nodeName == 'html' || $child->nodeName == 'body' || $child->nodeName == 'meta' || $child->nodeName == 'head') 155 | continue; 156 | 157 | if($limit_reached || str_replace(array(' ', ' '), '', trim($child->textContent)) == '') 158 | $remove_childs[] = $child; 159 | else { 160 | //count sentences 161 | $content_sentences = explode('.', $child->textContent); 162 | $count_content_sentences = count($content_sentences); 163 | 164 | if($count_content_sentences) { 165 | //ditch fake sentences 166 | $count_fake_sentences = 0; 167 | foreach ($content_sentences as $sentence) { 168 | $sentence_length = strlen($sentence); 169 | if(!$sentence || strlen(str_replace (' ', '', $sentence)) == $sentence_length ) 170 | $count_fake_sentences ++; 171 | } 172 | $current_sentences = $current_sentences + $count_content_sentences - $count_fake_sentences; 173 | } 174 | else 175 | if(str_word_count($child->textContent) > 3) 176 | $current_sentences ++; 177 | 178 | //count paragraph 179 | if($child->nodeName == 'p') 180 | $current_paragraphs ++; 181 | 182 | //check if limit reached 183 | if(!$limit_reached && $child->nodeValue && ($current_paragraphs >= $max_paragraphs || $current_sentences >= $max_sentences)) { 184 | $child->nodeValue = $child->nodeValue.'...'; 185 | $last_child = $child; 186 | $limit_reached = 1; 187 | } 188 | } 189 | } 190 | foreach ($remove_childs as $child) { 191 | $child->parentNode->removeChild($child); 192 | } 193 | 194 | $body = $dom->getElementsByTagName('body'); 195 | $body = $body->item(0); 196 | $return = $dom->saveXML($body); 197 | $return = str_replace('', '', $return); 198 | $return = str_replace('', '', $return); 199 | } 200 | else { 201 | $allowed_tags = array('','

      ','','

      ',''); 202 | 203 | $post_content = strip_tags($post_content, implode('', $allowed_tags)); 204 | 205 | $content_sentences = explode('.', strip_tags($post_content, implode('',$allowed_tags))); 206 | $content_text_length = strip_tags($post->post_content); 207 | 208 | 209 | 210 | if(strlen($content_text_length) > 1000 && count($content_sentences) == 1) { 211 | $return = substr($content_text_length, 0, 1000).'...'; 212 | } 213 | else { 214 | 215 | //ditch fake sentences 216 | $count_content_sentences_real = 0; 217 | $content_sentences_clean = array(); 218 | foreach ($content_sentences as $sentence) { 219 | $sentence_length = strlen($sentence); 220 | if( 221 | !(!$sentence || 222 | strlen(str_replace (' ', '', $sentence)) == $sentence_length || 223 | substr($sentence, 0, 1) != ' ') 224 | ) 225 | $count_content_sentences_real ++; 226 | 227 | $content_sentences_clean[] = $sentence; 228 | 229 | if($count_content_sentences_real == $max_sentences) 230 | break; 231 | } 232 | 233 | //limit to max sentences 234 | $return = implode('.', $content_sentences_clean); 235 | 236 | //limit to total paragraphs 237 | $return = str_replace('

      ', '', $return); 238 | $paragraphs = explode('

      ', $return); 239 | $return = implode('

      ', array_slice($paragraphs, 0, $max_paragraphs)); 240 | 241 | //check if content was stripped 242 | if($count_content_sentences_real == $max_sentences || count($paragraphs) > $max_paragraphs) 243 | $return .= '...'; 244 | 245 | //close all allowed tags 246 | foreach ($allowed_tags as $tag) { 247 | $opening_tag = str_replace('>', '', $tag); 248 | $closing_tag = str_replace('<', 'limit : $limit; 273 | $page = !$page ? $this->page : $page; 274 | 275 | if(is_numeric($limit) && is_numeric($page)) { 276 | $start = ($limit*$page)-$limit; 277 | 278 | return 'LIMIT '.$start.','.$limit; 279 | } 280 | else 281 | return 'LIMIT 0,10'; 282 | } 283 | 284 | function get_allowed_sites() { 285 | $allowed_sites = apply_filters('msreader_allowed_sites', array(), $this->args, $this->details['slug']); 286 | //lets get max 250 newest unique numbers(blog_ids) only 287 | $allowed_sites = array_unique($allowed_sites); 288 | $allowed_sites = array_filter($allowed_sites, 'is_numeric'); 289 | arsort($allowed_sites); 290 | $allowed_sites = array_slice($allowed_sites, 0, 250); 291 | 292 | return $allowed_sites; 293 | } 294 | 295 | //get limit string 296 | function get_public() { 297 | $public = $this->helpers->is_public_only(); 298 | 299 | if($public) { 300 | $allowed_sites = $this->get_allowed_sites(); //results are safe for query 301 | 302 | if(is_array($allowed_sites) && count($allowed_sites) > 0) 303 | $query_part = '(blogs.public = 1 OR posts.BLOG_ID IN('.implode(',', $allowed_sites).')) AND'; 304 | elseif($allowed_sites == 'all') 305 | $query_part = ''; 306 | else 307 | $query_part = 'blogs.public = 1 AND'; 308 | } 309 | else 310 | $query_part = ''; 311 | 312 | return apply_filters('msreader_filter_blog_public_query_part', $query_part, $this->args, $this->details['slug']); 313 | } 314 | 315 | //get limit string 316 | function get_module_dashboard_url($args = array(), $module_slug = '') { 317 | global $msreader_modules; 318 | 319 | $module_slug = $module_slug ? $module_slug : $this->details['slug']; 320 | 321 | if(array_key_exists($module_slug, $msreader_modules)) { 322 | $blog_id = (is_user_member_of_blog() || is_super_admin()) ? get_current_blog_id() : get_user_meta(get_current_user_id(), 'primary_blog', true); 323 | 324 | $url = get_admin_url($blog_id, 'index.php?page=msreader.php&module='.$module_slug); 325 | if($args) 326 | $url = add_query_arg(array('args' => $args), $url); 327 | } 328 | else 329 | $url = ''; 330 | 331 | $url = apply_filters('msreader_module_dashboard_url_'.$this->details['slug'], $url, $args); 332 | $url = apply_filters('msreader_module_dashboard_url', $url, $args); 333 | 334 | return $url; 335 | } 336 | 337 | //easily adds link to main widget 338 | function create_link_for_main_widget($title_after = '', $args = false) { 339 | $link = array( 340 | 'title' => $this->details['menu_title'].$title_after, 341 | 'link' => add_query_arg(array('module' => $this->details['slug'], 'args' => $args), admin_url('index.php?page=msreader.php')) 342 | ); 343 | 344 | return $link; 345 | } 346 | 347 | //lets you create links widget for module by providing array with arrays with "arg"(argument that will be added at the end), "title" or optionaly full link by "link" 348 | function create_list_widget($links, $widget_details = array()) { 349 | foreach ($links as $position => $data) { 350 | if(isset($data['args'])) 351 | $data['link'] = add_query_arg(array('module' => $this->details['slug'], 'args' => $data['args']), admin_url('index.php?page=msreader.php')); 352 | if(isset($data['link']) && !$data['link']) 353 | unset($data['link']); 354 | 355 | $links[$position] = $data; 356 | } 357 | $widget = array( 358 | 'title' => $this->details['menu_title'], 359 | 'data' => array( 360 | 'list' => $links 361 | ) 362 | ); 363 | 364 | $widget = array_replace_recursive($widget, $widget_details); 365 | 366 | return $widget; 367 | } 368 | 369 | function increase_cache_init() { 370 | $this->cache_init = $this->details['global_cache'] ? get_site_option('msreader_cache_init_'.$this->details['slug'], 1) : get_user_option('msreader_cache_init_'.$this->details['slug']); 371 | $this->cache_init = $this->cache_init == false ? 1 : $this->cache_init; 372 | 373 | $this->cache_init++; 374 | 375 | if($this->details['global_cache']) 376 | update_site_option( 'msreader_cache_init_'.$this->details['slug'], $this->cache_init ); 377 | else 378 | update_user_option( get_current_user_id(), 'msreader_cache_init_'.$this->details['slug'], $this->cache_init, true ); 379 | } 380 | 381 | function add_module_slug_to_array($array) { 382 | $array[] = $this->details['slug']; 383 | 384 | return $array; 385 | } 386 | function is_site_indexable($blog_id) { 387 | global $postindexeradmin; 388 | 389 | if( 390 | get_blog_status($blog_id, 'public') && ( 391 | !isset($postindexeradmin) || 392 | ( 393 | isset($postindexeradmin->model) && 394 | method_exists($postindexeradmin->model,'is_blog_indexable') && 395 | $postindexeradmin->model->is_blog_indexable( $blog_id ) 396 | ) 397 | ) 398 | ) 399 | return true; 400 | else 401 | return false; 402 | } 403 | 404 | function get_site_post_link($blog_id, $post_id) { 405 | return 406 | apply_filters( 407 | 'msreader_rss_feeds_post_link', 408 | esc_url( 409 | add_query_arg( 410 | array( 411 | 'msreader_'.$this->details['slug'] => 'open_post', 412 | 'blog_id' => $blog_id, 413 | 'post_id' => $post_id 414 | ), 415 | network_site_url() 416 | ) 417 | ), $blog_id, $post_id, network_site_url() 418 | ); 419 | } 420 | 421 | function get_user() { 422 | return (isset($this->user) && is_numeric($this->user)) ? $this->user : get_current_user_id(); 423 | } 424 | 425 | function get_blog() { 426 | return (isset($this->blog) && is_numeric($this->blog)) ? $this->blog : get_current_blog_id(); 427 | } 428 | 429 | function open_site_post() { 430 | wp_redirect(get_blog_permalink( $_GET['blog_id'], $_GET['post_id'] )); 431 | exit(); 432 | } 433 | } --------------------------------------------------------------------------------